ROS2 接口

0 阅读2分钟

1. ROS2 接口概述

在 ROS2 中,接口(Interface)用于定义节点之间的数据通信格式。拿生活的例子类比,你订阅微信公众号,公众号推送文章,内容的格式就是接口(消息接口)。 ROS2 的接口主要包括以下三类:

接口类型作用通信方式
msg普通数据消息Topic 发布/订阅
srv请求-响应服务Service
action长时间任务通信Action

ROS2 的接口定义语言(IDL)具有跨语言能力,支持:

  • C++
  • Python
  • Rust(部分支持)
  • Java(部分支持)

2. 接口的数据类型

接口的数据类型与C++、Python中的数据类型的对应关系,如下表所示:

Type nameC++PythonDDS type
boolboolbuiltins.boolboolean
byteuint8_tbuiltins.bytes*octet
charcharbuiltins.int*char
float32floatbuiltins.float*float
float64doublebuiltins.float*double
int8int8_tbuiltins.int*octet
uint8uint8_tbuiltins.int*octet
int16int16_tbuiltins.int*short
uint16uint16_tbuiltins.int*unsigned short
int32int32_tbuiltins.int*long
uint32uint32_tbuiltins.int*unsigned long
int64int64_tbuiltins.int*long long
uint64uint64_tbuiltins.int*unsigned long long
stringstd::stringbuiltins.strstring
wstringstd::u16stringbuiltins.strwstring

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接口服务,编写计算矩形面积服务的服务端和客户端。