ROS2-8章:自定义消息类型

目录

[目录... 1](#目录... 1)

[一、自定义消息类型(参数)... 2](#一、自定义消息类型(参数)... 2)

[二、创建过程... 2](#二、创建过程... 2)

[1. 在src文件夹创建一个功能包json_interface. 2](#1. 在src文件夹创建一个功能包json_interface. 2)

[2. 创建自定义消息类型... 3](#2. 创建自定义消息类型... 3)

[3. 如何使用 自定义的消息类型... 8](#3. 如何使用 自定义的消息类型... 8)

[3 机器人的坐标系管理... 8](#3 机器人的坐标系管理... 8)

一、自定义消息类型(参数)

在 ROS 2 中,参数(Parameter) 是专门用于**外部配置节点(Node)**的一种机制。你可以把它理解为节点的"全局设置"或"运行时开关"。

ROS 2 自定义消息类型(Custom Messages)核心课件

1. 课程导入:为什么需要自定义消息?

1.1 标准消息的局限性

ROS 2 提供了丰富的标准消息接口(如 std_msgs, sensor_msgs, geometry_msgs),但在实际机器人开发中,我们常遇到以下场景:

  • 语义不匹配:没有现成的消息能精确描述你的传感器数据或控制指令。
  • 组合需求:需要将多个标准消息打包成一个逻辑整体(例如:将"位置+速度+时间戳+置信度"封装为一个"目标状态")。
  • 通信效率:避免在话题中传输冗余字段,减少带宽占用和序列化开销。

1.2 核心设计理念

💡 ROS 2 的接口定义语言(IDL)本质是一种"契约"

自定义消息不是简单的数据结构,它是节点间通信的强类型协议。它确保了分布式系统中不同语言(C++/Python)、不同平台编写的节点能够安全、无歧义地交换数据。


2. 核心概念解析

2.1 什么是自定义消息类型?

自定义消息类型是开发者通过 .msg 文件定义的结构化数据模板。经过编译后,它会生成对应语言的代码(C++ 头文件 / Python 类),供节点在发布/订阅时使用。

2.2 三种接口类型的区别

接口类型 文件后缀 用途 典型场景
Message .msg 单向、异步数据传输 传感器读数、状态广播
Service .srv 双向、同步请求/响应 参数配置、触发校准
Action .action 带反馈的长时间任务 导航、机械臂抓取

⚠️ 本课重点:.msg 是基础,.srv 和 .action 内部都依赖 .msg 作为其数据载体。

2.3 消息定义的三要素

二、创建过程

1. 在src文件夹创建一个功能包json_interface

因为只能用C++语言来进行 IDL定义消息类型进行编译,说以这里使用ament_cmake ;自定义消息功能包的名称叫 json_interface 。

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@LHAYR:~/ros2_ws/src# ros2 pkg create --build-type ament_cmake --dependencies rosidl_default_generators --license MIT json_interface going to create a new package package name: json_interface destination directory: /root/ros2_ws/src package format: 3 version: 0.0.0 description: TODO: Package description maintainer: 'root \' licenses: 'MIT' build type: ament_cmake dependencies: 'rosidl_default_generators' creating folder ./json_interface creating ./json_interface/package.xml creating source and include folder creating folder ./json_interface/src creating folder ./json_interface/include/json_interface creating ./json_interface/CMakeLists.txt root@LHAYR:~/ros2_ws/src# |

打开 编程工具, code .

2. 创建自定义消息类型

在json_interface文件夹里面,创建三个子文件夹,msg、srv、action,并且在每个目录下,使用IDL定义消息的详细结构:(分别对应,话题、服务、动作的);直接在 vs code中创建文件夹;

2.1 定义话题(Topic)消息类型,在msg文件夹中创建一个Jsonmsg.msg的文件,修改其内容为:

|-------------------------------------------|
| # a shtring represent JSON string jsonstr |

2.2 定义 服务(service)消息类型,在srv文件夹中创建一个Jsonmsg.srv的文件,修改其内容为:

|--------------------------------------------------------------------------------------------------------------------------------|
| #client request is a string represent JSON string reqjsonstr --- #server response is a string represent JSON string rsqjsonstr |

2.3 定义 动作(Action)消息类型,在action文件夹中创建一个Jsonmsg.action的文件,修改其内容为:

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| #action client request is a string represent JSON string reqjsonstr --- #server response is a string represent JSON string rspjsonstr --- #action server's feed back is a string represent JSON string fbjsonstr |

创建完成,目录结构如下图

2.3 修改CMakelists.txt 在代码末尾添加。

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| rosidl_generate_interfaces( ${PROJECT_NAME} # 把接口生成到当前功能包名下 "msg/Jsonmsg.msg" # 自定义话题消息 "srv/Jsonsrv.srv" # 自定义服务 "action/Jsonaction.action" # 自定义动作 ) ament_package() |

2.4 修改package.xml 在代码倒数第二行添加。

|------------------------------------------------------------------|
| <member_of_group>rosidl_interface_packages</member_of_group> |

2.5 编译整个功能包

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@LHAYR:~/ros2_ws# colcon build --packages-select json_interface --symlink-install Starting >>> json_interface Finished <<< json_interface 0.42s Summary: 1 package finished 0.54s root@LHAYR:~/ros2_ws# |

2.6 安装,加载环境变量

|-------------------------------------------------------------------------|
| root@LHAYR:~/ros2_ws# source install/setup.bash root@LHAYR:~/ros2_ws# |

2.7 编译整个功能包

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@LHAYR:~/ros2_ws# colcon build --packages-select json_interface --symlink-install Starting >>> json_interface Finished <<< json_interface 0.42s Summary: 1 package finished 0.54s root@LHAYR:~/ros2_ws# |

2.8 验证接口

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| root@LHAYR:~/ros2_ws# source install/setup.bash root@LHAYR:~/ros2_ws# ros2 interface package json_interface json_interface/action/Jsonaction json_interface/msg/Jsonmsg json_interface/srv/Jsonsrv root@LHAYR:~/ros2_ws# |

3. 如何使用 自定义的消息类型

和原先的库里一样,先在代码前面倒入功能包

|-------------------------------------------------------------------------------------------------------------------|
| from json_interface import msg, srv , action strmsg=msg.Jsonmsg() srvmsg=srv.Jsonmsg() actionmsg=action.Jsonmsg() |