ROS通信机制

ROS中的通信机制

通信机制的分类

在ROS中比较常见的通信机制分为话题通信服务通信,当然还有其它更多的通信方式,在这里不过多描述

话题通信

角色

  1. 发布者(Publisher)
  2. 订阅者(Subscriber)
  3. 管理者(ROS Master)

流程

  1. 发布者和订阅者会向管理者提交自身信息,自身信息包括话题名称节点信息地址信息等,管理者会将这些信息存入
  2. 管理者会将接收到的信息进行比对,然后把匹配到一起的发布者的地址信息发送给订阅者,订阅者可以通过此信息找到发布者进行订阅
  3. 此时发布者会发送一个TCP server给订阅者,订阅者通过此信息和发布者建立单独的连接,并且发布者将消息发布给订阅者。

在这里插入图片描述
PS:在此图中Talker为Publisher, Listener为Subscriber
ROSmaster在完成建立之后会自己关闭

简单的案例

这里我们以仿真环境里的小车为例

gazebo

然后用rostopic list指令查看当前有什么话题
在这里插入图片描述

我们可以看到当前存在一个smart/cmd_vel的话题,此话题就是控制小车速度的话题,我们用rostopic pub对此话题进行发布
在这里插入图片描述可以看到小车以我们发布的速度行驶

这就是一个简单的话题通信模型

真实的案例

现在我们以机器人为例,机器人实现自动导航分为三步

  1. 雷达接收环境信息发布给进行计算的部件
  2. 部件对雷达发过来的信息进行计算并且发布给底盘
  3. 底盘通过部件发过来已经计算好的信息进行移动

在这个过程中就存在许多话题通信模型,接下来我们来讲讲服务通信

服务通信

角色

  1. 客户端(client)
  2. 服务端(server)
  3. 管理者(ROS Master)

流程

  1. 客户端和服务端会向管理者提交自身信息,自身信息包括服务名称节点信息地址信息等,管理者会将这些信息存入
  2. 管理者会将接收到的信息进行比对,然后把匹配到一起的服务端的地址信息发送给客户端,客户端可以通过此信息找到服务端进行订阅
  3. 此时客户端会将自己的请求/request发给服务端,服务端进行工作并反馈/response给客户端

在这里插入图片描述PS:此图中Talker为Service,Listener为Client
ROSmaster在完成建立之后会自己关闭

简单的案例

以经典时尚小海龟为例,打开小海龟

rosrun turtlesim turtlesim_node

这次我们用rosserver list查看一下有什么服务端
在这里插入图片描述我们发现这个列表中存在一个/spawn服务,这个服务端可以生成一个新的小海龟,现在我们自己成为一个客户端去请求一下这个服务端
hang 在这里插入图片描述我们用rosserver call去请求/spawn 并且设置参数
发现屏幕上多了一只小海龟
说明我们成功请求了服务端,服务端给我们反馈了一只小海龟

两种通信机制的区别

接下来我们来讨论一下两种通信机制有什么区别

异步与同步

首先我们先来讲一讲什么是异步
异步简单来说就是发布方和订阅方做着各自的事情,在发布方发布完消息之后就会继续去做自己的事情,至于发布的消息被怎么处理不会去管,而订阅方只管去订阅,不会在乎是谁发来的信息
在此基础上我们可以得出第一条结论
话题通信为异步,服务通信为同步

反馈

通过流程图我们可以很直观的得出第二条结论
话题通信不存在反馈,而服务通信存在反馈

实时性

由于话题通信为异步通信方式,所以它的实时性并不强
由于服务通信为同步通信方式,存在反馈机制,客户端会一直等待服务端进行反馈,所以它的实时性强
在此基础上我们可以得出第三条结论
话题通信的实时性弱,而服务通信的实时性强

节点关系

通过异步与同步得出的结论我们可以顺势推导出第四条结论
发布者可以发布给多个订阅者,而订阅者也可以订阅多个发布者
服务端可以接收多个客户端的请求,但一个客户端只能给一个服务端发送请求

小表格

条目话题服务
同步性异步同步
反馈机制
实时性
节点关系多对多一对多

使用场景

综合以上多个结论,我们可以得出最终结论
话题通信的逻辑性不强,但是对数据的发送和接收效率高
服务通信的逻辑性很强,但是对数据的发送和接收效率低

自定义消息数据类型

上面的过程中我们用的是ros中的话题和服务类型
接下来我们需要定义自己的数据类型

自定义话题消息

要想自定义消息类型,我们得先看看Twist有哪些信息
在这里插入图片描述我们可以看到这个消息里面包含了线速度和角速度
现在我们就可以自己创建一个msg文件,在里面写我们想发布的消息类型

uint16 num

这里相当于创建了一个整数类型的消息
然后我们需要在CMakeList.txt和package.xml文件中添加依赖
首先在package.xml文件中的最后加入

<build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>

接下来是CMakeList.txt

find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
add_message_files(
   FILES
   number.msg
 )
generate_messages(
  DEPENDENCIES
  std_msgs
)

这三步是待会在catkin_make的时候编译我们自定义的数据类型并且依赖于std_msgs
接下来我们catkin_make编译一下
然后用rosmsg show查看我们自定义的数据类型有没有成功编译
在这里插入图片描述

接下来我们用c++编写文件发布我们自定义的消息并且用echo订阅

#include <ros/ros.h>
#include <learning_topic/number.h>

int main(int argc, char *argv[]){
   ros::init(argc,argv,"num");
   
   ros::NodeHandle n;

   ros::Publisher pub = n.advertise<learning_topic::number>("num_pub", 10);

   ros::Rate rate(1);

   learning_topic::number nb;

   nb.num = 10;

   while(ros::ok()){
   	pub.publish(nb);

   	rate.sleep();

   	ROS_INFO("%d", nb.num);		
   }

   return 0;
}

在这里插入图片描述这样我们就成功发布并订阅了自定义的数据类型

自定义服务消息

同样的 我们用rossrv show看看服务消息里面的信息
在这里插入图片描述我们可以看到相比较与话题数据类型,服务数据类型会多增加一个反馈值,并且用“—”隔开
接下来我们就可以自己定义一个服务类型
这次需要在CMakeList.txt里面增加服务类型的依赖

add_service_files(
   FILES
   num_add.srv
 )

接下来用rossrv show查看我们是否成功编译
在这里插入图片描述可以看到我们自定义的类型已经成功编译,接下来我们编写一个服务端去接收请求,并用rosserver call发布请求

#include <ros/ros.h>
#include <learning_topic/num_add.h>

bool callback(learning_topic::num_add::Request &req, learning_topic::num_add::Response &res){
   int num1 = req.num1;
   int num2 = req.num2;
   int result = res.result;
   result = num1 + num2;
   ROS_INFO("%d + %d = %d",num1,num2,result);
   return true;
}

int main(int argc, char *argv[]){
   ros::init(argc,argv,"n_a");

   ros::NodeHandle n;
   
   ros::ServiceServer server = n.advertiseService("add_num",callback);

   ROS_INFO("Wait for request");

   ros::spin();

   return 0;
}

在这里插入图片描述可以看到我们编写的服务端一直在等待客户端去发送请求,我们用rosserver call去发送请求,客户端成功收到请求
这样我们就成功完成了自定义服务数据类型的发布

总结

到这里ROS中的通信机制就讲完了,此讲的内容包括通信模型实用案例两种通信机制的区别以及自定义数据类型的使用

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值