【ROS理论与实践-赵虚左老师】Chap2 ROS通信机制

第二章 ROS通信机制

通信是ROS中的核心 Core

机器人是一种高度复杂的系统性实现,在机器人上可能集成各种传感器(雷达、摄像头、GPS…)以及运动控制实现,为了解耦合,在ROS中每一个功能点都是一个单独的进程,每一个进程都是独立运行的。更确切的讲,ROS是进程(也称为Nodes)的分布式框架。 因为这些进程甚至还可分布于不同主机,不同主机协同工作,从而分散计算压力。不过随之也有一个问题:
不同的进程是如何通信的?也即不同进程间如何实现数据交换的?在此我们就需要介绍一下ROS中的通信机制了。

ROS 中的基本通信机制主要有如下三种实现策略:

话题通信 topic(发布订阅模式) 抖音知乎关注

服务通信service (请求响应模式) 访问互联网

参数服务器(参数共享模式) 公司小吃中心

2.1 话题通信(topic)

2.1.1 理论模型、概述和C++实现

话题通信是ROS中使用频率最高的一种通信模式,话题通信是基于发布订阅模式的,也即:一个节点发布消息,另一个节点订阅该消息。话题通信的应用场景也极其广泛,比如下面一个常见场景:

机器人在执行导航功能,使用的传感器是激光雷达,机器人会采集激光雷达感知到的信息并计算,然后生成运动控制信息驱动机器人底盘运动。

在上述场景中,就不止一次使用到了话题通信。

--------以激光雷达信息的采集处理为例,在 ROS 中有一个节点需要时时的发布当前雷达采集到的数据,导航模块中也有节点会订阅并解析雷达数据。
--------再以运动消息的发布为例,导航模块会根据传感器采集的数据时时的计算出运动控制信息并发布给底盘,底盘也可以有一个节点订阅运动信息并最终转换成控制电机的脉冲信号。
以此类推,像雷达、摄像头、GPS… 等等一些传感器数据的采集,也都是使用了话题通信,换言之,话题通信适用于不断更新的数据传输相关的应用场景。

核心要素三个:
发布方 订阅方 话题

话题 topic
发布方 订阅方 话题
作用:
用于不断更新的、少逻辑处理的数据传输场景。

流程
联想媒婆撮合

bar为话题名称
TIPS:
1.使用的协议有RPC和TCP
RPC协议是远程调用
2.步骤0和1没有顺序关系
3.talker和listener都可以存在多个
4.talker和listener建立连接后,master(管理匹配话题)就可以关闭了(也就是roscore可以关闭了)
5.上述实现流程已经封转了,以后直接调用即可。

master可以根据话题建立发布者和订阅者之间的连接

话题通信应用时需要注意的点
1.大部分实现已经被封装了
2.话题设置
3.关注发布者实现
4.关注订阅者实现
5.关注消息载体(两者通信使用的数据)

计算机或者程序都是对现实世界的仿真。。。学习的时候要善于将理论模型映射到现实模型,任何理论都来源于生活

补充3:

订阅时,第一条数据丢失

原因: 发送第一条数据时, publisher 还未在 roscore 注册完毕

解决: 注册后,加入休眠 ros::Duration(3.0).sleep(); 延迟第一条数据的发送

回调函数ROS中经常用到
每订阅到一个数据,回调函数就被执行一次
类似于中断函数,当订阅到消息后,回调函数才被调用

有点类似于小鬼子踩地雷后 地雷才爆炸,回调函数啥会被执行不是我们可以控制的,是外部相关机制控制的。
而普通函数的调用类似于打鬼子需要造子弹(造子弹可以看作一个函数)

计算图 显示的就是节点之间的关系

解耦合

解耦合的特点的一个体现:
不用语言书写的节点也是可以通信的
跨物种(手动狗头)

2.1.2 话题通信自定义msg

发布消息变为自定义类型
可以发布复合信息

