首先需要注意一点,在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这个消息