空地协同消防实战:从通信协议到路径规划的嵌入式系统实现

张开发
2026/4/6 19:36:45 15 分钟阅读

分享文章

空地协同消防实战:从通信协议到路径规划的嵌入式系统实现
1. 空地协同消防系统的核心挑战在消防应急场景中时间就是生命。传统消防车受限于地面交通状况往往难以及时抵达火灾现场。而无人机虽然机动性强但续航和载重能力有限。将两者优势结合的空地协同消防系统正成为智能应急救援的新方向。我去年带队参加全国大学生电子设计竞赛时就曾实现过一套包含无人机和消防车的协同系统。实测下来发现三大技术难点首先是通信稳定性当无人机飞行高度达到18dm时蓝牙信号经常出现丢包其次是路径规划算法要兼顾全覆盖效率和火情响应速度最后是多设备协同如何让无人机、消防车、串口屏等硬件像交响乐团一样默契配合。这个系统的核心指标很明确从发现火情到完成灭火的全流程时间必须压缩到360秒内。听起来简单但当你真正调试时会发现光是让无人机准确降落在30cm×30cm的起飞区就够头疼的。有次测试中无人机因为GPS漂移直接撞上了消防车那场面简直不忍直视。2. 硬件选型与嵌入式系统设计2.1 主控芯片的抉择主控芯片就像系统的大脑我们对比过TI的TM4C123和盘古开发板。TM4C123GXL这块板子真是踩过大坑——调试接口不稳定Keil编译时频繁闪退有次硬件直接卡死在中断服务函数里。后来换成TI盘古开发板(TM4C123GH6PZT7)80MHz主频的Cortex-M4F内核配合256KB Flash跑多任务游刃有余。这块板子的外设资源特别适合我们的场景12位ADC用于光敏传感器信号采集8个PWM通道控制电机和舵机6个串口同时驱动蓝牙、串口屏、OpenMV等设备板载加速度计实现跌落保护2.2 通信模块的实战经验无线通信试过三种方案普通蓝牙、WiFi和UWB。蓝牙模块成本最低但传输距离有限我们在代码里加了重传机制——每帧数据带序列号收不到ACK就自动重发。大熊智能的DX2003模块用AT指令配置时要注意// 主机配置 ATNAMEDX2003-M ATMASTER04 // 主机模式 ATCONN22345000891f // 连接从机地址 // 从机配置 ATNAMEDX2003-S ATMASTER01 // 从机模式UWB定位精度能达到10cm级别配合TDOA算法可以实现室内精确定位。不过一套模块要800多元而且驱动开发周期长。最终我们折中方案是用蓝牙传输指令UWB只做辅助定位。2.3 电机驱动与电源管理消防车的开山斧驱动板确实稳四路PWM输入支持正反转控制。但第一次接线时就烧了个电机——原来PWM频率设成了1kHz应该用10kHz以上才能避免电机啸叫。正确的初始化代码void PWM0_Init(void) { SysCtlPWMClockSet(SYSCTL_PWMDIV_8); // 80MHz/810MHz PWMGenConfigure(PWM0_BASE, PWM_GEN_0, PWM_GEN_MODE_DOWN | PWM_GEN_MODE_SYNC); PWMGenPeriodSet(PWM0_BASE, PWM_GEN_0, 1000); // 10kHz PWMPulseWidthSet(PWM0_BASE, PWM_OUT_2, 500); // 50%占空比 }电源方面无人机用3S锂电(11.1V)通过TPS5430降压到5V给主控供电。消防车需要12V电池组关键是要选高倍率放电型号否则电机启动瞬间会触发欠压保护。3. 通信协议与数据解析3.1 自定义轻量级协议无人机和消防车之间采用字符型通信协议这样调试时可以直接用串口助手查看。协议设计有三个要点帧头标识数据类型A-航点/B-火源逗号分隔数据字段帧尾用F作为结束符典型数据帧长这样A,160,150,F // 无人机当前位置(160,150) B,250,100,F // 火源坐标(250,100)在消防车主控端要用状态机解析这些数据。我写过最稳定的解析函数是这样的void uart4_data_check(void) { if(uart4_rec_temp[0] A) { char* token strtok(uart4_rec_temp,,); token strtok(NULL,,); // 提取X坐标 float x atof(token); token strtok(NULL,,); // 提取Y坐标 float y atof(token); updateUAVPosition(x,y); // 更新无人机位置 } memset(uart4_rec_temp, 0, sizeof(uart4_rec_temp)); // 清空缓冲区 }3.2 实时地图绘制技巧消防车上的陶晶驰串口屏确实省心但绘制动态轨迹要注意两点一是坐标转换把实际40dm×48dm区域映射到320×240像素屏幕二是避免频繁刷新导致的闪烁。我们的解决方案是// 绘制航迹线 void drawPath(int x1, int y1, int x2, int y2) { char cmd[50]; sprintf(cmd,line %d,%d,%d,%d,BLUE, mapX(x1), mapY(y1), mapX(x2), mapY(y2)); UART5_SendString(cmd); UART5_SendBinary(); // 发送结束符0xFF 0xFF 0xFF } // 坐标映射函数 int mapX(float x) { return (int)(x * 312 / 480); } int mapY(float y) { return 262 - (int)(y * 256 / 400); }实测发现如果每秒绘制超过20个线段屏幕就会明显卡顿。后来我们改为只保留最近50个航点效果就好多了。4. 路径规划算法实现4.1 全覆盖巡逻算法要让无人机在40dm×48dm区域实现8dm宽度的全覆盖我们对比过三种扫描方式蛇形扫描像打印机一样来回走Z字型覆盖效率高但转弯次数多螺旋扫描从外向内盘旋转弯少但中心区域重复率高分区扫描将区域划分为多个子区域分别扫描最终选择改进版蛇形扫描关键参数如下飞行高度18dm保证8dm覆盖宽度航线间距7dm留1dm重叠防止漏检转弯半径3dm防止无人机失速算法核心代码如下void generatePath() { bool rightToLeft true; for(int y8; y48; y7) { if(rightToLeft) { addWaypoint(40, y); addWaypoint(0, y); } else { addWaypoint(0, y); addWaypoint(40, y); } rightToLeft !rightToLeft; } }4.2 火情响应策略当OpenMV检测到火源时系统立即进入应急响应模式无人机下降至10dm高度悬停抛洒灭火包要计算下落抛物线通过蓝牙发送火源坐标给消防车消防车规划避障路径前往灭火这里最棘手的是消防车的路径避障。我们采用最简单的街区导航法——把场地划分为多个虚拟街区消防车只沿街区边缘移动。虽然看起来笨拙但实测比复杂的A*算法更可靠。void Car_Move(int blockID) { switch(blockID) { case 1: // 1号街区 Car_Forward(500,1000); Car_TurnLeft(500,1000); break; case 2: // 2号街区 Car_TurnRight(500,1000); Car_Forward(500,3000); break; // 其他街区路径... } }在省赛现场这套系统从发现火情到完成灭火最快只用了278秒。虽然中途出现过蓝牙断连的小插曲但整体表现远超预期。赛后复盘时裁判特别肯定了我们在有限硬件资源下的创新实现——用不到2000元的成本做出了商用级系统30%的功能。

更多文章