在 ROS 通信协议中,数据载体是一个较为重要组成部分,ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty… 但是,这些数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性,当传输一些复杂的数据,比如: 激光雷达的信息… std_msgs 由于描述性较差而显得力不从心,这种场景下可以使用自定义的消息类型

自定义msg类似于C++的结构体

generate_messages(
DEPENDENCIES
std_msgs ##复合自定义消息类型中的每个字段数据类型都是最为基本的标准数据类型 也就是复合的消息实现需要依赖于标准消息实现
)

在这里插入图片描述
在这里插入图片描述
tips:如果2里面的功能包编写的有问题。编译一定会出问题 。但是如果2没问题3有问题则可能会出现编译也可以通过,但是运行不对,产生异常。
简单地理解为2是编译时的依赖,3为运行时的依赖。
package.xml中添加编译依赖与执行依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

编译生成的中间文件 分为c++调用和python调用的

devel是开发文件夹

C++ 需要调用的中间文件(…/工作空间/devel/include/包名/xxx.h)
Python 需要调用的中间文件(…/工作空间/devel/lib/python3/dist-packages/包名/msg)

在这里插入图片描述

后续调用相关msg时,是从这些中间文件调用的

vscode配置一下
方便vscode找到相关的头文件 让vscode知道头文件在哪(head file)
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
这样就不会出现msg没有编译 cpp文件写好后 同时编译产生的头文件无法使用的问题。

在这里插入图片描述

在这里插入图片描855述

自定义消息类型的话需要在cmakelist多配置两行

add_dependencies(person_talker ${PROJECT_NAME}_generate_messages_cpp)
add_dependencies(person_listener ${PROJECT_NAME}_generate_messages_cpp)

话题通信

2.2 服务通信

服务通信也是ROS中一种极其常用的通信模式服务通信是基于请求响应模式的,是一种应答机制。也即: 一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回给A。比如如下场景:

机器人巡逻过程中,控制系统分析传感器数据发现可疑物体或人… 此时需要拍摄照片并留存。

在上述场景中,就使用到了服务通信。

一个节点需要向相机节点发送拍照请求,相机节点处理请求,并返回处理结果
与上述应用类似的,服务通信更适用于对时时性有要求、具有一定逻辑处理的应用场景。

概念
以请求响应的方式实现不同节点之间数据交互的通信模式。
类似于访问互联网

作用
用于偶然的、对实时性有要求、有一定逻辑处理需求的数据传输场景。

案例
实现两个数字的求和,客户端节点,运行会向服务器发送两个数字,服务器端节点接收两个数字求和并将结

2.2.1 服务通信理论模型

服务通信较之于话题通信更简单些,理论模型如下图所示,该模型中涉及到三个角色:

ROS master(管理者)
Server(服务端)
Client(客户端)

话题(也就是服务) 字符串形式

ROS Master 负责保管 Server 和 Client 注册的信息,并匹配话题相同的 Server 与 Client ,帮助 Server 与 Client 建立连接,连接建立后,Client 发送请求信息,Server 返回响应信息。

在这里插入图片描述
流程:
在这里插入图片描述
1234类比公司地址
3456类比公司服务电话

关注点;
0.
1.也用到了 话题也就是服务(bar) 话题 话题 都需要话题,保证服务端和客户端 有相同的话题
2.实现的时候,关注服务端 ~接收到请求(数据)如何处理
3.关注客户端怎么请求数据,接受到响应之后如何处理
4.涉及到中间的数据载体 请求和响应的数据需要设定成固定格式的 可能需要自己定义数据载体

整个流程由以下步骤实现:

0.Server注册
Server 启动后,会通过RPC在 ROS Master 中注册自身信息,其中包含提供的服务的名称。ROS Master 会将节点的注册信息加入到注册表中。

1.Client注册
Client 启动后,也会通过RPC在 ROS Master 中注册自身信息,包含需要请求的服务的名称。ROS Master 会将节点的注册信息加入到注册表中。

