3. ROS2基础
PX4 的外部控制与 Offboard 开发,本质上是在 ROS 2 的计算图(Computation Graph)中,让一个或多个节点与 PX4 的 uXRCE-DDS 桥接节点交换数据。因此,理解 ROS 2 的通信模型,是后续编写 Offboard 控制程序、调试话题频率、排查“指令发不出去”问题的前提。本节把 ROS 2 的核心概念串成一条主线:节点是执行单元,话题/服务/动作是三种通信方式,参数是节点配置,Launch 是启动编排,命令行工具是观察与验证手段。
一、核心原理:节点与三种通信机制
ROS 2 采用分布式节点架构。每个节点(Node)是一个独立进程,通过 DDS 中间件自动发现彼此,无需中心 Master。节点之间通过以下方式交互:
- 话题(Topic):发布/订阅模型,异步、单向、多对多,适合高频连续数据流,如
/fmu/out/vehicle_odometry、/fmu/in/trajectory_setpoint。 - 服务(Service):请求/响应模型,同步、双向、一对一,适合一次性命令,如解锁、切换模式、设置参数。
- 动作(Action):基于话题和服务的组合,支持长时任务、周期反馈与可取消,如“飞往某航点并持续上报进度”。
- 参数(Parameter):节点的运行时配置项,可动态读写,如控制增益、超时阈值、坐标系选择。
在 PX4 Offboard 场景中,最常用的是话题:PX4 通过 uXRCE-DDS 把 /fmu/out/* 发布出来,外部控制节点订阅状态,并向 /fmu/in/* 发布设定值。服务与动作则用于模式切换、解锁、任务级控制等非连续交互。
二、方法流程:从建包到运行的最小闭环
一个可运行的 ROS 2 控制程序,通常遵循“建包 → 写节点 → 配参数 → 写 Launch → 编译运行”的流程。下面以 Python 节点为例:
# 1. 创建功能包
ros2 pkg create --build-type ament_python offboard_demo \
--dependencies rclpy px4_msgs
# 2. 节点骨架(offboard_demo/offboard_node.py)
import rclpy
from rclpy.node import Node
from px4_msgs.msg import OffboardControlMode, TrajectorySetpoint
class OffboardNode(Node):
def __init__(self):
super().__init__('offboard_node')
self.declare_parameter('setpoint_rate', 20.0)
rate = self.get_parameter('setpoint_rate').value
self.pub_mode = self.create_publisher(
OffboardControlMode, '/fmu/in/offboard_control_mode', 10)
self.pub_sp = self.create_publisher(
TrajectorySetpoint, '/fmu/in/trajectory_setpoint', 10)
self.timer = self.create_timer(1.0 / rate, self.tick)
def tick(self):
mode = OffboardControlMode()
mode.position = True
self.pub_mode.publish(mode)
sp = TrajectorySetpoint()
sp.position = [0.0, 0.0, -5.0]
self.pub_sp.publish(sp)
def main():
rclpy.init()
node = OffboardNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
参数通过 declare_parameter 声明后,可在 Launch 文件中覆盖,也可用命令行动态修改。Launch 文件负责把桥接节点、控制节点、参数配置一次性拉起:
# offboard_demo/launch/offboard.launch.py
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(package='offboard_demo', executable='offboard_node',
name='offboard_node',
parameters=[{'setpoint_rate': 20.0}]),
])
三、常用命令行工具:观察与验证
调试 Offboard 时,命令行工具是“眼睛”。下表列出最常用的命令及其用途:
| 命令 | 作用 | Offboard 场景示例 |
|---|---|---|
ros2 node list |
列出运行中的节点 | 确认 offboard_node 与 px4_uxrce_dds 是否在线 |
ros2 topic list |
列出所有话题 | 检查 /fmu/in 与 /fmu/out 是否出现 |
ros2 topic hz <topic> |
统计发布频率 | 验证设定值是否稳定在 20 Hz |
ros2 topic echo <topic> |
打印话题内容 | 查看 vehicle_odometry 的位姿数值 |
ros2 interface show <type> |
查看消息/服务定义 | 确认 TrajectorySetpoint 字段含义 |
ros2 param list / get / set |
查看与修改参数 | 运行时调整 setpoint_rate |
ros2 service call |
调用服务 | 触发解锁或模式切换 |
ros2 launch <pkg> <file> |
启动 Launch 文件 | 一键拉起控制节点与参数 |
四、案例与误区复盘
案例:Offboard 模式无法进入。常见原因是只发布了 trajectory_setpoint,却没有持续发布 offboard_control_mode 心跳。PX4 要求进入 Offboard 前必须先收到稳定的控制模式消息,且频率足够。用 ros2 topic hz /fmu/in/offboard_control_mode 即可确认心跳是否存在。
误区一:把服务当话题用。服务是同步阻塞的,若在回调中长时间等待,会拖垮执行器。高频控制必须走话题。
误区二:忽略 QoS 配置。PX4 的 uXRCE-DDS 话题通常使用 Best Effort 或特定 Reliability,若订阅端 QoS 不匹配,会“看不到数据”。用 ros2 topic info -v 可查看 QoS 详情。
误区三:参数改了却没生效。参数修改后需确认节点是否重新读取,或是否被 Launch 文件中的默认值覆盖。建议用 ros2 param get 复核实际值。
ros2 node list、ros2 topic list、ros2 topic hz 三步检查,确认桥接节点在线、关键话题存在、频率稳定,再启动控制逻辑,可显著减少“指令无响应”的排查时间。掌握节点、话题、服务、动作、参数与 Launch 的协作方式,并熟练使用命令行工具观察数据流,就具备了后续编写 PX4 Offboard 控制程序的基础设施能力。下一阶段将把这些概念落到具体的 PX4 消息接口与坐标系约定上。