1. 课程导入
无人机自主飞行能力的核心,不在于单个控制环路的参数调得多好,而在于机载计算机能否持续、稳定、实时地把期望指令交给飞控。PX4 与 ROS 2 的组合,正是当前开源无人机领域最主流的“外部控制”方案:PX4 负责姿态与位置底层控制、传感器融合与安全保护,ROS 2 负责感知、规划、决策与任务调度。本课程的目标,是让你从“会飞”走到“会控”,最终能够独立设计并调试一套 Offboard 外部控制程序。
一、学习目标:从接口调用到系统集成
本课程不是简单的 API 手册,而是围绕一条完整的工程链路展开。学完之后,你应当具备以下能力:
- 理解架构:说清 PX4 内部 uORB 消息总线、commander、navigator、mc_pos_control 等模块与外部控制之间的关系。
- 掌握接口:熟练使用 uXRCE-DDS 与 Micro XRCE-DDS Agent,在 PX4 与 ROS 2 之间建立话题桥接。
- 编写控制:用 C++ 或 Python 编写 Offboard 节点,发布
TrajectorySetpoint、OffboardControlMode、VehicleCommand等消息。 - 调试排障:能通过 QGC、ros2 topic、px4 日志定位“切不进 Offboard”“飞机不响应”“模式自动退出”等典型问题。
- 安全设计:理解失效保护、遥控器接管、地理围栏与 Offboard 心跳超时的联动逻辑。
二、核心概念:外部控制与 Offboard 的本质
PX4 的飞行模式中,Offboard 模式的含义是:位置、速度或姿态的期望值不再由遥控器或内部航点生成,而是由外部系统通过 MAVLink 或 uXRCE-DDS 持续输入。这里的“外部”通常就是运行 ROS 2 的机载计算机。理解 Offboard,需要抓住三个关键词:
- 期望值流:外部系统以固定频率发布 setpoint,PX4 内部控制器跟踪这些期望值。
- 心跳约束:Offboard 模式要求 setpoint 流不能中断,超时后 PX4 会自动退出该模式并触发失效保护。
- 权限边界:外部控制并不绕过 PX4 的安全检查,解锁、模式切换、失控保护仍由 PX4 的 commander 统一裁决。
关键认知:Offboard 不是“把飞控交给电脑”,而是“电脑给出期望,飞控决定如何安全地实现”。PX4 始终保留最终控制权与安全兜底能力。
三、整体框架:从 ROS 2 节点到电机输出
下图展示了本课程要打通的核心数据链路。左侧是 ROS 2 侧的应用节点,中间是 uXRCE-DDS 桥接层,右侧是 PX4 内部的控制与执行链路。理解这张图,就理解了整门课的骨架。
从图中可以看到,ROS 2 侧的 Offboard 控制节点并不直接驱动电机,它只负责把期望轨迹写入 trajectory_setpoint,把模式切换请求写入 vehicle_command。PX4 的 commander 判断是否允许进入 Offboard,mc_pos_control 与 mc_att_control 再逐级跟踪期望值。这条链路中任何一环断裂,飞机都不会按预期运动。
四、学习路径:四个阶段循序渐进
为了让知识可落地,本课程按“环境—接口—控制—实战”四阶段推进:
- 环境搭建:安装 PX4、ROS 2、Gazebo 仿真,配置 uXRCE-DDS Agent,跑通第一个话题桥接。
- 接口打通:理解
px4_msgs消息定义,掌握时间戳、坐标系、NED/ENU 转换等易错点。 - 控制实现:从位置控制到速度控制,再到轨迹跟踪,逐步编写并验证 Offboard 节点。
- 实战排障:在仿真与真机上复现典型故障,建立日志分析与安全策略设计能力。
五、典型场景与常见误区
一个典型场景是:无人机起飞后进入 Offboard,按圆形轨迹飞行,同时接收视觉定位数据。此时 ROS 2 节点需要以不低于 2 Hz 的频率发布 setpoint,否则 PX4 会判定外部控制失效。很多初学者第一次调试时,飞机刚切模式就退出,原因往往不是算法错误,而是发布频率不足、时间戳单位错误或坐标系方向反了。
| 常见现象 | 可能原因 | 排查方向 |
|---|---|---|
| 无法进入 Offboard | 未先发送 setpoint 流 | 先持续发布再请求切模式 |
| 进入后立即退出 | setpoint 超时或频率过低 | 检查发布周期与心跳 |
| 飞机朝反方向飞 | NED 与 ENU 坐标混用 | 核对坐标系与符号 |
| 位置漂移严重 | 定位源不稳定或时间戳错 | 检查 VIO 与时间同步 |
安全提醒:所有 Offboard 实验应先在 SITL 仿真中完成验证,真机测试必须保留遥控器接管能力,并设置合理的失效保护动作。切勿在人员密集区域直接测试未验证的控制程序。
六、一个最小 Offboard 控制片段
下面这段伪代码展示了 Offboard 节点的基本节奏:先持续发布 setpoint,再发送切换模式命令,最后循环更新期望位置。它是后续所有复杂控制程序的起点。
// 1. 持续发布 OffboardControlMode 与 TrajectorySetpoint
publish_offboard_control_mode();
publish_trajectory_setpoint(0.0f, 0.0f, -5.0f); // NED: 上升 5 米
// 2. 发送切换 Offboard 模式命令
VehicleCommand cmd{};
cmd.command = VehicleCommand::VEHICLE_CMD_DO_SET_MODE;
cmd.param1 = 1; // 自定义模式
cmd.param2 = 6; // PX4_CUSTOM_MAIN_MODE_OFFBOARD
publish_vehicle_command(cmd);
// 3. 循环更新期望值,保持频率 >= 2Hz
while (ros::ok()) {
publish_trajectory_setpoint(x, y, z, yaw);
sleep(50ms);
}