2.ROS Master实现信息匹配
ROS Master 会根据注册表中的信息匹配Server和 Client,并通过 RPC 向 Client 发送 Server 的 TCP 地址信息。

3.Client发送请求
Client 根据步骤2 响应的信息,使用 TCP 与 Server 建立网络连接,并发送请求数据。

4.Server发送响应
Server 接收、解析请求的数据,并产生响应结果返回给 Client。

注意:

1.客户端请求被处理时,需要保证服务器已经启动;
2.服务端和客户端都可以存在多个。
类似于多个公司和多个用户

2.2.2 服务通信自定义srv

定义srv文件
**srv 文件内的可用数据类型与 msg 文件一致,且定义 srv 实现流程与自定义 msg 实现流程类似,都是基于std_msgs标准+

在这里插入图片描述

在这里插入图片描述

argc是命令行总的参数个数
argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数
命令行后面跟的用户输入的参数,

return
如果执行了return语句,那么后面的语句将会不执行。当前函数只要执行了return,之后的代码是不可能执行的
如果没到return,比如return 在 if里面,而if没满足条件,那有可能执行后面的语句

在这里插入图片描述

问题:
如果先启动客户端,那么会请求异常
需求:
如果先请求客户端,不要直接抛出异常,而是挂起,等待服务器启动后,再正常请求 这种问题很常见 因为节点一多 难免有些顺序不能保证

解决:
提供了内置函数 这些函数可以让客户端启动后挂起,等待服务端启动

在客户端发送请求前添加:client.waitForExistence();
或:ros::service::waitForService(“AddInts”);(话题名)
这是一个 阻塞式 函数,只有服务启动成功后才会继续执行

阻塞式函数

在这里插入图片描述

2.3 参数服务器

参数服务器在ROS中主要用于实现不同节点之间的数据共享。参数服务器相当于是独立于所有节点的一个公共容器,可以将数据存储在该容器中,被不同的节点调用,当然不同的节点也可以往其中存储数据,关于参数服务器的典型应用场景如下:

导航实现时,会进行路径规划,比如: 全局路径规划,设计一个从出发点到目标点的大致路径。本地路径规划,会根据当前路况生成时时的行进路径

上述场景中,全局路径规划和本地路径规划时,就会使用到参数服务器:

路径规划时,需要参考小车的尺寸,我们可以将这些尺寸信息存储到参数服务器,全局路径规划节点与本地路径规划节点都可以从参数服务器中调用这些参数
参数服务器,一般适用于存在数据共享的一些应用场景。

概念
以共享的方式实现不同节点之间数据交互的通信模式。

作用
存储一些多节点共享的数据,类似于全局变量。

案例
实现参数增 删 改 查操作。

77777
注意:参数服务器不是为高性能而设计的,因此最好用于存储静态的非二进制的简单数据

rosparam list 查看参数服务器的所有参数

rosparam get /radius 查看参数服务器中的某一个参数的值

1 参数增加与修改

在这里插入图片描述

2 参数查找

param(键,默认值)
存在,返回对应结果,否则返回默认值

    getParam(键,存储结果的变量)
        存在,返回 true,且将值赋值给参数2
        若果键不存在,那么返回值为 false,且不为参数2赋值

    getParamCached键,存储结果的变量)--提高变量获取效率
        存在,返回 true,且将值赋值给参数2
        若果键不存在,那么返回值为 false,且不为参数2赋值

    getParamNames(std::vector<std::string>)
        获取所有的键,并存储在参数 vector 中 

    hasParam(键)
        是否包含某个键,存在返回 true,否则返回 false

    searchParam(参数1,参数2)
        搜索键,参数1是被搜索的键,参数2存储搜索结果的变量

ros::param ----- 与 NodeHandle 类似

在这里插入图片描述

3 参数删除

删除参数的时候只能删一次。因为第一次已经删除了 所以第二次删除的时候会报删除失败的提示

参数操作(C++实现)

2.4 常用命令(基本用来测试 测试 测试)

