ROS 2 创建自定义消息过程

首先需要注意一点,在ROS 2 dashing发行版里面,只有C++的功能包可以自定义消息类型,也就是说,在创建包的时候,只有选择 ament_cmake方式创建的包才可以自定义消息,但是python类型的功能包可以导入由C++类型包创建的自定义消息。

创建过程:

前提条件是你已经有一个工作空间了。

进入工作空间的源码目录

cd src/

创建一个C++类型的功能包

ros2 pkg create --build-type ament_cmake test2 --dependencies std_msgs --node-name test22

我自己使用的时候,就单独维护了一个消息功能包管理ROS 上的自定义消息,这个包里面没有可执行文件,因此不需要指定节点名字

ros2 pkg create --build-type ament_cmake test2 --dependencies std_msgs

在刚刚创建的包的目录下面,新建文件夹:

mkdir src

新建消息文件

touch MyOwnNum.msg

在该包里的CMakeLists.txt里面添加

要将定义的接口转换为特定语言的代码(例如C ++和Python),以便可以在这些语言中使用它们,

find_package(builtin_interfaces REQUIRED)
find_package(geometry_msgs REQUIRED)
find_package(rosidl_default_generators REQUIRED)
find_package(std_msgs REQUIRED)

set(msg_files
  "msg/MyOwnNum.msg"
)
rosidl_generate_interfaces(${PROJECT_NAME} ${msg_files} DEPENDENCIES builtin_interfaces geometry_msgs std_msgs ADD_LINTER_TESTS)

ament_export_dependencies(rosidl_default_generators)
ament_export_dependencies(rosidl_default_runtime)
ament_export_include_directories(include)

在该包里的package.xml文件里面添加

由于接口依赖rosidl_default_generators来生成特定于语言的代码,因此需要声明对其的依赖。

<build_depend>rosidl_default_generators</build_depend>

<exec_depend>rosidl_default_runtime</exec_depend>

<member_of_group>rosidl_interface_packages</member_of_group>

创建完成后,进行编译

这里只编译该包
一种方法是在工程目录里面,在不需要编译的包里面创建一个空文件,文件名字为 AMENT_IGNORE
另一种方法是直接指定要编译的包

colcon build --packages-select test2

编译完成后,查看消息

首先需要

source install setup.bash

然后

ros2 msg list

正常的话可以看到我们自定义的消息已经出现在消息列表里面。

或者

ros2 msg show test2/msg/MyOwnNum

可以查看消息的具体内容。

当需要在其他包中使用该消息的时候

当前功能包如果是ament_cmake包的话

1. 在CMakeLists.txt里面添加

find_package(test REQUIRED) # 根据你的名称修改
ament_target_dependencies(${PROJECT_NAME}_node "std_msgs" "rclcpp" "test2")

2. 在package.xml里面添加

<depend>test2</depend>

3. 在源文件中包含

特别注意,这里的格式,消息文件是驼峰风格的命名方式,也就是通过大写分割单词,但是包含的时候要用下划线风格,全部是小写

#include "test2/msg/my_own_num.hpp" 

4. 使用的时候

publisher = this->create_publisher<test::msg::MyOwnNum>("test", 10);

当前功能包如果是ament_python包的话

1. 在package.xml里添加

<exec_depend>test2</exec_depend>

好像不加也是可以的。

2. 在源文件里添加

from test2.msg import MyOwnNum

3. 使用的时候

msg = MyOwnNum()
msg.signal = 3 // 加入msg里有signal这个消息

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
自定义消息是在ROS2中传递数据的重要方式之一,可以根据自己的需求自定义消息类型。下面是在ROS2下使用Python自定义消息的详细过程: 1. 创建自定义消息文件 在ROS2中,自定义消息类型以.msg文件的形式存在,需要先创建一个自定义消息文件,例如: ``` # Example.msg int32 id string name float32 score ``` 其中,每一行都代表一个字段,第一个字段表示字段类型,第二个字段表示字段名称。 2. 生成消息代码 在创建自定义消息文件后,需要使用ROS2自带的工具来生成消息代码。打开终端,进入工作空间,执行以下命令: ``` ros2 msg create <package_name> <msg_name> ``` 其中,`<package_name>`表示自定义消息所在的包名,`<msg_name>`表示自定义消息的名称。例如: ``` ros2 msg create my_package Example ``` 执行完该命令后,ROS2会自动生成Example.msg文件对应的Python代码,存放在`my_package/msg`目录下。 3. 编辑自动生成的代码 生成的代码包含一个类,类名与自定义消息文件名相同。在类的定义中,ROS2为每个字段生成了getter和setter方法,可以通过调用这些方法来设置和获取字段的值。例如: ``` class Example: def __init__(self): self.id = 0 self.name = '' self.score = 0.0 def __str__(self): return 'id:{} name:{} score:{}'.format(self.id, self.name, self.score) def serialize(self, buff): # 将消息序列化为二进制数据 pass def deserialize(self, buff): # 从二进制数据中反序列化消息 pass def get_size(self): # 返回消息序列化后的大小 pass def get_fields(self): # 返回消息的字段 return {'id': 'int32', 'name': 'string', 'score': 'float32'} def set_fields(self, values): # 设置消息的字段值 if 'id' in values: self.id = values['id'] if 'name' in values: self.name = values['name'] if 'score' in values: self.score = values['score'] def to_dict(self): # 将消息转换为字典形式 return {'id': self.id, 'name': self.name, 'score': self.score} def from_dict(self, values): # 从字典形式中设置字段值 if 'id' in values: self.id = values['id'] if 'name' in values: self.name = values['name'] if 'score' in values: self.score = values['score'] ``` 可以根据需要对自动生成的代码进行修改。 4. 使用自定义消息 在代码中使用自定义消息与使用ROS2提供的标准消息类似。需要导入自定义消息所在的包,然后创建自定义消息对象并设置字段值,最后将消息发布到ROS2网络中。例如: ``` from my_package.msg import Example import rclpy def main(): rclpy.init() node = rclpy.create_node('my_node') publisher = node.create_publisher(Example, 'my_topic') msg = Example() msg.id = 1 msg.name = 'Tom' msg.score = 90.5 publisher.publish(msg) rclpy.spin(node) node.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() ``` 可以看到,使用自定义消息与使用ROS2提供的标准消息基本相同,只需要将自定义消息类作为参数传递给Node的create_publisher()方法即可。 总结 自定义消息ROS2中传递数据的重要方式之一,可以根据自己的需求灵活定义消息类型。使用Python自定义消息过程与使用ROS2提供的标准消息类似,只需要创建自定义消息文件并生成Python代码,然后在代码中使用自定义消息即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值