ROS2之消息接口

 ROS2 的三大消息接口

1. 消息(Message, msg)

  • 定义文件后缀.msg

  • 作用:用于 话题 (Topic) 通信,节点之间以“流”的方式交换数据。

  • 特点

    • 一对多(一个话题可以有多个订阅者/发布者)

    • 单向通信(发布 → 订阅)

    • 异步(发送方不用等待接收方响应)

  • 使用场景

    • 传感器数据(如 sensor_msgs/Image 图像)

    • 控制命令(如 geometry_msgs/Twist 速度指令)

  • 示例(定义一个 Person.msg):

     
    string name int32 age float32 height

2. 服务(Service, srv)

  • 定义文件后缀.srv

  • 作用:提供 请求-响应 (Request/Response) 的同步通信方式。

  • 特点

    • 一对一(一个客户端请求,一个服务端响应)

    • 双向通信(请求 + 响应)

    • 同步(客户端必须等待服务端返回结果)

  • 使用场景

    • 查询类操作(获取机器人状态)

    • 控制类操作(重置仿真、生成新对象)

  • 示例(定义一个 AddTwoInts.srv):

     
    int64 a int64 b --- int64 sum

3. 动作(Action, action)

  • 定义文件后缀.action

  • 作用:适合 长时间执行的任务,支持过程中的反馈和最终结果。

  • 特点

    • 客户端-服务端 模型,但比 srv 更复杂

    • 三部分通信

      • Goal(目标):客户端发送任务请求

      • Feedback(反馈):服务端周期性返回任务进度

      • Result(结果):任务完成时返回最终结果

    • 支持取消任务

  • 使用场景

    • 移动机器人导航(目标点任务 + 进度反馈 + 最终到达结果)

    • 机械臂执行长时间的运动

  • 示例(定义一个 Navigate.action):

     
    # Goal geometry_msgs/PoseStamped target_pose --- # Result bool success --- # Feedback float32 progress_percent
     
接口类型 文件后缀 通信方式 特点 使用场景
msg .msg 话题 (Topic) 单向,异步,一对多 传感器数据,控制指令
srv .srv 服务 (Service) 请求-响应,同步,一对一 查询、重置、短时任务
action .action 动作 (Action) 目标 + 反馈 + 结果,支持取消

长时任务(导

航、运动控制)

 ROS2的消息接口的数据类型

ROS2 的消息接口(msg/srv/action) 中,数据类型主要分为三类:

  1. 基本类型

    • 就是编程里常见的标量,比如整数、浮点数、布尔值、字符串等。

    • 例如:int32, float64, bool, string

  2. 复合类型(嵌套类型)

    • 可以在一个消息里使用另一个消息作为字段。

    • 比如 geometry_msgs/Twist 就包含 Vector3 类型的成员。

  3. 数组与序列类型

    • 支持固定长度数组和动态长度序列,用于存放多个相同类型的数据。

    • 例如:int32[10](固定长度 10)、string[](动态长度字符串序列)。

依赖

如果你要写 自定义接口包,最基本的依赖是:

  • 必须有

    • rosidl_default_generators (生成代码用)

    • rosidl_default_runtime (运行时用)

  • 如果用到其他消息类型(比如 std_msgs/Header

    • std_msgs

    • geometry_msgs

    • sensor_msgs
      等等都要写到 package.xmlCMakeLists.txt 里。

package.xml

<package format="3">
  <name>my_interfaces</name>
  <version>0.0.0</version>
  <description>My custom interfaces</description>
  <maintainer email="xxx@todo.todo">Your Name</maintainer>
  <license>Apache License 2.0</license>

  <!-- 构建依赖:生成接口代码 -->
  <build_depend>rosidl_default_generators</build_depend>

  <!-- 如果用到 std_msgs / geometry_msgs,需要写 -->
  <build_depend>std_msgs</build_depend>
  <build_depend>geometry_msgs</build_depend>

  <!-- 执行依赖:运行时需要 -->
  <exec_depend>rosidl_default_runtime</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>geometry_msgs</exec_depend>

  <!-- 测试依赖 -->
  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>
</package>

CMakeLists.txt

cmake_minimum_required(VERSION 3.8)
project(my_interfaces)

find_package(ament_cmake REQUIRED)
find_package(rosidl_default_generators REQUIRED)
find_package(std_msgs REQUIRED)
find_package(geometry_msgs REQUIRED)

# 生成接口(msg/srv/action)
rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/Person.msg"
  "srv/AddTwoInts.srv"
  "action/Navigate.action"
  DEPENDENCIES std_msgs geometry_msgs  # 如果用到了外部消息
)

ament_export_dependencies(rosidl_default_runtime)
ament_package()

 

posted @ 2025-09-25 15:24  突破铁皮  阅读(37)  评论(0)    收藏  举报