机器人系统中启动的节点少则几个,多则十几个、几十个,不同的节点名称各异,通信时使用话题、服务、消息、参数等等都各不相同,一个显而易见的问题是: 当需要自定义节点和其他某个已经存在的节点通信时,如何获取对方的话题、以及消息载体的格式呢?

在 ROS 同提供了一些实用的命令行工具,可以用于获取不同节点的各类信息,常用的命令如下:

rosnode : 操作节点
rostopic : 操作话题
rosservice : 操作服务

rosmsg : 操作msg消息
rossrv : 操作srv消息
rosparam : 操作参数

2.4.1 rosnode

rosnode 是用于获取节点信息的命令

rosnode ping 测试到节点的连接状态
rosnode list 列出活动节点
rosnode info 打印节点信息
rosnode machine 列出指定设备上节点
rosnode kill 杀死某个节点
rosnode cleanup 清除不可连接的节点,也就是清除僵尸节点(已经关掉了节点,理论上节点已经死了,但是master还不知道)

2.4.2 rostopic(话题通信相关 topic)

话题通信 话题通信(发布订阅模式) topic

rostopic包含rostopic命令行工具,用于显示有关ROS 主题的调试信息,包括发布者,订阅者,发布频率和ROS消息。它还包含一个实验性Python库,用于动态获取有关主题的信息并与之交互。

rostopic bw 显示主题使用的带宽
rostopic delay 显示带有 header 的主题延迟
rostopic echo 打印消息到屏幕
rostopic find 根据类型查找主题
rostopic hz 显示主题的发布频率
rostopic info 显示主题相关信息
rostopic list 显示所有活动状态下的主题
rostopic pub 将数据发布到主题
rostopic type 打印主题类型

2.4.4 rosservice(与服务通信相关 service)

rosservice包含用于列出和查询ROSServices的rosservice命令行工具。

调用部分服务时,如果对相关工作空间没有配置 path,需要进入工作空间调用 source ./devel/setup.bash

2.4.5 rosmsg(用在发布订阅模型中)

rosmsg是用于显示有关 ROS消息类型的 信息的命令行工具。

rosmsg 演示

rosmsg show 显示消息描述
rosmsg info 显示消息信息
rosmsg list 列出所有消息类型
rosmsg md5 显示 md5 加密后的消息
rosmsg package 显示某个功能包下的所有消息
rosmsg packages 列出包含消息的功能包

2.4.5 rossrv

rossrv是用于显示有关ROS服务类型的信息的命令行工具,与 rosmsg 使用语法高度雷同。

