
开头我就不绕弯子了直接说结论ego-planner在Gazebo仿真里跑得再顺离真机上能稳定自主穿树林还差着十万八千里。这篇东西不是给你讲原理的是给你一条从零到一、把Jetson Orin-NX和Pixhawk 6C这套组合真正飞起来的路。我见过太多人卡在同一个地方仿真里一切正常一上真机就各种灵异现象——要么无人机原地抽风要么高度突然往下掉要么压根切不进offboard。这背后大部分不是算法问题而是通信链路、坐标系、时间戳、参数这些脏活没处理干净。这篇文章就是把我在这个过程中走过的弯路、踩过的坑、最后验证有效的方法全部写出来照着做能让你少折腾至少两个星期。1. 为什么是Orin-NX Pixhawk 6C ego-planner这组搭档1.1 算力与飞控的分工逻辑先说清楚这套系统的角色划分。Pixhawk 6C是飞控管的是最底层的事IMU数据读取、姿态解算、电机控制、PWM输出它跑的是PX4固件控制频率通常在250Hz到1kHz之间。Jetson Orin-NX是机载计算机管的是脑子层面的事相机图像处理、VIO里程计、点云生成、路径规划最后输出一个期望位置或者期望速度给飞控。飞控再把这个期望值翻译成具体的油门和舵量。这就像开车Pixhawk是手脚负责执行Orin-NX是眼睛和大脑负责看路和决定往哪走。你不可能让飞控去跑ego-planner这种需要大量优化的算法——它的CPU根本扛不住也没那个必要。反过来你也不能让Orin-NX直接去控制电机——实时性没法保证。1.2 ego-planner到底解决什么问题ego-planner全称是Edge-aware Gradient-based Online planner从名字就能看出来两个关键点基于梯度的优化、在线生成。核心就是在保证轨迹平滑可飞的同时尽可能贴近障碍物边缘飞行这样无人机不会像个惊弓之鸟一样离障碍物八丈远就绕路而是能贴边穿过去。和传统的A*、RRT这类基于搜索的规划器不同ego-planner不构建显式的障碍物地图而是直接把传感器点云当成斥力源来做梯度优化。这意味着它天然适合机载场景——不需要先建一张全局栅格图省掉了大量计算和内存开销。它的前端有基于快速搜索随机树RRT的路径发现后端有B样条轨迹优化两者配合使得算法在Orin-NX这种级别的算力上能跑到20Hz以上的规划频率。1.3 这套组合适合谁如果你是想做无人机编队、复杂的全局自主导航、长距离勘探那ego-planner并不适合你——它是个局部规划器没有全局地图的概念飞丢了大概率救不回来。但如果你想做的是近距离避障、穿林飞行、快速自主探索未知环境这套组合就是目前开源社区里最成熟的方案之一。还有一个前提你得对ROS、Linux基础操作有一定了解至少知道catkin_make是干嘛的、什么是话题topic、什么是TF变换。完全零基础的话建议先把ROS入门教程过一遍再回来。2. ego-planner的代码脉络与仿真闭环搭建2.1 代码仓库与依赖准备代码这块建议直接用Fast-Drone-250这个仓库它是ego-planner团队浙大FAST-Lab出的配套教程工程自带精简版ego-planner实现、PX4飞控仿真环境、以及一个专门为无人机设计的VIO适配层。仓库里给的说明文档是中文的对新手极其友好。依赖方面你需要准备Ubuntu 18.04或20.04推荐20.04ROS Melodic或Noetic对应Ubuntu版本别装错PX4-Autopilot固件源码Fast-Drone-250自带编译脚本版本锁定在1.13.x左右GazeboPX4官方推荐版本为9或11具体看仓库要求装依赖的时候最容出问题的就是PX4固件和Gazebo插件的版本匹配。我的建议是严格按照仓库的README装不要手痒去拉最新版PX4否则大概率会遇到mavlink消息类型对不上、插件加载不进来之类的问题。环境变量记得写入~/.bashrc每次开新终端都要能直接跑gazebo才行。2.2 仿真闭环的三个不等于仿真跑通之后不要急着欢呼先对着下面三条自查一遍这是我从惨痛教训里总结出来的第一仿真能跑不等于你理解了整个链路。我在仿真阶段其实很早就跑通了无人机在随机障碍物里穿梭的demo但后来真机调参时才发现我连ego-planner订阅的是什么话题、发布的是什么坐标系都说不清楚。仿真环境里隐藏了大量你不知道但不需要处理的细节比如mavros帮你做好的坐标转换、PX4仿真环境下自动处理的姿态话题这些在真机上全部要自己搭。第二参数设置合理不等于真机也能用同样的参数。Fast-Drone-250的仿真默认参数是给一个理想化的小型四旋翼调的机体质量、电机响应、传感器延迟都和你的真机不一样。我在仿真里把最大速度设到3m/s飞得飞快第一次上真机试了试直接吓得手心出汗——真机到3m/s的时候那种机动性带来的压迫感完全不是仿真能模拟的。第三能稳定起降不等于能安全切换offboard。仿真里切换offboard模式就是让飞控交给外部程序控制是零成本的但真机上切换的瞬间如果期望位置和当前位置偏差过大飞控会用力补偿结果是直接飞走。这个后面在参数迁移的章节详细讲。2.3 仿真阶段应该做的事跑通全链路学会看日志仿真阶段真正的目标只有一个全链路无死角地跑通同时知道每个节点在干什么、输出什么、依赖什么。我建议你在仿真里做这几件事用rosnode listrqt_graph看清所有节点之间的通信关系确认ego_planner_node订阅的点云、里程计、状态话题分别来自哪里。用rostopic echo逐个确认消息内容。比如/odom的坐标系是odom还是world/pointcloud的PointCloud2消息的frame_id是什么。仿真环境里这些往往不显眼但对后续真机有决定性影响。手动修改一次规划参数比如把max_vel从1.5改成3.0观察飞行轨迹的变化建立参数→行为的直觉。3. 真机前夜硬件接线、PX4配置与通信链路3.1 机载电脑与飞控的连接方式首先明确一个底层原则Jetson和Pixhawk之间是串口通信走MAVLink协议。两边的连接就两根线——TX、RXPixhawk的TELEM口一般是TELEM2接Jetson的UART口。要注意的是Jetson的GPIO引脚电平是3.3V不要直接接5V的串口设备最好通过电平转换芯片否则有烧毁GPIO的风险。我这里用的方案是USB转TTLPixhawk的TELEM2口接到一个USB-TTL转接模块模块另一头插Jetson的USB口。这样做的原因很简单——USB口即插即用用ls /dev/ttyUSB0就能看到设备不需要配置设备树排查起来也方便。代价是理论上USB的实时性不如原生UART但实际跑起来没遇到瓶颈。3.2 PX4端要改的参数PX4固件这边需要配置的参数一条条列给你MAV_1_CONFIG TELEM2设置MAVLink通道使用的物理串口。MAV_1_MODE Onboard设置MAVLink模式为机载模式此时飞控会以较高的频率发送机载需要的消息。SYS_COMPANION Companion告诉PX4连接了一个机载计算机这会调整部分消息发送策略。SYS_AUTOSTART根据你的机架类型设置机型比如400是四旋翼X布局。BAT*系列参数根据你的电池型号和容量设置电压阈值。这个务必设置准确否则飞行中可能直接触发低压保护降落。改完参数后重启飞控在QGroundControl里确认能看到MAVLink连接已经在TELEM2上工作。3.3 通信层mavros的配置与自检Jetson端跑的是mavros节点把MAVLink协议翻译成ROS话题。mavros配置需要注意几个关键点在px4_config.yaml里把fcu_url改成你的设备路径fcu_url: /dev/ttyUSB0:921600波特率要飞控端匹配。PX4的TELEM2默认波特率是921600如果你飞控端没改这里就填921600两边不一致会导致通信乱码。mavros配置好之后用roslaunch mavros px4.launch启动然后依次确认rostopic echo /mavros/state能看到connected: True以及armed、guided、mode的变化。rostopic echo /mavros/local_position/odom有数据说明飞控在发布本地位置。rostopic hz /mavros/imu/data频率稳定在100Hz左右说明链路通畅。有一个非常容易踩的坑mavros的setpoint_raw/local话题在飞控解锁前就能发布但飞控不会执行。如果你发现程序在跑、话题有数据、但电机不动别慌先检查飞控状态机是否处于可解锁状态QGroundControl里有没有弹出解锁限制条件。3.4 TF树与时间同步——90%的灵异现象源头这是整个链路里最枯燥也最容易出问题的一环。ego-planner规划出来的轨迹是有坐标系语义的如果TF树不对飞控收到的期望位置就可能是在一个错误的参考系下轻则无人机悬停位置偏重则直接失控。一个正常的TF树应该长这样world - odom - base_link - camera_link但实际中有些VIO方案输出的里程计本身就在world系下此时就变成world(odom) - base_link - camera_link需要根据你的视觉里程计方案灵活处理核心是保证ego_planner订阅的里程计消息和点云消息在同一个参考系里对齐。时间同步也是个隐形杀手。VIO节点产生的位姿时间戳如果和点云时间戳对不上规划器算出来的轨迹就是基于一个过期状态的估计轻则轨迹抖动重则撞障。我的解决方案是让VIO帧率图像帧率和点云发布频率都对齐到30Hz用message_filters在ego_planner节点里做时间同步超过10ms的丢帧直接丢弃。4. 从仿真到真机的参数迁移——一个参数一个参数地抠4.1 控制器增益先让你的飞机听话Fast-Drone-250真机适配里有一个单独的控制器节点px4_pos_controller它把ego-planner规划的期望位置转换成速度指令再通过mavros发给PX4。默认参数是为仿真调的真机上通常需要重新调。核心参数是三个traj_xy_gain水平位置误差的增益。traj_z_gain垂直方向增益。hover_xy_gain、hover_z_gain悬停时的平滑增益。我的经验是从仿真默认值的一半开始飞起来之后观察悬停精度和跟踪误差。如果无人机在悬停时频繁修正、有一冲一冲的感觉说明traj_xy_gain偏大降下来如果跟踪轨迹时总是慢半拍、转弯明显落后说明增益偏小。真机上调参要小步快跑每次改10%左右悬停稳定了再试小范围飞行千万别一上来就往大了调。4.2 规划器参数限制梦想保护真机ego-planner节点ego_planner_node里的参数在仿真里可以很激进真机上必须收敛。我整理了一份自己的配置基准参数仿真默认真机推荐影响max_vel3.0 m/s1.5 ~ 2.0 m/s最大飞行速度过高容易来不及避障max_acc3.0 m/s²2.0 m/s²最大加速度过高会让电机饱和轨迹变形flight_height1.0 m1.5 ~ 2.0 m默认飞行高度真机上太低了地面噪点干扰大obstacles_inflation0.15 m0.3 ~ 0.5 m障碍物膨胀半径真机安全性全靠它pointcloud_hit0.20.4点云命中阈值调高能减少误报点特别注意obstacles_inflation这个参数室外环境下激光雷达或者深度相机扫到的点云噪声远比仿真多膨胀半径过小的话规划的轨迹会离障碍物太近稍有风或者定位偏差就可能蹭上去。我最终是取0.4m保证树叶、细枝这种点云噪点不会被当作威胁。4.3 传感器朝向一个不起眼但致命的参数很多VIO方案比如VINS-Fusion、Realsense的T265初始化时会输出一个初始朝向如果你的相机安装方向和机体坐标轴不一致VIO输出的里程计会带一个固定偏移。这个偏移如果不补偿ego-planner规划出来的轨迹在真机上就是歪的。解决方案是在VIO启动前做一个静态TF标定把camera_link到base_link的变换写死在launch文件里同时用static_transform_publisher发布出来。具体怎么标定拿一个量角器加一把直尺量出相机光心相对机体中心的三轴偏移和三个欧拉角就行。注意不同安装方式朝前、朝前下45度对应的roll/pitch/yaw值差异很大不要凭感觉填。5. 首飞实测与一次完整的炸机排查5.1 炸机现场无人机在offboard模式下突然急速下坠那次炸机发生在我第三次真机测试时。流程是可以正常解锁切到定高模式起飞悬停到1.2m高度然后在地面站里切换offboard模式。切换前一切都正常切完不到两秒无人机直接往下坠——不是缓慢下沉是动力全部输出为0、自由落体级别的下坠。好在只砸在草地上桨叶断了两根机架没大伤。5.2 排查链路从现象反推根因我复盘时没有直接去翻代码而是先列了一个可能导致下坠的清单逐项排查第一嫌疑PX4的offboard切换条件不满足。PX4有一个安全机制从自稳模式切到offboard时如果期望位置和当前位置相差超过某个阈值飞控会拒绝切换或者切换后有一个强制追踪的过渡。但我的排查结果是QGroundControl里显示已经成功进入offboard而且无人机是先进入offboard、然后才下坠的所以这个排除。第二嫌疑ego-planner发布的期望位置错误。我用rostopic echo /command/pos看发布的位置发现数值一直在正常范围内高度1.2m附近抖动没有跳变。这个也排除。第三嫌疑mavros的setpoint_raw话题频率不够或者丢失。PX4手册明确要求offboard模式下必须连续收到设定点消息推荐10Hz以上如果超过1秒没收到飞控会退出offboard回到上一个模式。我录了包回放发现mavros在切换offboard后大约0.5秒内就不再收到ego-planner的设定点了而ego-planner节点本身还在正常运行。到这里基本锁定问题出在ego-planner → mavros之间的通信链路上。第四嫌疑坐标系/消息类型不匹配导致mavros丢弃消息。打开mavros的log发现它报了一个TRANSFORM相关的warning然后拒收了一条setpoint_raw/local消息——因为这条消息的frame_id和mavros期望的不一致。原来我在ego-planner的发布端把frame_id写成了base_link而mavros要求必须是local_origin也就是PX4的本地坐标系二者差了一个机体航向角。在仿真里PX4用的local系和世界系对齐所以从来没有暴露过这个问题真机上机体是旋转的消息一来就直接冲突。5.3 修复方案与复盘教训修复很粗暴但有效在ego-planner发布setpoint的代码里把frame_id从base_link改成map然后在TF树里把map到local_origin的变换在mavros侧做好。改完重新编译、跑通信自检、离地悬停测试再切offboard问题消失。这次炸机让我明白三件事仿真环境里恰好能工作的参数和坐标系恰恰是最危险的盲区。很多问题之所以在仿真里不出现是因为仿真环境做了太多隐含假设。offboard切换必须是最高优先级的功能测试。绝对不要在没验证offboard切换的情况下就去跑完整路径规划。先把切offboard、悬停、手动接管这一整套动作练到肌肉记忆再谈自主飞行。录包是排查问题的最好手段。那次炸机我能这么快定位完全得益于当时开着rosbag record -a。炸机之后回放数据几分钟就找到了线索。6. ego-planner的边界条件与安全兜底6.1 规划器的自我保护机制ego-planner的代码里其实有几个内置的刹车机制我在读代码时发现它们非常关键第一状态机的异常处理。ego-planner有一个状态机在还未收到有效里程计和已经正常规划之间切换。如果它长时间收不到里程计或者点云会停在原地发布悬停指令而不是继续按最后一条轨迹飞。这是保命的机制——但前提是你没把异常状态下的指令当正常指令用。第二轨迹刷新率限制。规划器默认在新轨迹生成前会沿用上一条轨迹的剩余部分。这就意味着如果上一条轨迹规划时离障碍物太近即使现在障碍物已经不在视野里无人机还是会盲飞一段。所以真机上max_vel设小一点、obstacles_inflation设大一点本质上是给这个盲飞段留安全缓冲。6.2 手动接管你的最后一道防线不管ego-planner多成熟手动接管永远是你最重要的逃生通道。我的做法是遥控器的飞行模式开关一个档位是自稳Stabilized另一个档位是offboard。遇到任何不对劲先把模式开关打回自稳同时直接把油门杆拉到底——这样至少能保证无人机不会继续执行错误的自主指令。这里有个细节飞控从offboard切回自稳后会丢失外部期望位置此时需要你先手动稳住姿态再决定下一步怎么办。不要指望切回去之后飞控还帮你维持高度——自稳模式的油门是你给多少它飞多少给少了就下沉给多了就抬头需要你手动接管。6.3 电量管理与飞行边界真机飞行前一定要检查电池电压我建议用一块满电的4S或者6S电池电压低于3.8V/cell就直接换。ego-planner在室外飞行的功率消耗比室内高不少——频繁加减速、急转弯、来回调整位置电机的瞬时电流可以逼近峰值。我测试时飞了8分钟左右电池就到3.75V了规划器还在正常跑但飞控已经在报警低压这时候退出offboard手动降落已经是必须的。另外真机测试场地选择也很重要。初期测试尽量选开阔的草地周围没有铁丝网、电线、树木即便失控也有缓冲区域。可以在场地四周拉一圈安全线安排两个人在对角位置站着一人盯飞机一人盯遥控器和地面站屏幕。7. 从仿真到真机的最后一公里跑通一次完整的自主飞行真机自主飞行和仿真不同不是启动launch文件等飞机自己飞就完了。我的标准流程写给你作参考起飞机检清单电池电压在安全范围内桨叶安装方向正确螺丝拧紧。QGroundControl里确认飞控能收到GPS或光流数据室内光流也需要确保本地位置估计正常。Jetson上确认所有节点runningrosnode list里能看到ego_planner_node和mavrosrqt_tf_tree里TF树完整。rostopic echo /mavros/state里确认connected: True模式处于手动/自稳。起飞流程遥控器开锁切到自稳模式手动起飞到1.5m高度。观察悬停是否稳定这个高度下如果抖动明显先降下来调参数。切换offboard模式观察无人机是继续稳在一个点上还是开始飘。我的经验是如果一切正常切过去后机身会有一次非常轻微的点头动作那是飞控从内部姿态控制切换到外部位置控制的正常过渡。确认悬停稳定之后在另一个终端里运行预先写好的路径发布脚本或者手动给出一组目标点观察无人机是否按预期沿着轨迹飞。全程手握遥控器拇指放在模式开关上任何异常立刻切回自稳。飞行中观察什么轨迹是否平滑真机上飞出来的轨迹应该是连续、圆润的曲线如果出现锯齿形修正说明参数太激进。是否有贴边效果ego-planner的招牌能力是贴近障碍物飞行真机测试时可以和障碍物保持一个安全距离再观察如果规划轨迹离障碍物太远了说明膨胀半径设得偏大。高度是否能保持如果飞行中高度慢慢漂移说明VIO的高度估计在退化室外GPS辅助或者室内光流都会影响需要检查传感器融合。落地流程从offboard切回自稳。手动控制降落不要依赖自主降落。落地后立即解锁其实就是把油门杆拉到最低飞控会自动上锁。保存所有节点日志和rosbag回头看曲线调整参数。这套流程跑通之后你才算真正意义上用ego-planner在真机上自主飞行了一次。关于后续的扩展方向我个人的建议是先把Fast-Drone-250自带的VIO方案Robust-VIO彻底摸透再去尝试换Realsense、换Livox激光雷达或者把规划器换成Fast-Planner做全局规划。不要一上来就追求大而全ego-planner这套系统的精髓在于每个环节都能单独调试和验证逐层把底层打牢上层才会稳定。我踩过最大的坑就是跳过底层联调直接跑整机测试最后花在排查问题上的时间远大于重新走一遍流程的时间。希望你不用再交这个学费。