在室外跑惯GPS航点的固定翼和穿越机,一到室内停车场、隧道、厂区这类环境,我第一反应就是先检查信号数。GPS在遮挡严重的环境里要么搜不到星,要么位置一跳就是十几米,飞控的EKF滤波器直接被脏数据带偏,姿态都跟着晃。后来做室内巡检项目,我尝试用UWB超宽带定位取代GPS作为PX4的外部位置源,这才算真正把“室内自主飞行”跑通。这篇就把UWB接入PX4的完整思路、参数配置和踩坑记录整出来,给被室内定位困扰的朋友一条能直接照抄的路径。
这篇内容适合三类人:一是想把飞机从室外搬进室内的飞控玩家,二是做无人机巡检、仓储物流、管道探测等方案的工程师,三是学习PX4 EKF2融合原理的学生。硬件上我以常见的现成UWB定位系统为例,固件以PX4 v1.13/v1.14为例,不同版本参数名差别不大,但我会特别标注版本差异。整个方案不涉及改飞控源码,走外部位置估计的标准通道,愿意动手的朋友一个周末就能跑通。
1. 整体思路拆解:UWB如何平滑接管GPS的位置职责
1.1 为什么GPS在室内会失效,UWB补位的逻辑
GPS能定位依赖卫星直射信号,而卫星信号到达地面时功率已经低到-120dBm级别,穿透混凝土、钢结构、金属货架以后基本衰减得干干净净。室内环境还有一个致命问题——多径效应,信号从墙面、地面、货架反射后和直射信号叠加,接收机计算伪距时会产生数米到数十米的随机误差。在停车场这种空间里,GPS经常出现定位飘忽、高度乱跳、速度方向反转的诡异现象。
UWB全称是Ultra Wideband,超宽带无线通信技术。它用纳秒级窄脉冲发送信号,带宽通常在500MHz以上,时间分辨率极高。常规窄带信号遇到多径会叠加出严重的衰落,UWB却能把直射路径和反射路径在时间上分离开,测距精度能做到厘米级到分米级。再加上UWB信号工作在高频段(3.1-10.6GHz),穿透非金属遮挡的能力比GPS信号强很多,在室内中等遮挡条件下依然稳定。
所以UWB替代GPS的思路不是“物理上换一颗卫星”,而是换一个外部位置源。PX4的核心导航状态估计器EKF2支持多种定位源:GPS、视觉里程计、光流、外部位置估计。我们要做的就是让EKF2放弃GPS,改用UWB系统提供的位置、速度数据,剩下的事情全交给滤波融合算法。
1.2 PX4外部位置估计链路:从UWB坐标到EKF2融合
PX4里有一个专门消息叫VISION_POSITION_ESTIMATE,翻译成中文是“视觉位置估计”,但它的使用范围其实不限于视觉,任何能提供三轴位置、三轴姿态或三轴速度的外部定位系统,都可以通过这条消息接入。这个机制本来是给VIO摄像头、Mocap动作捕捉系统用的,UWB定位也是一个道理。
数据链路长这样:UWB标签测量到多个基站的距离,解算出标签在UWB坐标系下的三维坐标,机载电脑或者转接板通过串口/网口读取这个坐标,打包成MAVLink的VISION_POSITION_ESTIMATE消息,再通过串口或UDP发给飞控。飞控收到消息后,由EKF2模块把位置和速度信息融合进状态估计,最终输出飞机在地球固定坐标系下的位置、速度、姿态。
这个链路里最关键的认知是:PX4并不关心你的定位源是GPS还是UWB,它只接收经过MAVLink封装的外部位置估计。如果UWB系统能输出NED或者ENU坐标系下的位置坐标,PX4就能直接用。这大大降低了接入门槛,不需要改动飞控底层代码,只需要配置参数和搭好通信链路。
1.3 方案选型:现成UWB定位系统还是自研
UWB定位系统的选择大致分三个层级。第一层级是买现成完整方案,比如Nooploop LinkTrack、Pozyx、Sewio这类商业化产品。它们自带基站、标签、定位解算算法,有的还提供ROS驱动和PX4桥接程序,开箱即用,适合聚焦应用开发的团队。第二层级是买模块自己搭,典型硬件是Decawave DWM1001-DEV或者Qorvo的DW3000系列,需要自己写测距协议或TDOA同步逻辑,适合做研究和深度定制。第三层级是纯算法仿真,用Matlab或Python模拟UWB测距数据,适合只做算法验证。
我的建议是:如果目标是让飞机快速飞起来,别自己做底层测距协议,直接选现成系统。定位这群人不是搞射频芯片的,基础定位算法和天线校准是深坑,一次标签校准做不好,后面所有数据都是垃圾。选择一个有ROS驱动的系统,能省下大量时间。如果后续发现定位精度满足不了需求,再判断要不要自研。
2. 核心参数解析:EKF2、数据协议与坐标系
2.1 UWB定位原理:TOF、TDOA与三边定位
UWB定位最常见的原理是TOF(Time of Flight,飞行时间法)。测距过程就是标签向基站发一个脉冲,基站返回一个确认脉冲,标签记录从发出到收到的时间差,乘上光速除以2,就能得到标签与基站的距离。这个方法简单可靠,但要求标签和基站之间有精确的时钟同步,或者采用双向测距来抵消钟差,所以一般叫TOF双程测距。
有了标签到三个以上已知坐标基站的距离,就可以用三边定位解算标签位置。三个基站就是三个球面方程,取交集得到的位置就是标签坐标。实际使用中基站数量通常不止三个,因为多出来的冗余量可以参与最小二乘优化,提高精度和鲁棒性。
另一个常用的方式是TDOA(Time Difference of Arrival,到达时间差法)。这种模式下标签只发信号,多个基站记录信号到达的时间差,利用时间差计算标签到不同基站的距离差,进而解算位置。TDOA不需要标签响应,可以支持更多标签并发,但所有基站之间必须高精度同步,对系统时钟要求更高。对于单无人机定位场景,TOF方案足够用,也更好调试。
无论哪种方式,最终输出都是UWB坐标系下的三维坐标。PX4使用NED(北东地)或ENU(东北天)坐标系,因此必须确认UWB系统的输出坐标系,并在转接代码里做好坐标轴转换。
2.2 卡尔曼滤波在UWB融合中的角色
很多同学看到“卡尔曼滤波推导”就头疼,但理解UWB接入PX4并不需要完整推导公式,关键是理解EKF2是怎么把UWB数据和IMU数据结合起来的。EKF2的状态向量包含位置、速度、姿态、陀螺零偏、加速度计零偏等几十个维度。IMU以250Hz到1000Hz的高频率进行预测,外部定位源则以较低频率提供观测修正。
GPS频率一般是5Hz到10Hz,UWB系统通常能到10Hz到50Hz,少数系统能到100Hz以上。EKF2内部有一个延迟补偿机制,可以用EKF2_EV_DELAY参数设定外部位置源相对于IMU的延迟毫秒数。这个参数宁可多调几次,也不能忽略——延迟设置不对,定位数据会像“拉着弹簧”一样震荡。
卡尔曼滤波在UWB融合里的作用相当于一个“裁缝”:IMU短时间内很稳,但长时间会漂;UWB长期绝对位置准,但短期噪声大。滤波把两者缝在一起,得到既平滑又不飘的位置估计。所以即使UWB数据出现个别跳变点,只要融合门限设置得当,EKF2也能自动降权甚至拒绝污染源,不至于瞬间飞出几米。
2.3 PX4关键参数清单与调整原则
下面这张表是我在PX4 v1.13和v1.14上验证过的参数配置,每个参数后面都写了作用。实际设置时请以你固件版本的参数说明为准,但核心逻辑是一样的。
| 参数名 | 推荐值 | 作用 |
|---|---|---|
| SYS_HAS_GPS | 0 | 告诉系统没有GPS硬件,防止EKF等待GPS信号 |
| EKF2_GPS_CTRL | 0 | 关闭GPS辅助融合控制 |
| EKF2_AID_MASK | 24 | 启用外部位置估计和外部航向融合 |
| EKF2_EV_DELAY | 按实测填写 | 外部位置源延迟补偿,单位毫秒 |
| EKF2_EV_POS_X/Y/Z | 按实机填写 | UWB标签或外部设备相对IMU的安装偏移 |
| EKF2_EV_QUAL_MIN | 0.3 | 外部位置数据最低质量阈值 |
| ATT_EXT_MD | 1(旧固件) | 旧版本PX4中启用外部姿态位置模式 |
EKF2_AID_MASK这个参数在不同固件版本里位定义不同,一定要先在QGroundControl里点开参数说明确认当前固件的bit定义。常见组合中,24表示同时启用视觉位置和视觉航向融合,但如果你的固件版本里视觉位置对应bit4、视觉航向对应bit8,那么24=16+8并不成立,需按实际位值计算。我自己的习惯是先设24,如果EKF告警提示vision pos source not active,再查一下位定义。
还要理解一个底层逻辑:关闭GPS后,EKF2航向估计也会受影响,因为GPS航向往往是固定翼的航向参考之一。多旋翼在悬停时主要通过磁力计得到航向,所以只要磁力计标定合格,EKF2_AID_MASK里的视觉航向可以作为辅助,但不应该完全依赖。如果UWB系统本身不提供航向,只提供位置,那么EKF2_AID_MASK只需要启用视觉位置融合即可。
3. 实操配置全流程:从UWB基站到飞控一条龙
3.1 准备硬件与固件版本
我这次用的是Nooploop LinkTrack P-B系列作为UWB定位系统,四个基站布在房间四角,一个标签装在飞机顶部。基站高度尽量和飞行高度接近,因为UWB的高度方向精度天然比水平方向差,如果基站高度和飞行高度差太多,Z轴会飘得更厉害。
飞控是Pixhawk 6C,固件PX4 v1.14.3,机载电脑是一块树莓派4B,跑Ubuntu 22.04和MAVROS。你也可以用更轻量的ESP32或STM32做串口转MAVLink,但机载电脑方案调试更方便,后续还能扩展视觉避障。
固件版本尽量选v1.12以上,因为从v1.12开始EKF2统一管理外部位置估计,旧的ATT_EXT_MD参数逐渐被废弃。如果你还在v1.10及以下固件,建议先升级,否则下面的参数配置很多对不上。
3.2 数据接入通道:串口转发与MAVLink消息
UWB系统给出定位坐标后,需要转成MAVLink消息发给飞控。最常用的消息是VISION_POSITION_ESTIMATE,字段包括:
- time_usec:时间戳,微秒
- x、y、z:位置坐标,单位米
- roll、pitch、yaw:姿态估计,单位弧度
- covariance:协方差矩阵,可选
如果你的UWB系统只提供位置,不提供姿态,把roll/pitch/yaw填0即可,EKF2中的视觉航向融合会自动忽略无效姿态。如果UWB系统提供速度信息,还可以用VISION_SPEED_ESTIMATE消息单独发送速度,进一步约束EKF。
树莓派上的转发逻辑就三步:第一步读取UWB标签串口数据,解析出x、y、z坐标;第二步把坐标系从UWB系统坐标系对齐到NED或ENU;第三步用MAVROS或者pymavlink打包成VISION_POSITION_ESTIMATE消息,通过串口或者WIFI发给飞控。
我实际用的是MAVROS的vision_position_estimate话题,发布频率设置在20Hz。UWB系统本身最高能到50Hz,但在复杂环境下20Hz已经能让EKF稳定收敛。频率太低会导致EKF预测时间过长,位置估计退化;频率太高则会造成串口带宽浪费,增加延迟抖动。
3.3 QGroundControl参数设置
在QGroundControl连接飞控后,按顺序执行以下操作:
第一步,把SYS_HAS_GPS设为0。这一步会让PX4内部不再等待GPS数据,EKF初始化不再被“没有GPS”卡住。有些版本的飞控如果不关这个参数,即使EKF2_AID_MASK已经启用了视觉位置,飞控日志里依然会定期报“GPS failure”,位置估计模式也不干净。
第二步,把EKF2_GPS_CTRL设为0。这是v1.13以后新增的GPS辅助控制位,相当于在EKF2内部把GPS相关的一切融合全部屏蔽。就算SYS_HAS_GPS忘了设,这步也能兜底。
第三步,设置EKF2_AID_MASK。我按bit定义计算后,设置为24,启用视觉位置和视觉航向融合。这个参数修改后会要求飞控重启,重启后再检查参数是否生效。
第四步,设置EKF2_EV_DELAY。这个值的确定方法后面专门讲,初值可以先给10毫秒到30毫秒,后续根据飞行数据调整。
第五步,设置EKF2_EV_POS_X/Y/Z。这三个值表示UWB标签或外部定位天线相对飞控IMU的位置偏移,单位是米。标签装在机头方向1米处,那么EKF2_EV_POS_X就是1(或者-1,看坐标系定义)。这个偏移如果忽略,飞机旋转时会产生虚假的位置反馈,悬停会来回晃。
第六步,回到参数页确认SYS_MC_EST_GROUP是否为2(EKF2),这是多旋翼默认估计器组,一般不用改,但如果有人把估计器组改成LPE,就要先切回来。
3.4 飞行验证与数据体检
参数配好以后不要急着解锁起飞,先做地面体检。打开QGroundControl的MAVLink Inspector,订阅VISION_POSITION_ESTIMATE消息,确认坐标值变化和实际移动一致。再切到EKF2状态页面,看位置估计是否进入“Vision”模式,而不是还在等GPS。
我在地面测试时习惯做两个动作:第一个是手持飞机沿着房间对角线走一圈,观察地面站里飞机位置轨迹是否跟着人走,方向是否和实际一致。第二个是原地快速旋转机体,观察位置估计是否发生明显漂移,这一步能验证EKF2_EV_POS_X/Y/Z和航向融合是否正确。
确认没大问题后,做一次高度0.5米的低空悬停。先切Position模式,如果EKF位置估计品质合格,飞控会允许进入Position模式。悬停时观察位置误差,正常可以控制在10厘米以内。如果出现一个方向持续漂移,多半是坐标系对齐或安装偏移问题;如果出现高频震荡,多半是EKF2_EV_DELAY设置过小或过大。
4. 常见问题与排查技巧实录
4.1 位置漂移、跳变与航向偏移
UWB接入后最常遇到的现象就是位置慢速漂移。我第一次调试时飞机悬停三分钟,位置估计漂出半米,排查了半天,最后发现是基站坐标系和PX4的NED坐标系没对齐。UWB系统坐标原点放在房间西南角,X轴指向北,但我在解析代码里把X轴和Y轴写反了,等于飞机实际往北飞,飞控以为它在往东飞。
排查方法很简单:人拿飞机朝正北移动半米,看地面站里Y轴和X轴哪个在变。如果方向不对,就在代码里做矩阵旋转或者交换坐标轴。另外,不同UWB系统的坐标定义差异很大,有些用右手系,有些用左手系,落地前必须用实测确认。
跳变问题的原因通常是UWB测距中出现多径路径,或者基站与标签之间有一瞬间被遮挡。EKF2有质量门限,异常的观测会被降权。但如果跳变频率过高,就需要检查基站布设是否合理,避免基站旁边紧贴大块金属,同时把EKF2_EV_QUAL_MIN适当调高,让异常数据更难通过。
航向偏移是一个隐蔽的坑。UWB位置定位本身不测量航向,如果只使用视觉位置而不同时使用视觉航向,EKF2会退回磁力计航向。磁力计在室内受钢筋、铁架影响会产生恒定偏差,导致飞控认为飞机在转圈,实际飞机却在朝某个方向平移。解决办法是标定磁力计后,在EKF2里把磁力计偏航设为偏差补偿模式,或者用外部信号源提供航向。
4.2 参数配置失效的排查
有些朋友照着教程设完参数,发现EKF2依旧显示GPS依靠状态,或者位置估计模式一直是“SYS_RATE”之类的奇怪状态。这种情况大概率是参数没有真正写入,或者写入了但固件版本读取的位定义不同。
排查步骤我列个清单:
- 检查飞控参数是否在修改后点击了“写入并重启”。参数页很多操作只是暂存,不重启不生效。
- 检查EKF2_AID_MASK的实际数值是否和你填的一致,有时拨码开关和参数编辑器会舍入。
- 检查SYS_HAS_GPS是否被某个启动脚本覆盖。如果启用了带GPS的机型定义,脚本可能在启动时把参数强制改回默认值。
- 检查v1.11以前的固件版本是否还在用ATT_EXT_MD,而不是EKF2_AID_MASK。
- 检查日志里有没有vision pos related error,如果有,把具体报错信息粘贴到搜索引擎,基本能定位到原因。
再强调一次:EKF2_AID_MASK的位定义在不同版本间有差异。v1.12和v1.13文档中的bit定义就不完全一样。我建议每次刷了新固件,都先打开QGC参数描述页,找到EKF2_AID_MASK的枚举注释,再计算需要的组合值,不要凭记忆照搬。
4.3 硬件安装与天线布设的坑
UWB系统的精度很大程度取决于基站布设的几何条件。基站形成三角形包裹越“正”,垂直方向的定位解算越稳定。如果所有基站几乎排成一条直线,那么位置解算在垂直于这条直线的方向会严重发散。室内空间有限时,宁可把基站放在四个角落上方,也不要挤在房间正中。
标签的天线安装方向也有讲究。UWB模块的天线通常是全向的,但不同模块的辐射方向图不一样。DWM1000这类模块依赖PCB天线的水平方向辐射,如果标签天线侧面正对基站,信号弱,测距误差大。安装时尽量让标签天线所在平面朝向大多数基站的方向,并且不要让机身碳架、金属外壳包住天线。
还有一个常被忽略的问题:电池和电机的电磁干扰。电机高速旋转时,高频噪音可能干扰UWB接收机的低噪声放大器。我实测在电机解锁但不转桨和全油门之间,UWB测距噪声能差出一倍。如果条件允许,把UWB标签放在远离电源模块和电调的位置,或者在标签和安装座之间加一层薄泡棉减震隔离。
4.4 延迟补偿实战:一个调参案例
最后讲一个最实用的经验,关于EKF2_EV_DELAY的现场调整方法。这套方法不需要高端设备,只用QGC的日志分析就能做。
先把飞机固定在一个稳定的架子上,确保机体不会因电机振动移动。解锁电机,给一个中等油门至半油门区间,让IMU数据活跃起来,但确保GPS和UWB位置理论上都不变。在地上用力晃动UWB标签再迅速放回原位,模拟一个位置阶跃输入。飞控会在延迟补偿参数的不同值下产生超调和回摆,通过日志里EKF2的innovation值判断延迟是否匹配。
我在现场的做法是:EKF2_EV_DELAY从0毫秒开始,每次加5毫秒,观察位置估计在阶跃输入后的超调量。超调最小、恢复最快的那组值就是当前链路的最佳延迟。这个值通常由三部分组成:UWB系统自身从测距到输出坐标的计算时间、串口波特率带来的传输时间、机载电脑MAVROS处理消息的用户态延迟。链路越复杂,延迟越大。在我这套系统上,最终确认的延迟是35毫秒,和一开始拍脑袋设置的10毫秒差了不少,效果区别也很大。
结尾
我实际操作下来最大的体会是,UWB替代GPS这件事技术上并不神秘,真正费时间的不是MAVLink消息怎么写,而是坐标系、延迟、安装偏移这些“闹心”的细节。只要把EKF2看作一个对数据源有要求的融合器,把UWB当成一个带噪声的传感器,整个调试思路就清晰了。
最后再分享一个小技巧:第一次跑通后,建议专门做一次“断电重启+冷启动定位”测试,确保UWB系统掉线后重新上电,飞控也能在纯外部定位源下正常完成EKF初始化。很多室内项目出问题不是飞行中,而是开机等待阶段就卡死在“等待GPS fix”上。把这个环节提前测掉,能省掉现场一大半尴尬。