rossrv show 显示服务消息详情
rossrv info 显示服务消息类型的相关信息
rossrv list 列出所有服务信息类型 (在srv文件夹下

rossrv md5 显示 md5 加密后的服务消息
rossrv package 显示某个包下所有服务消息
rossrv packages 显示包含服务消息的所有包

查看自定义的消息载体 ,要查看的话一定要进入工作空间,刷新环境变量

2.4.6 rosparam

rosparam包含rosparam命令行工具,用于使用 YAML 编码文件在参数服务器上获取和设置ROS参数。

rosparam set 设置参数
rosparam get 获取参数
rosparam load 从外部文件加载参数
rosparam dump 将参数写出到外部文件
rosparam delete 删除参数
rosparam list 列出所有参数
在这里插入图片描述

2.5 通信机制实操

2.5.1 话题发布

机器人运动中常见的参数 六自由度
以机器人作参考坐标

在这里插入图片描述
小乌龟 线速度只有x 角速度只有偏航角z
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
roslaunch plumbing_test start_turtle.launch

在这里插入图片描述
在这里插入图片描述

后期需要添加功能包的配置
1
在这里插入图片描述
2
在这里插入图片描述

只要涉及到节点之间通信的,话题 和 消息载体是必不可少的

2.5.3

在这里插入图片描述

一般都是自定义srv文件 请求部分的数据和响应部分的数据会用三个—分开
可以概括为: 两个节点通过话题关联到一起,并使用某种类型的数据载体实现数据传输。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ROS2的源码是指ROS2软件框架的实现源代码,其中包含了ROS2的核心功能实现及相关库和工具的源代码。 赵虚C是指赵虚所编写的ROS2 C语言版本的源码。赵虚C源码是一种使用C语言实现的ROS2框架源码,它基于ROS2的设计理念和规范,实现了ROS2的核心功能。 在赵虚C源码中,可以看到ROS2中的许多重要概念和组件的实现,包括节点(Node)、话题(Topic)、服务(Service)和参数(Parameter)等。通过阅读这些源码,可以深入理解ROS2的工作原理和实现细节,以便于进行二次开发和定制化。 此外,赵虚C源码还包含了ROS2的通信机制、消息传输和序列化等关键部分的实现。通过分析这些源码,可以了解ROS2是如何处理节点之间的通信、数据的传输和消息的序列化与反序列化的过程。 总之,赵虚C源码是ROS2的一种具体实现,通过对它的研究和理解,可以深入了解ROS2的内部机制和工作原理,为ROS2的应用开发和定制提供参考和基础。 ### 回答2: ROS 2(Robot Operating System 2)是一个用于开发机器人和机器人系统的开源框架。而"赵虚 c"是一个源码工程师,可能是ROS 2框架的贡献者之一,他在其中的C++源码方面进行了贡献。 ROS 2是ROS框架的下一代版本,它提供了更强大、更灵活的功能,使得开发机器人应用更加简单和高效。与ROS 1相比,ROS 2在可扩展性、实时性、安全性和分布式系统方面有了进一步的改进。 "赵虚 c"可能是一个开发者,他在ROS 2源码中使用了C++语言来为框架做出贡献。C++是一种通用的、高级的编程语言,常用于开发复杂的系统和应用。在ROS 2中,C++用于编写框架的核心功能、通信模块、节点等。 作为一个源码工程师,"赵虚 c"可能参与了ROS 2的开发过程,贡献了自己的代码和思想。他可能在ROS 2的源码中实现了一些功能模块、优化了代码结构、提高了系统的性能,或者修复了一些bug。 通过贡献C++源码,"赵虚 c"可能帮助改进了ROS 2框架,使得它更加稳定、高效、易用。源码工程师的工作是为了让软件系统能够更好地满足用户需求,提供良好的开发体验和性能。 总结来说,"ros2 赵虚 c"源码可能指的是ROS 2框架中贡献者赵虚的C++源码。他通过自己的工作,为ROS 2框架的发展和改进做出了贡献。 ### 回答3: ROS 2是Robot Operating System(机器人操作系统)的第二个主要版本。相比于ROS 1,ROS 2在一些方面进行了改进和优化。其中ROS 2的核心部分就是ROS 2的源码,它包含了ROS 2系统的各个模块和功能的实现。 赵虚C是ROS 2中的一个模块,它是基于C语言编写的。赵虚C的作用是提供一些ROS 2系统中常用的功能,比如节点节点的创建与运行、消息的发布与订阅等。赵虚C的源码中包含了一些函数和数据结构,通过这些函数和数据结构,开发者可以在自己的ROS 2应用程序中调用和使用这些功能。 赵虚C源码的结构比较清晰,它按照模块和功能进行了组织。赵虚C的源码中使用了一些ROS 2的API和库函数,这些函数通过ROS 2的底层实现来完成特定的功能。在理解赵虚C源码时,需要对ROS 2的相关概念和机制有所了解,比如节点的概念、消息的定义与传输、话题的订阅与发布等。 通过阅读赵虚C源码,可以更深入地理解ROS 2系统的运行原理和实现细节。同时,开发者也可以基于赵虚C的源码进行二次开发,实现自己的ROS 2应用程序,以满足特定的需求。 总之,赵虚C是ROS 2中的一个重要模块,通过阅读其源码可以更好地理解和使用ROS 2系统。对于ROS 2开发者来说,熟悉赵虚C源码是提高开发效率和质量的一种有效途径。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值