动手学ROS2-2节点通信-接口之RCLCPP实现

说明:本文基于ubuntu22.04和ros2 humble版本

一、接口基础

1.接口介绍

接口(interface)其实是一种规范。之前使用过的两种接口,这两种数据类型分别代表字符串和32位二进制的整型数据,是ROS2提前定义的一种规范。

std_msgs/msg/String

std_msgs/msg/UInt32

使用接口的意义:

不同的厂家生产出不同的类型的激光雷达,每种雷达驱动方式、扫描速率等等都不相同。

当机器人进行导航时,需要激光雷达的扫描数据,假如没有统一接口,每次更换一个种类的雷达,都需要重新做程序适配。

于是ROS2中定义了一个统一的接口叫做sensor_msgs/msg/LaserScan,现在几乎每个雷达的厂家都会编写程序将自己雷达的数据变成sensor_msgs/msg/LaserScan格式,提供给用户使用。

ROS2自带的接口:

ROS2还定义了很多做机器人常用的接口。传感器类的消息包是sensor_msgs

#打开终端输入下一行命令,可以查看sensor_msgs接口包下的所有接口

ros2 interface package sensor_msgs

sensor_msgs/msg/JointState #机器人关节数据

sensor_msgs/msg/Temperature #温度数据

sensor_msgs/msg/Imu #加速度传感器

sensor_msgs/msg/Image #图像

sensor_msgs/msg/LaserScan #雷达数据

......

2.接口文件

2.1可以自定义的三种通信接口

ROS2提供的四种通信方式中除了参数之外,话题、服务和动作(Action)都支持自定义接口,每一种通信方式所适用的场景各不相同,所定义的接口也被分为话题接口、服务接口、动作接口三种。

2.2三种接口定义的格式

话题接口格式:xxx.msg

int64 num

服务接口格式:xxx.srv

int64 a

int64 b

---

int64 sum

动作接口格式:xxx.action

int32 order

---

int32[] sequence

---

int32[] partial_sequence

2.3接口数据类型

根据引用方式的不同,可以分为基础类型和包装类型两类。

基础类型有(同时后面加上[ ]可形成数组)

bool
byte
char
float32,float64
int8,uint8
int16,uint16
int32,uint32
int64,uint64
string

包装类型,即在已有的接口类型上进行包装,比如

uint32 id
string image_name
sensor_msgs/Image

在接口文件中定义通信过程中所使用的数据类型和数据名称。

通过基本类型的组合,可以构成一个新的数据类型,而新的数据类型又可以和基本类型或者另外一个数据类型互相组成另一个数据类型。

图像数据类型sensor_msgs/Image

ros2 interface show sensor_msgs/msg/Image

2.4接口生成代码

只是简单的在接口文件中写了一下变量类型和名称,如何在程序里面怎么调用?是通过导入头文件使用这个消息模块。接口转换的过程:将msg、srv、action文件转换为Python和C++的头文件

3.自定义接口实践 

3.1场景

一个机器人开发中的常见控制场景,需要设计满足要求的服务接口和话题接口。

设计两个节点

  • 机器人本体节点,对外提供移动指定距离服务,移动完成后返回当前位置,同时对外发布机器人的位置和状态。
  • 机器人控制节点,通过服务控制机器人移动指定距离,并实时获取机器人的当前位置和状态。

假设机器人在坐标轴上,只能前后移动。

3.2定义接口

服务接口MoveRobot.srv

# 前进后退的距离

float32 distance

---

# 当前的位置

float32 pose

话题接口,采用基础类型 RobotStatus.msg

uint32 STATUS_MOVEING = 1
uint32 STATUS_STOP = 1
uint32  status
float32 pose

话题接口,混合包装类型 RobotPose.msg

uint32 STATUS_MOVEING = 1
uint32 STATUS_STOP = 2
uint32  status
geometry_msgs/Pose pose

3.3创建接口功能包编写接口

cd chapt3_ws/src

ros2 pkg create example_ros2_interfaces --build-type ament_cmake --dependencies rosidl_default_generators geometry_msgs

注意功能包类型必须为:ament_cmake

依赖rosidl_default_generators必须添加,geometry_msgs视内容情况添加(我们这里有geometry_msgs/Pose pose所以要添加)。

接着创建文件夹和文件将3.2中文件写入,注意话题接口放到msg文件夹下,以.msg结尾。服务接口放到srv文件夹下,以.srv结尾。

 修改CMakeLists.txt,添加依赖

find_package(rosidl_default_generators REQUIRED)
find_package(geometry_msgs REQUIRED)
# 添加下面的内容
rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/RobotPose.msg"
  "msg/RobotStatus.msg"
  "srv/MoveRobot.srv"
  DEPENDENCIES geometry_msgs
)

修改package.xml

  <buildtool_depend>ament_cmake</buildtool_depend>

  <depend>rosidl_default_generators</depend>
  <depend>geometry_msgs</depend>
  
  <member_of_group>rosidl_interface_packages</member_of_group> #添加这一行

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

在工作空间下编译

colcon build --packages-select example_ros2_interfaces

编译完成后在chapt3_ws/install/example_ros2_interfaces/include下应该可以看到C++的头文件。

chapt3_ws/install/example_ros2_interfaces/local/lib/python3.10/dist-packages下应该可以看到Python版本的头文件。

编译失败

 4.接口常用CLI命令

查看接口列表

ros2 interface list

查看某接口的详细内容

ros2 interface show std_msgs/msg/String

二、自定义接口RCLCPP实战

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ROS2中,C++节点通信主要通过ROS2提供的rclcpp实现rclcpp库是一个ROS2的C++客户端库,它提供了创建ROS2节点、发布和订阅话题、服务调用等功能。 下面是一个简单的例子,演示如何使用rclcpp库在C++节点之间进行通信: 1. 首先,我们需要包含必要的头文件: ```cpp #include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" ``` 2. 创建一个发布者: ```cpp auto publisher = node->create_publisher<std_msgs::msg::String>("my_topic", 10); ``` 其中,`node`是一个`rclcpp::Node`对象,`std_msgs::msg::String`是消息类型,`my_topic`是话题名称,`10`是话题队列长度。 3. 创建一个消息: ```cpp auto message = std_msgs::msg::String(); message.data = "Hello, world!"; ``` 4. 发布消息: ```cpp publisher->publish(message); ``` 5. 创建一个订阅者: ```cpp auto subscription = node->create_subscription<std_msgs::msg::String>("my_topic", 10, [](const std_msgs::msg::String::SharedPtr msg) { RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "I heard: '%s'", msg->data.c_str()); }); ``` 其中,`std_msgs::msg::String`是消息类型,`my_topic`是话题名称,`10`是话题队列长度,`[](const std_msgs::msg::String::SharedPtr msg) {...}`是消息回调函数,用于处理接收到的消息。 6. 运行节点: ```cpp rclcpp::spin(node); ``` 以上是一个简单的例子,演示了如何在C++节点之间使用ROS2进行通信。在实际应用中,我们可以根据需要创建多个发布者和订阅者,以实现节点之间的复杂通信
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值