1. ROS2 接口概述
在 ROS2 中,接口(Interface)用于定义节点之间的数据通信格式。拿生活的例子类比,你订阅微信公众号,公众号推送文章,内容的格式就是接口(消息接口)。 ROS2 的接口主要包括以下三类:
| 接口类型 | 作用 | 通信方式 |
|---|---|---|
| msg | 普通数据消息 | Topic 发布/订阅 |
| srv | 请求-响应服务 | Service |
| action | 长时间任务通信 | Action |
ROS2 的接口定义语言(IDL)具有跨语言能力,支持:
- C++
- Python
- Rust(部分支持)
- Java(部分支持)
2. 接口的数据类型
接口的数据类型与C++、Python中的数据类型的对应关系,如下表所示:
| Type name | C++ | Python | DDS type |
|---|---|---|---|
| bool | bool | builtins.bool | boolean |
| byte | uint8_t | builtins.bytes* | octet |
| char | char | builtins.int* | char |
| float32 | float | builtins.float* | float |
| float64 | double | builtins.float* | double |
| int8 | int8_t | builtins.int* | octet |
| uint8 | uint8_t | builtins.int* | octet |
| int16 | int16_t | builtins.int* | short |
| uint16 | uint16_t | builtins.int* | unsigned short |
| int32 | int32_t | builtins.int* | long |
| uint32 | uint32_t | builtins.int* | unsigned long |
| int64 | int64_t | builtins.int* | long long |
| uint64 | uint64_t | builtins.int* | unsigned long long |
| string | std::string | builtins.str | string |
| wstring | std::u16string | builtins.str | wstring |
3. 自定义消息接口
3.1 创建消息接口
创建功能包
cd ~/ros2_ws/src
ros2 pkg create my_robot_interfaces --build-type ament_cmake --license Apache-2.0
创建 msg 目录
消息接口目录是msg,服务接口是srv,动作接口是action,这是ros2官方规定的。
cd my_robot_interfaces
mkdir msg
创建 HardwareStatus.msg
创建一个硬件状态消息接口
文件:
msg/HardwareStatus.msg
注意:消息接口文件名称采用驼峰命名法,服务、动作接口也是一样的。
HardwareStatus.msg内容:
string name
int32 age
float32 height
配置 CMakeLists.txt
修改:
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/HardwareStatus.msg"
)
配置 package.xml
添加:
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
构建功能包
colcon build --packages-select my_robot_interfaces
测试功能包
ros2 interface show my_robot_interfaces/msg/HardwareStatus
输出:
int64 temperature
bool are_motors_ready
string debug_message
说明消息接口功能包构建成功。
3.2 编写发布者节点
创建一个功能包,然后创建发布者节点,这些我就省略了。我的功能包是my_py_pkg,是python类型的功能包,然后创建硬件状态发布者节点。
hardware_status_publisher.py内容如下:
import rclpy
from rclpy.node import Node
from my_robot_interfaces.msg import HardwareStatus
class HardwareStatusPublisherNode(Node):
def __init__(self):
super().__init__("hardware_status_publisher")
self.hw_status_publisher_ = self.create_publisher(HardwareStatus, "hardware_status", 10)
self.timer_ = self.create_timer(1.0, self.publish_hw_status)
self.get_logger().info("Hardware status publisher has been started.")
def publish_hw_status(self):
msg = HardwareStatus()
msg.temperature = 43.2
msg.are_motors_ready = True
msg.debug_message = "Nothing special"
self.hw_status_publisher_.publish(msg)
def main(args=None):
rclpy.init(args=args)
node = HardwareStatusPublisherNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
配置 package.xml
<exec_depend>rclpy</exec_depend>
<exec_depend>my_robot_interfaces</exec_depend>
配置 setup.py
entry_points={
'console_scripts': [
"hardware_status_publisher = my_py_pkg.hardware_status_publisher:main",
],
},
构建并运行
colcon build --packages-select my_py_pkg
source install/setup.bash
ros2 run my_py_pkg hardware_status_publisher
3.3 测试
查看话题列表
source install/setup.bash
ros2 topic list
输出:
/hardware_status
/parameter_events
/rosout
查看消息内容
ros2 topic echo /hardware_status
输出:
temperature: 43.2
are_motors_ready: true
debug_message: Nothing special
说明节点正常运行。
4. 自定义服务接口
创建一个计算矩形面积的服务
4.1 创建服务接口
在my_robot_interfaces功能包中创建服务接口
创建 srv 目录
mkdir srv
创建服务接口文件
ComputeRectangleArea.srv内容
float64 length
float64 width
---
float64 area
使用---来分割请求和响应,上面部分是请求,下面部分是响应
修改配置文件
配置CMakeLists.txt:
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/HardwareStatus.msg"
"srv/ComputeRectangleArea.srv"
)
构建并测试功能包
构建功能包
colcon build --packages-select my_robot_interfaces
测试功能包
输入:
ros2 interface show my_robot_interfaces/srv/ComputeRectangleArea
输出:
float64 length
float64 width
---
float64 area
说明ComputeRectangleArea服务接口构建成功。
4.2 练习
根据已经创建好的ComputeRectangleArea.srv接口服务,编写计算矩形面积服务的服务端和客户端。