2. ROS2基础

在无人机伴随计算机开发中,ROS2 并不是一个“库”,而是一套分布式通信与运行管理框架。伴随计算机上通常同时运行感知、定位、规划、控制、通信等多个进程,它们需要以松耦合方式交换数据、响应请求并协调任务。理解节点、话题、服务、动作、参数、Launch 文件与工作空间,是后续编写无人机机载软件的基础。

一、核心概念:节点是执行单元,通信原语是连接方式

ROS2 程序的基本执行单元是节点(Node)。一个节点通常只负责一项明确职责,例如读取激光雷达、运行视觉里程计、发布姿态指令或转发 MAVLink 消息。节点可以运行在同一台计算机,也可以分布在无人机机载计算机与地面站之间,通过 DDS 中间件自动发现并通信。

节点之间主要有四种交互方式:

  • 话题(Topic):发布/订阅模型,适合连续、单向、高频数据流,如 /camera/image_raw、/odom、/cmd_vel。
  • 服务(Service):请求/响应模型,适合短时、需确认结果的操作,如查询电池状态、切换飞行模式。
  • 动作(Action):带反馈的长时间任务,适合“飞到目标点”“执行航点巡航”等可取消、可监控进度的任务。
  • 参数(Parameter):节点运行时配置项,如控制增益、相机曝光、目标高度,可在启动时设置,也可动态修改。
记忆要点:话题是“广播流”,服务是“问答”,动作是“带进度的长任务”,参数是“节点配置表”。

二、通信模型对比与选择

选择通信方式时,关键看数据是否连续、是否需要应答、任务是否长时间运行。下表给出无人机伴随计算中的典型判断依据。

通信方式 模型 典型场景 是否可取消 是否有反馈
话题 Topic 发布/订阅 图像、IMU、里程计、控制指令 否 无
服务 Service 请求/响应 查询状态、校准传感器、切换模式 否 仅最终结果
动作 Action 目标/反馈/结果 航点飞行、返航、跟踪目标 是 持续反馈
参数 Parameter 键值配置 PID 增益、高度限制、相机参数 不适用 可查询

三、工作空间与功能包创建方法

ROS2 使用工作空间(Workspace)组织代码,典型结构为 src/ 存放源码,build/、install/、log/ 由构建工具生成。创建流程如下:

mkdir -p ~/drone_ws/src
cd ~/drone_ws/src
ros2 pkg create --build-type ament_cmake drone_bringup \
  --dependencies rclcpp std_msgs sensor_msgs
cd ~/drone_ws
colcon build --symlink-install
source install/setup.bash

其中 --dependencies 会自动写入 package.xml 与 CMakeLists.txt,避免手动遗漏依赖。Python 包则使用 --build-type ament_python。每次打开新终端后,必须 source install/setup.bash,否则 ros2 run 找不到自定义包。

四、Launch 文件:一次启动多个节点

无人机起飞前往往需要同时启动相机、IMU、里程计、控制器和通信桥。逐个 ros2 run 效率低且容易漏项,因此使用 Launch 文件统一编排。ROS2 推荐 Python Launch 文件,便于使用条件判断和参数替换。

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='drone_bringup',
            executable='camera_node',
            name='front_camera',
            parameters=[{'fps': 30, 'width': 1280}]
        ),
        Node(
            package='drone_bringup',
            executable='odom_node',
            name='visual_odom',
            remappings=[('image_in', '/front_camera/image_raw')]
        ),
    ])

运行方式为 ros2 launch drone_bringup bringup.launch.py。Launch 文件还能通过 IncludeLaunchDescription 复用其他包,通过 DeclareLaunchArgument 暴露可配置参数,是机载系统集成的核心工具。

五、典型场景:伴随计算机启动链路

以“无人机视觉伴随飞行”为例,启动后系统内部的数据关系如下:相机节点发布图像话题,视觉里程计订阅图像并发布 /odom,规划节点订阅里程计并发布 /cmd_vel,飞控桥接节点订阅 /cmd_vel 并转换为 MAVLink 指令;同时,状态监控节点通过服务查询电池,通过动作下发“起飞到 5 米”任务。参数服务器保存控制增益,Launch 文件负责把这一切按顺序拉起。

ROS2 无人机伴随计算:节点、通信与 Launch 启动关系 感知与状态节点 camera_node imu_node 估计与规划节点 visual_odom planner_node 控制与桥接节点 mavlink_bridge flight_control /image_raw /cmd_vel Launch 文件:bringup.launch.py 统一启动 camera_node、visual_odom、planner_node、mavlink_bridge 设置参数 fps=30、width=1280,并完成话题重映射 服务 Service /query_battery 查询电池状态 /set_mode 切换飞行模式 动作 Action /takeoff 起飞到指定高度 /goto_waypoint 航点飞行(带反馈)

六、常见误区与复盘

误区一:把高频控制指令做成服务。服务是同步阻塞的,不适合 50 Hz 以上的连续控制,应使用话题。
误区二:忘记 source 工作空间。新终端中直接 ros2 run 会提示找不到包,需先执行 source install/setup.bash。
误区三:Launch 文件中硬编码所有参数。应使用 DeclareLaunchArgument 暴露关键参数,便于仿真与实机切换。
误区四:节点职责过重。一个节点同时做图像处理、规划和通信,会导致调试困难,应拆分为单一职责节点。
建议在伴随计算机上先建立 drone_ws 工作空间,按“感知—估计—规划—控制—桥接”拆分功能包,再用 Launch 文件统一启动。这样既符合 ROS2 分布式思想,也便于后续接入 PX4、MAVROS 或自定义飞控协议。