PX4 与 ROS 无人机 Offboard 控制模式解析及实战实现
深入解析 PX4 六大核心飞行模式,重点阐述 Offboard 模式的工作原理及其在 ROS 系统中的控制方法。通过 C++ 实现包含自动起飞、悬停、轨迹跟踪(圆/方/螺旋)及降落的完整状态机控制程序。文章涵盖代码结构设计、核心算法实现、参数配置、编译运行及安全失效保护机制,适用于无人机自主飞行开发与科研实践。

深入解析 PX4 六大核心飞行模式,重点阐述 Offboard 模式的工作原理及其在 ROS 系统中的控制方法。通过 C++ 实现包含自动起飞、悬停、轨迹跟踪(圆/方/螺旋)及降落的完整状态机控制程序。文章涵盖代码结构设计、核心算法实现、参数配置、编译运行及安全失效保护机制,适用于无人机自主飞行开发与科研实践。

无人机自主飞行是机器人领域的热门方向,而 PX4 作为功能强大的开源飞控,配合 ROS(机器人操作系统)的灵活性与生态,成为实现高级自主飞行的黄金组合。然而,许多初学者对 PX4 的飞行模式理解不清,更不知道如何通过 ROS 编写可靠的 Offboard 控制程序。
本文将带你彻底搞懂 PX4 核心飞行模式,实现无人机的自动起飞、悬停、轨迹跟踪(圆形/方形/螺旋)与降落。
PX4 的飞行模式可以看作一个控制权逐级递增的层级结构。理解这些模式是编写控制程序的前提。
包括任务模式 (MISSION)、返航模式 (RTL)、降落模式 (LAND)、起飞模式 (TAKEOFF) 等。由飞控内部逻辑执行预设任务,无需外部持续指令。
通过 ROS(通常借助 MAVROS)控制 PX4,主要有两种方式:模式切换和直接指令发送。
MAVROS 理论上可以切换到任何已配置的飞行模式,最常用于:
OFFBOARD:最关键的模式,切换到此模式才能发送流式控制指令。POSCTL:作为 Offboard 前的准备,或安全回退模式。AUTO.MISSION / AUTO.RTL / AUTO.LAND:启动自动任务、触发返航或降落。服务调用示例:
rosservice call /mavros/set_mode "base_mode: 0 custom_mode: 'OFFBOARD'"
| 模式 | 是否接受 ROS 流式控制 | 控制方式 |
|---|---|---|
OFFBOARD | 是 | 发送 setpoint_position/setpoint_velocity 等指令 |
POSCTL/ALTCTL | 否(可模拟 RC) | 通过 mavros/rc/override 模拟遥控器输入,不推荐 |
| 其他 | 否 | 仅能通过服务切换模式,不能实时控制 |
结论: 实现 ROS 程序控制的唯一标准方法是使用 Offboard 模式。
我们将创建一个名为 px4_offboard_control 的 ROS 功能包,实现以下功能:
技术栈:ROS Melodic/Noetic、C++14、MAVROS、PX4 SITL、Eigen、TF2。
px4_offboard_control/
├── CMakeLists.txt
├── package.xml
├── launch/
│ └── offboard_control.launch # 主启动文件
├── config/
│ └── params.yaml # 参数配置文件
├── include/
│ └── px4_offboard_control/
│ └── trajectory_generator.h # 轨迹生成器头文件
└── src/
├── offboard_control.cpp # 主控制节点(含状态机)
└── trajectory_generator.cpp # 轨迹生成器实现
TrajectoryGenerator:负责生成各种轨迹点,并提供从当前位置到目标点的速度指令计算(P 控制器)。
OffboardControl:主控制类,包含:
INIT -> ARMING -> TAKEOFF -> HOVER -> FOLLOW_TRAJECTORY -> LAND -> DISARM -> 结束
每个状态都有超时或条件判断,确保安全转换。
生成圆形轨迹:
std::vector<geometry_msgs::PoseStamped> generateCircleTrajectory(
const geometry_msgs::PoseStamped& start_pose,
double radius, double height, int points, int num_loops)
{
std::vector<geometry_msgs::PoseStamped> traj;
for (int loop = 0; loop < num_loops; ++loop) {
for (int i = 0; i < points; ++i) {
double angle = 2.0 * M_PI * i / points;
pose.pose.position.x = start_pose.pose.position.x + radius * cos(angle);
pose.pose.position.y = start_pose.pose.position.y + radius * sin(angle);
pose.pose.position.z = height;
// 使无人机始终指向圆心(可选)
double yaw = atan2(-sin(angle), -cos(angle));
pose.pose.orientation = getQuaternionFromYaw(yaw);
traj.push_back(pose);
}
}
return traj;
}
速度指令计算:使用简单的 P 控制器,将位置误差转换为速度指令,并限制最大速度。
状态机处理示例(起飞状态):
void handleTakeoffState(ros::Rate& rate) {
geometry_msgs::PoseStamped target_pose;
target_pose.pose.position.z = home_pose_.pose.position.z + takeoff_height_;
if (use_position_control_) {
local_pos_pub_.publish(target_pose);
if (fabs(current_pose_.pose.position.z - target_pose.pose.position.z) < pos_tolerance_) {
ROS_INFO("Reached takeoff altitude");
control_state_ = HOVER;
}
} else if (use_velocity_control_) {
auto vel_cmd = trajectory_gen_.calculateVelocityCommand(current_pose_, target_pose, ...);
local_vel_pub_.publish(vel_cmd);
if (vel_cmd.twist.linear.z == 0) {
control_state_ = HOVER;
}
}
}
Offboard 模式切换与解锁:
bool setMode(std::string mode) {
mavros_msgs::SetMode srv;
srv.request.custom_mode = mode;
return set_mode_client_.call(srv) && srv.response.mode_sent;
}
bool arm(bool arm) {
mavros_msgs::CommandBool srv;
srv.request.value = arm;
return arming_client_.call(srv) && srv.response.success;
}
主循环:以 20Hz 运行,根据当前状态调用对应的处理函数,并持续发送设定点以维持 Offboard 模式。
# 基本参数
takeoff_height: 2.0
hover_duration: 5.0
pos_tolerance: 0.1
# 控制模式(只能选一个)
use_position_control: true # 位置控制模式
use_velocity_control: false # 速度控制模式
# 轨迹类型(circle / square / spiral)
trajectory_type: "circle"
# 速度限制
max_linear_vel: 1.0
max_angular_vel: 0.5
# 可视化
publish_trajectory: true
启动 MAVROS 和 Offboard 控制节点,可传参:
<arg name="trajectory_type" default="circle"/>
<arg name="takeoff_height" default="2.0"/>
...
<node name="offboard_control" pkg="px4_offboard_control" type="offboard_control" output="screen">
<param name="trajectory_type" value="$(arg trajectory_type)"/>
...
</node>
cd ~/catkin_ws
catkin_make
source devel/setup.bash
roslaunch px4_offboard_control offboard_control.launch trajectory_type:=circle
将看到无人机自动起飞、悬停、执行圆形轨迹,最后降落。
测试场景:
观察指标:
可视化:程序会发布 /planned_trajectory 话题,可在 RViz 中显示路径。
COM_RCL_EXCEPT:允许在遥控器丢失时仍保持 Offboard(谨慎)。COM_OF_LOSS_T:Offboard 指令超时后切换到什么模式(建议设为 21 或 20,即降落或返航)。mavros/state 中的 armed 和 mode,异常时自动降落。本文详细解析了 PX4 飞行模式,并提供了一个完整的 ROS Offboard 控制实现。你可以在此基础上:
参考文献:

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online