固定翼降落那一下,圈里人常开玩笑叫“耀斑”——不是太阳耀斑,而是落地瞬间机身一弹、像放了个“闪光弹”的姿态,轻则拉飘重则砸地,运气不好就是一次炸鸡。我接管过不少固定翼飞控项目,Pixhawk飞固定翼自动着陆的最大痛点从来不是算法跑不通,而是高度源在低空根本不可信。气压计受气流和翼面扰动影响,漂移起来能差出好几米;GPS垂直精度在民用领域只能到±5米量级,这数据拿去做自动着陆的flare拉平参考,基本等于闭眼跳台阶。
后来我把激光测距仪接进PX4,用它作为EKF2的高度观测源,固定翼自动着陆的稳定性和接地精度才有质的提升。这篇文章把整个流程摊开讲:从激光测距仪选型、接线、PX4参数配置,到EKF2融合逻辑和自动着陆flare相关参数,再到Gazebo SITL仿真验证和真机排查,一条龙给你捋清楚。适合正在搞PX4二次开发、给固定翼做自动化改造,或者单纯想把自动着陆调稳的玩家参考。
1. 为什么固定翼降落总是“一波三折”
1.1 传统高度测量方案的局限
固定翼自动着陆对高度数据的要求是“近地面绝对准”。起降阶段飞机高度从几十米一路压缩到零,任何一个高度误差都会被几何放大——下滑道是3度、5度还是7度,决定权就在这几十厘米到几米的高度上。
先说气压计。气压计测的是气压换算高度,原理没问题,但固定翼飞行时有两个致命干扰:一是飞行速度带来的动压分量会让气室内的静压测量产生偏差,虽然皮托管和静压孔做了分离,但低空大攻角状态下误差还是明显;二是地面效应和热气流会让近地气压局部分布紊乱,你在200米高空看着稳定的高度数据,一进近地高度层可能直接给你跳个1到2米。气压计本身的绝对精度也一般,消费级MS5611约±0.1米(相对高度),但受温度漂移和滞回影响,实际飞行经常不止。
再说GPS。GPS的垂直分量精度天然比水平差一截,民用单频场景下VDOP一差,高度误差三五米是常态。更麻烦的是GPS高度在时间相关性上表现很差,相邻几秒内可能出现缓慢漂移,这对于需要精确判断“离地还有1.5米,该拉平了”的flare阶段来说,基本没法用。RTK能解决,但成本和架设门槛对大多数玩家不现实。
所以问题就摆在这里:自动着陆最需要精确高度的阶段,恰好在最不可靠的高度源覆盖区间。传统的做法是让飞控用气压计做主导高度,用GPS修正缓变漂移,凑合着飞没问题,但要做“精准拉飘后轻触地”这种活,高度源就是第一块短板。
1.2 激光测距仪在降落场景里的定位
激光测距仪(LiDAR单点测距)解决的正是这个“最后一公里”问题。它直接测量机体相对地面或跑道的绝对距离,不依赖气压换算,不受气流干扰,短距离内精度能做到厘米级,而且更新速率通常能达到100Hz甚至更高,远超气压计和GPS的更新节奏。
在PX4的姿态估计体系里,激光测距仪并不是简单替换气压计,而是作为EKF2的一个“辅助观测源”参与融合。EKF2会根据当前飞行状态和传感器有效性动态决定信任谁多一点:高空阶段相信GPS/气压计,低空且测距数据有效时,大幅提高测距仪的权重,让高度状态量逐步收敛到测距仪给出的真实离地高度。到了flare拉平阶段,高度主要就由激光测距仪说了算。
这个特性非常关键,也是固定翼能用它实现精准自动着陆的核心原因——“耀斑”降落说白了就是高度不准导致拉平过早或过晚,只要低空高度源精度够,飞控完全有能力把flare动作做漂亮。
2. 激光测距仪选型与安装,这几件事不能将就
2.1 主流测距仪横向对比
市面上能直接接飞控的激光测距仪不多,我挑了几款常用的按参数列了一下:
| 型号 | 量程 | 精度 | 更新率 | 接口 | 重量 | 特点 |
|---|---|---|---|---|---|---|
| 北醒 TFmini-S | 0.1m ~ 12m | ±1cm @ 6m 内 | 100Hz(可调) | UART | 约12g | 性价比高,固定翼玩家首选 |
| 北醒 TF-Luna | 0.2m ~ 8m | ±6cm | 100Hz | UART/I2C | 约11g | 体积小,适合机舱内安装 |
| Garmin LIDAR-Lite v3 | 0.2m ~ 40m | ±2.5cm | 约20Hz(可调) | I2C/PWM | 约31g | 量程大,可兼顾低空高度和避障 |
| LightWare SF11/C | 0.02m ~ 120m | ±10mm | 100Hz/400Hz | UART/I2C | 约78g | 专业级,价格高,适合重型平台 |
固定翼自动着陆用,我最推荐的还是TFmini-S。原因很实在:重量轻、量程足够覆盖下滑道起点(一般固定翼从20米高度进入下滑道没问题)、精度在6米内做到±1cm完全能应付flare拉平判断,还有最关键的UART接口,直接和飞控串口对接,不需要做电平转换和协议折腾。
从实战角度看,TFmini-S还有一个优势——它对镜面和强光的抗干扰处理在同类产品里算稳的,当然它也不是万能,后面我会专门讲光线干扰的坑。选型时不要一味追求大量程,固定翼空速大,进近速度快时测距数据更新率比量程更重要,100Hz的传感器在每秒20米的地速下意味着每0.2米就有一个高度样本,飞机状态变化捕捉得很细腻。
2.2 安装位置、供电与走线细节
安装位置是我反复强调的一环,很多人在这一步就埋了雷。固定翼的激光测距仪必须安装在机身底部,且透视区域要避开起落架、天线、舵机拉杆、机翼遮挡。镜头垂直朝下略微前倾(10到15度)是比较合理的姿态,这样在正常低头姿态下测的是正下方地面,而不是前方远处的地面。但要注意,前倾角度不宜过大,否则飞机大攻角进近时测距激光打出去,测到的是前方几米外的地面,离地高度会偏大,flare触发就会偏早——这是实打实会导致“飘”的隐藏问题。
供电是另一个高发坑区。激光测距仪的峰值电流(尤其是TFmini系列)可达500mA级别,如果直接从飞控的接收机供电口取电,容易造成电压跌落,轻则数据异常跳变,重则让飞控供电进入低电压报警。我的做法是单独从5V BEC供电,或者从飞控电源模块的5V输出端取电,同时保证共地。飞控的串口TX/RX只接信号线,不要靠串口去给传感器供电。
走线时还有个容易被忽略的点:测距仪信号线尽量远离电机电调的三相线和电流计导线,这些大电流线上的开关噪声会串进串口信号里,导致数据偶发性乱码或丢包。如果机身内走线无法避免交叉,用带屏蔽层的硅胶线,或者至少把信号线绞合起来降低耦合干扰。
3. 为什么EKF2要“信”激光测距仪,它的融合逻辑是什么
3.1 卡尔曼滤波在高度估计里的角色
PX4的姿态和位置估计核心是EKF2(扩展卡尔曼滤波器),网上关于卡尔曼滤波的推导文章一抓一大把,但很多都把人劝退。我换一种直观说法。
卡尔曼滤波做的就是一件事:把“我不太确定的预测”和“我也不太确定的观测”按各自的置信度加权平均,得到当前最优估计。对于高度这个一维状态,传感器融合可以简化成以下过程——
预测阶段,飞控用IMU的z向加速度积分估计高度的变化趋势,同时这个预测会随时间越来越不自信,协方差逐渐增大。更新阶段,当有气压计、GPS、激光测距仪等观测到来时,按照每一个观测的噪声特性,去修正预测结果。如果某个观测的噪声协方差小(比如激光测距仪近地精度高),滤波器就会更相信它;如果噪声大(比如GPS高度),修正力度就弱。
所以EKF2并不是“看到激光数据就完全覆盖高度”,而是渐进式地把高度估计从气压计/ GPS主导,过渡到激光测距仪主导。这个过渡过程具体怎么设计,就是PX4源码里那几个EKF2_RNG_*参数在做的事。理解了这一点,后面调参数就不容易懵。
一维高度卡尔曼滤波的核心关系可以写成这样:
状态预测方程:h_k = h_{k-1} + v_{k-1}·Δt
协方差预测方程:P_k = P_{k-1} + Q
卡尔曼增益计算:K_k = P_k / (P_k + R)
状态更新方程:h_hat_k = h_k + K_k·(z_k - h_k)
协方差更新方程:P_hat_k = (1 - K_k)·P_k
这里的Q是过程噪声协方差(IMU积分不信任程度),R是观测噪声协方差(传感器噪声大小)。激光测距仪在近地时R值可以被设得很小,于是K_k趋近于1,更新结果几乎全部采信激光数据,这就是它在flare阶段能“一锤定音”的数学本质。
3.2 PX4里激光测距仪接入的软硬件链路
在PX4上接入激光测距仪,链路分三层。第一层是硬件串口,测距仪通过UART和飞控的一个空闲串口连接;第二层是驱动,PX4的drivers/ distance_sensor目录下有对应驱动(常见型号都有现成支持),编译时通过SENS_EN_RANGEFINDER参数使能;第三层是EKF,测距数据发布到uORB消息sensor_distance,EKF2订阅这个topic后按参数配置决定是否参与融合。
整条链路里,最常出错的是前两层:串口没配对、波特率不对、驱动没编译进去。我建议一开始先把测距仪单独接好,用QGroundControl的MAVLink控制台执行:
# 查看是否有sensor_distance消息发布 listener sensor_distance如果在控制台能看到sensor_distance数据正常更新,说明驱动层已经通了,再往下调EKF参数就有的放矢。看不到数据就先去查串口配置和波特率,别在EKF参数上瞎折腾。
PX4中测距仪相关的关键EKF参数和作用如下:
| 参数名 | 作用 | 推荐值(固定翼着陆场景) |
|---|---|---|
| EKF2_RNG_AID | 是否启用测距仪辅助 | 1(启用) |
| EKF2_RNG_AID_AID | 是否在位置辅助时使用测距仪 | 1(固定翼推荐) |
| EKF2_RNG_HGT_VALID | 测距仪垂直方向有效性阈值 | 3.0m左右(小于此高度才强化信任) |
| EKF2_RNG_QLTY_T | 测距信号质量阈值 | 按传感器惯常(TFSmini约0.9) |
| EKF2_RNG_SNSR_POS | 测距仪相对IMU的位置偏移 | 按实际安装填写 |
注意EKF2_RNG_HGT_VALID这个参数,它代表“低于这个高度时,测距仪高度观测是有效的”。固定翼自动着陆场景其实用得很妙:飞机在高空时,激光测距数据即使有,也不参与或很少参与高度融合,避免它对GPS/气压计高度造成干扰;一旦进入低空测距有效区,融合权重逐渐转移到激光上,为flare做数据准备。这个参数的设置要和你的进近航线高度匹配,一般3米到5米都行,具体看你下滑道的最后段离地高度设定。
4. 手把手实操:从接线到PX4参数配置,一次跑通测距仪
4.1 硬件接线与飞控串口选择
先把Pixhawk系列飞控接线的通用做法说清楚,以Pixhawk 6C为例。这板子有好几路UART,典型空闲口是TELEM2、UART4、UART6等。一般建议选一个不用于数传和图传的空闲串口,我常用的是TELEM2(或者UART6,视飞控型号而定),目的很简单——避免和调参通信、遥控、数传抢占资源。
接线图简化如下:
TFmini-S -> Pixhawk 串口(以TELEM2为例) 5V -> TELEM2 5V(仅当电流安全时,或用外部BEC) GND -> TELEM2 GND TX -> TELEM2 RX RX -> TELEM2 TX供电问题我再强调一次:如果飞控的5V输出能力有限,或者你的测距仪峰值电流比较大,请不要直接从飞控串口取电,从BEC单独拉一根5V线给测距仪,然后把GND和飞控串口GND共地。直接靠飞控电源供电也不是完全不能跑,但容易在舵机满偏、电机大油门时触发供电跌落,导致测距数据跳变——这种偶发性问题排查起来心力交瘁,不如一开始就规避。
接好线后,在QGroundControl里做两件事。第一,把对应串口的“串口配置”设为测距仪(或正常UART),波特率按传感器规格填写,TFmini系列默认115200;第二,把SENS_EN_RANGEFINDER设为1使能测距仪驱动,SENS_RNGFND_CFG填上对应的串口路径(比如/dev/ttyS2或/dev/ttyS6之类,取决于你用的是哪个口)。
4.2 参数配置和sensor_distance数据验证
上电后在QGroundControl的参数界面,按顺序检查以下几组参数:
先看驱动和测量范围:
| 参数 | 设置 | 说明 |
|---|---|---|
| SENS_EN_RANGEFINDER | 1 | 使能测距仪驱动 |
| SENS_RNGFND_CFG | 对应串口路径 | 绑定测距仪到串口 |
| SENS_RNGFND_MIN_MA | 0.1 | 测距下限(米) |
| SENS_RNGFND_MAX_MA | 12.0 | 测距上限(TFmini-S按12米填) |
| SENS_RNGFND_SCALE | 1.0 | 模拟型传感器线性比例,数字型保持1.0 |
| SENS_RNGFND_ORIENT | 3(DOWNFWD) | 传感器朝向下前方,按实际安装填 |
SENS_RNGFND_ORIENT这个参数容易被人忽略,填错了EKF会把测距方向当成水平测距,高度融合逻辑直接乱套。固定翼常规是朝下略带前倾,选DOWNFWD(朝下前方向),如果传感器正垂直朝下就选DOWN。
然后设置EKF融合参数,打开EKF2_RNG_AID并确认EKF2_RNG_AID_AID为1。
参数填完,重启飞控,再回到MAVLink控制台跑:
listener sensor_distance正常情况下控制台会持续打印类似这样的消息:
uORB::Publication sensor_distance timestamp: 127394123 (0.115s ago) time: 0 current_distance: 15.2 cm ...current_distance数值会随实际距离变化,到这一步说明硬件链路和驱动已经通了。如果数值固定在0或者始终是最大值,按顺序排查:波特率是否一致、串口路径是否填对、供电是否正常、信号线TX/RX有没有接反。我用经验担保,90%的问题是接反或波特率不匹配。
4.3 让EKF真正开始融合测距数据
驱动通了不代表EKF就自动开始用。还需要确认EKF2_RNG_AID为1,并且飞控的时间源、IMU校准都正常。调试时可以先把EKF2_RNG_AID打开并注释掉其他辅助手段,观察高度估计是否平滑。
我踩过的一个坑是:只开了EKF2_RNG_AID,但UAVCAN设备或传统串口测距仪同时存在时,参数SENS_RNGFND_CFG的串口路径总搞不对,导致明明使能了驱动,却一直没数据进EKF。后来发现是Pixhawk板子上的串口编号在不同飞控版本映射不一致,不要想当然填/dev/ttyS2,直接从QGC的“MAVLink控制台”执行:
ls /dev/ttyS*把RNG绑到实际能读到数据的那个串口上,这个问题才彻底解决。
5. 自动着陆flare参数调优,让“耀斑”变成“轻吻”
5.1 PX4固定翼自动着陆流程拆解
PX4的固定翼自动着陆分了几个阶段:进入着陆航段(进近对齐)、下滑道跟踪、flare拉平、接地减速。巡航转下滑道时飞控以固定下滑角控制高度和空速,进入flare阶段后,飞控不再追踪下滑道而是按照高度阈值触发拉平,把下沉率降低到安全范围。
先说几个真正的核心参数:
| 参数 | 作用 | 推荐起始值 |
|---|---|---|
| FW_LND_ANG | 下滑角(度) | 3.0 ~ 5.0 |
| FW_LND_FLALT | flare触发高度(米) | 1.0 ~ 1.5 |
| FW_LND_FL_PMAX | flare阶段最大俯仰角(度) | 8 ~ 10 |
| FW_LND_FL_PMIN | flare阶段最小俯仰角(度) | -4 ~ -2 |
| FW_LND_FL_TIME | flare持续时间(秒) | 2.0 ~ 3.0 |
| FW_LND_HVIRT | 虚拟高度校正(米) | 0.3 ~ 1.0 |
固定翼不支持像多旋翼那样的悬停减速,它的flare本质上是“姿态控制下的速度-下沉率转换”。飞控在下滑道阶段保持一个下沉率,到了flare高度时通过增大俯仰角把气动升力提高,下沉率快速收敛,落地的瞬间垂直速度被压到可接受范围。这里高度数据的实时性和精度直接决定flare触发时机,触发早了飞机变成“飘”状态,触发晚了等于砸地。
5.2 测距仪数据如何优化flare触发
默认情况下,PX4固定翼的flare高度参考是融合后的估计高度。如果你像前面那样把激光测距仪正确接入EKF,那么在低空段融合高度会快速偏向激光数据,此时FW_LND_FLALT的值就变得真实可信了。
我的调参经验是从FW_LND_FLALT = 1.2米开始,先配合仿真观察下沉率和接地速率。如果接地瞬间垂直速度偏大(垂向速度超过1.2m/s),说明flare触发太晚或者拉平姿态不够,就适当提高FW_LND_FLALT到1.5米,同时把FW_LND_FL_PMAX抬高到10度。如果飞机拉飘(接地前还有明显剩余高度、减速过快甚至陷入“飘”状态),就是flare触发过早,往回压FW_LND_FLALT到0.8米到1.0米。
需要注意,测距仪的物理安装高度会影响flare逻辑。假设激光测距仪装在机腹下方,它测的是“机腹离地高度”,而固定翼的着陆几何,真正决定接地点的是主轮/腹板的最低点。如果测距仪和主轮高度差有20厘米,那FW_LND_FLALT至少要加上这20厘米。这在真机上是个很容易忽略的细节——测距数据再准,安装基准和飞机着陆基准不一致,照样会拉平偏差。
另一个值得提的参数是FW_LND_HVIRT。这个参数本质上是给flare高度估计加一个“虚拟高度缓冲”,目的是防止EKF切换数据源时高度突变导致flare误触发。我建议从0.3米起调,如果发现每次着陆前高度估计都有一个小台阶跳变,就适当加大,直到接地前高度曲线平滑为止。
6. 仿真先行、真机收尾,常见问题排查速查
6.1 在Gazebo SITL里验证测距仪和自动着陆
真机试飞前强烈建议至少做一轮SITL仿真,Gazebo环境下固定翼模型配置激光测距仪的过程不复杂,但能帮你提前暴露参数和逻辑问题。
常规步骤是,先编译PX4 SITL固件并启动Gazebo:
cd ~/PX4-Autopilot make px4_sitl gazebo然后在你的固定翼模型文件(model.sdf)里加入测距仪plugin。以TFmini-S的参数为例,在机身底部加一个ray sensor,定义量程、角度和更新率:
<plugin name='laser_rangefinder' filename='libgazebo_ros_range.so'> <alwaysOn>true</alwaysOn> <updateRate>100</updateRate> <ray> <scan> <horizontal> <samples>1</samples> <resolution>1</resolution> <min_angle>0</min_angle> <max_angle>0</max_angle> </horizontal> </scan> <range> <min>0.1</min> <max>12.0</max> </range> </ray> <visualize>false</visualize> <frame_id>base_link</frame_id> <topicName>/rangefinder</topicName> </plugin>启动Gazebo后,在QGC里同样把SENS_EN_RANGEFINDER、EKF2_RNG_AID等参数按第4节配置好,然后在任务规划里添加一条着陆航线,切换自动模式看飞机是否能稳定完成进近、flare、接地。仿真里主要观察两个指标:flare触发高度是否稳定在设定值附近,接地垂直速度是否被压到可接受范围。
如果仿真中测距仪数据正常、自动着陆却失败,多半是参数组合问题,按第5节的方式逐项排查。真机和仿真环境的传感器噪声特性有差异,仿真里调好的参数到真机上可能还要微调,这个心态要有。
6.2 真机试飞的安全注意事项
真机试飞自动着陆前,我强烈建议先做几次遥控切换验证。具体做法是:解锁起飞后切到AUTO模式,让飞控接管下滑道,但在flare阶段前人工切回遥控把飞机拉起来,观察飞控在低空段的姿态和高度估计是否稳定。我习惯把第一次完整自动着陆放在天气良好、风速小于5m/s的环境里,跑道是长直草地(就算着陆姿态不好也不会炸太惨)。
真机试飞时焦距放这几个点:测距仪镜头有没有在滑跑中被地面杂物遮挡或弄脏;着陆滑跑后测距数据是否正常归零;多次飞行后测距仪是否因振动发生松动导致数据跳变。我在一次测试中就遇到过,TFmini的排线在振动下慢慢松动,飞到第三圈时数据偶发跳变,后来给接头打了704硅胶才稳定下来。
6.3 常见故障速查表
最后把我在实际项目里踩过、帮人排查过的高频问题整理成表格,方便你出问题时快速定位:
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| sensor_distance无输出 | 串口接反或波特率不匹配 | 检查TX/RX接线,核对115200波特率,执行listener验证 |
| 距离数据偶发跳变到满量程 | 供电跌落或信号线干扰 | 换独立BEC供电,信号线远离电调三相线,检查接头松动 |
| 低空高度估计发散 | EKF2_RNG_AID未启用,或传感器方向参数错误 | 确认EKF2_RNG_AID=1,检查SENS_RNGFND_ORIENT |
| flare触发明显偏早 | FW_LND_FLALT设置过高,或测距仪安装角度前倾过大 | 降低FW_LND_FLALT,修正测距仪俯仰安装角 |
| flare触发偏晚导致砸地 | FW_LND_FLALT过低,或测距仪安装基准高于着陆最低点 | 抬升FW_LND_FLALT,修正安装基准偏差 |
| 强光/镜面干扰下距离跳变 | 反光或传感器自动增益异常 | 加装遮光罩,避免对着水面/反光地面,尝试降低增益或加大滤波 |
排查顺序也有讲究,不要一上来就动EKF参数。先确认传感器数据健康,再用Flight Review或QGC的日志分析功能看高度估计和测距原始值的曲线关系。数据都没问题了再动参数,否则就是在错误的变量上做无用功。
最后说点实际操作中的体会
这套方案我前前后后在好几架不同尺寸的固定翼上试过,从1.6米翼展的泡沫机到2.8米的复合材料FPV平台,激光测距仪接入PX4后的自动着陆成绩差别很大,但规律是共通的——只要低空高度估计曲线平滑,flare就不会离谱。调这个系统最花时间的往往不是参数本身,而是让传感器数据在振动、光照、供电干扰下依然稳定工作。所以我建议你在试验前先花半天时间做地面振动测试和长距离行车测距模拟,把传感器和线束的可靠性搞定,再上天空飞,这样后面的事情都会顺利很多。
另外一个小技巧:调flare参数时别只盯着“有没有轻触地”这一个结果,把QGC日志里的EKF height、rangefinder distance、airspeed、pitch angle几条曲线拉出来一起看。你会发现每次落地姿态的差异根源基本上都在高度源切换的那一瞬间,如果能把切换做得平滑,着陆质量会从一个“偶尔好”变成一个“稳定好”的状态。这活儿做完之后,手动降落反而变得有点多余了——不是飞控多聪明,是低空高度数据终于做了回人做的事。