PX4飞控L1制导律:从航点追踪到航向保持的实战解析
1. L1制导律的前世今生从导弹到无人机我第一次接触L1制导律是在调试一架固定翼无人机时。当时飞机在转弯时总是画龙就像新手司机在高速公路上不断修正方向一样。后来在PX4飞控参数列表里发现了一个叫FW_L1_PERIOD的神秘参数这才打开了L1制导律的大门。L1制导律最初是为导弹设计的它的核心思想非常简单让飞行器始终朝着未来某个时间点的预测位置飞行。这个未来时间点就是L1距离相当于汽车驾驶中的视线引导——老司机不会盯着车头看而是看着远方道路来打方向盘。在PX4飞控中L1算法主要用在两个场景navigate_waypoints让飞机沿着预设的航点A→B→C飞行navigate_heading保持固定航向飞行比如测绘任务中的直线飞行实测下来L1比传统的PID控制更适合固定翼因为它考虑了飞机的动力学特性。就像骑自行车时你不会等到偏离路线才转向而是提前预判转弯幅度。2. 航点追踪的魔法navigate_waypoints详解2.1 航点间的三种位置关系假设现在要让飞机从航点A飞向航点BL1算法会根据飞机当前位置动态计算参考点。这里有个关键概念L1距离由FW_L1_PERIOD参数决定默认20秒可以理解为预瞄距离。飞机相对于航段AB的位置有三种情况正常追踪状态飞机位于航段AB的起始区域// PX4源码片段简化版 if (distance_plane_to_AB L1_distance) { reference_point 沿AB方向距离飞机L1_length的点; }此时参考点(reference_point)会放在航段AB的延长线上距离飞机正好一个L1距离。就像开车时看着前方100米的路面调整方向。航点切换状态飞机接近航点Belse if (distance_to_B L1_distance) { reference_point B; }当距离下一个航点不足L1距离时直接以航点B作为参考。相当于快到路口时司机开始盯着路口中心点准备转弯。错过航点状态飞机飞过了航段ABelse { reference_point B; // 紧急修正 _circle_mode true; // 进入盘旋模式 }如果因为风扰等原因错过航段飞控会命令飞机绕圈返回。这个逻辑我在野外测试时深有体会——有次强侧风导致飞机偏离航线就看到它自动画了个优美的弧线重新接上航线。2.2 横向加速度计算确定了参考点后算法会计算需要的横向加速度a_{lat} 2 \cdot V^2 \cdot \frac{\sin(\eta)}{L1}其中V是空速注意不是地速η是飞机当前航向与参考点连线的夹角L1是前文说的预瞄距离这个公式的物理意义很直观偏差角越大、速度越快需要的转弯力度就越大。PX4会将这个加速度转换为滚转角指令roll_setpoint atan2(a_lat, 9.81) * (180/M_PI); // 转换为角度这里有个实战经验FW_L1_PERIOD参数需要根据飞机性能调整。我的轻型测绘机用15秒而重型货运机需要25秒。值太小会导致飞机频繁摇摆太大则反应迟钝。3. 航向保持的秘诀navigate_heading解析当执行测绘等需要保持固定航向的任务时navigate_heading函数就开始发挥作用了。虽然原理类似但实现更简单// 伪代码表示逻辑 Vector2f reference_point 当前位置 L1_distance * 目标航向向量;这里L1算法会虚拟一个永远在前方的航点。我常用这个模式做电力巡线即使有侧风干扰飞机也能像被磁铁吸引一样牢牢咬住航线。有个容易忽略的细节当航向改变时比如从90°转到180°PX4会平滑过渡// 在commander模块中 heading_setpoint wrap_pi(heading_setpoint delta_angle * 0.05); // 每次只转5%的差值这种渐进式调整避免了急转弯。有次我直接修改目标航向90度结果飞机像醉汉一样晃晃悠悠转了半分钟后来才发现是这个过渡逻辑在起作用。4. 调参实战让L1算法发挥最佳性能4.1 关键参数表参数名默认值作用调整建议FW_L1_PERIOD20秒L1预瞄时间轻型机15-18秒重型机22-25秒FW_L1_DAMPING0.75阻尼系数风大时增至0.8-0.9FW_R_LL0.9滚转时间常数通常不需修改FW_L1_SKIP_PERIOD10秒航点跳过超时复杂地形可缩短4.2 调试技巧画圆测试设置4个构成正方形的航点观察转弯轨迹。理想的轨迹应该是平滑的弧线如果出现棱角说明L1_PERIOD需要增大。风扰测试在侧风条件下观察航向保持效果。如果飞机像螃蟹一样斜着飞需要适当增加L1_DAMPING。空速校准L1算法依赖真实空速。有次我的空速管堵塞导致算法误判飞机不断画8字。现在每次起飞前都会用手持风速仪校准。日志分析重点看vehicle_attitude_setpoint消息中的roll_setpoint变化曲线。健康的L1控制应该是平滑的正弦波如果出现锯齿状说明需要调整参数。记得有次帮客户调试农药喷洒机发现转弯时药液洒布不均匀。最后把L1_PERIOD从20调到16秒同时将roll_rate_limit放宽到60度/秒问题完美解决。这种细节只有实际踩过坑才能体会。5. 进阶应用特殊场景处理5.1 山地飞行在起伏地形中单纯的L1控制可能导致飞机撞山。这时需要配合FW_ALT_MODE参数设置为0默认保持相对高度设置为1保持绝对海拔高度我在阿尔卑斯山做冰川监测时就遇到过飞机在下降段突然拉起的惊险情况。后来发现是因为默认模式会维持与地面的相对高度当飞越悬崖时突然看到地面高度骤降导致紧急爬升。改用绝对高度模式后问题消失。5.2 编队飞行用L1实现多机编队是个有趣的应用。僚机可以把长机的轨迹点作为虚拟航点// 伪代码 if (is_wingman) { waypoint_A leader_position - offset; waypoint_B leader_position leader_velocity * L1_period - offset; }实测时需要特别注意每架飞机的FW_L1_PERIOD必须完全一致建议关闭GPS更新延迟补偿EKF2_GPS_DELAY0通信延迟超过200ms时建议改用其他编队算法5.3 应急处理当GPS信号丢失时L1算法会自动退化到航向保持模式。但这里有个隐患如果丢失前飞机正在转弯初始的heading_setpoint可能是斜向的。我的应急方案是param set EKF2_MAG_CHECK 0 # 禁用磁罗盘检查 param set COM_POS_FS_DELAY 5 # 延长位置失效判定时间这些经验都是用炸机换来的。最惨的一次是在峡谷中GPS信号被遮挡飞机进入应急模式后保持错误航向直撞山壁。现在我的所有机型都加装了激光雷达避障。