ROS:通信机制

news2024/12/28 19:39:39

目录

  • 一、通信机制简介
  • 二、话题通信机制
    • 2.1话题通信简介
    • 2.2话题通信实操(C++)
      • 2.2.1分析
      • 2.2.2发布方代码
      • 2.2.3订阅方代码
      • 2.2.4配置CMakeLists.txt
      • 2.2.5执行
      • 2.2.6注意
    • 2.3话题通信实操(python)
      • 2.3.1分析
      • 2.3.2发布方代码
      • 2.3.3订阅方代码
      • 2.3.4添加可执行权限
      • 2.3.5配置 CMakeLists.txt
      • 2.3.6执行
  • 三、服务通信机制
  • 四、参数管理机制
  • 五、话题与服务的区别

一、通信机制简介

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

ROS 中的基本通信机制主要有如下三种实现策略:
话题通信(发布订阅模式)
服务通信(请求响应模式)
参数服务器(参数共享模式)

二、话题通信机制

2.1话题通信简介

话题在ROS中使用最为频繁,其通信模型也较为复杂。在ROS中有两个节点:一个是发布者Talker,另一个是订阅着Listener。两个节点分别发布、订阅同一个话题,启动顺序没有强制要求,此处假设Talker首先启动,可分为如下七步分析建立通信的详细过程。
在这里插入图片描述
0、Talker注册
Talker启动,通过1234端口使用RPC向ROS Master注册发布者的信息,包含所发布消息的话题名;ROS Master会将节点的注册信息加入注册列表中。
1、Listener注册
Listener启动,同样通过RPC向ROS Master注册订阅者的信息,包含需要订阅的话题名。
2、ROS Master进行信息匹配
Master根据Listener的订阅信息从注册列表中进行查找,如果没有找到匹配的发布者,则等待发布者的加入:如果找到匹配的发布者信息,则通过RPC向Listener发送Talker的RPC地址信息。
3、Listener发送连接请求
Listener接收到Master发回的Talker地址信息,尝试通过RPC向Talker发送连接请求,传输订阅的话题名、消息类型以及通信协议(TCP/UDP)
4、Talker确认连接请求
Talker接收到Listener发送的连接请求后,继续通过RPC向Listener确认连接信息,其中包含自身的TCP地址信息。
5、Listener尝试与Talker建立网络连接
Listener接收到确认信息后,使用TCP尝试与Talker建立网络连接。
6、Talker向Listener发布数据
成功建立连接后,Talker开始向Listener发送话题消息数据。
从上面的分析中可以发现,前五个步骤使用的通信协议都是RPC,最后发布数据的过程才使用到TCP。ROS Master在节点建立连接的过程中起到了重要作用,但是并不参与节点之间最终的数据传输。

2.2话题通信实操(C++)

2.2.1分析

在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:
发布方
接收方
数据(此处为普通文本)

流程:
编写发布方实现;
编写订阅方实现;
编辑配置文件;
编译并执行。

2.2.2发布方代码

#include "ros/ros.h"
#include "std_msgs/String.h"
#include "sstream"

/*
发布方实现:
1.包含头文件
ROS中文本类型--->td_msgs/String.h
2.初始化ros节点
3.创建节点句柄
4.创建发布者对象
5.编写发布逻辑并发布数据
*/



int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    //2.初始化ros节点
    ros::init(argc,argv,"erGouZi");
    //3.创建节点句柄
    ros::NodeHandle nh;
    //4.创建发布者对象
    ros::Publisher pub = nh.advertise<std_msgs::String>("fang",10);
    //5.编写发布逻辑并发布数据
    //要求以10HZ的频率发布数据,并且文本后添加编号
    //先创建被发布的消息
    std_msgs::String msg;
    //发布频率
    ros::Rate rate(10);
    //设置编号
    int count =0;
    //编写循环,循环中发布数据
    while (ros::ok())
    {
        count++;
        //msg.data = "hello";
        //实现字符串拼接数字
        std::stringstream ss;
        ss << "hello ---> " <<count;
        msg.data = ss.str();
        pub.publish(msg);

        //添加日志
        ROS_INFO("发布的数据是:%s",ss.str().c_str());

        rate.sleep();根据前面制定的发送贫频率自动休眠 休眠时间 = 1/频率;

        ros::spinOnce();//官方建议添加回调函数
    }
    
    return 0;
}

2.2.3订阅方代码

#include "ros/ros.h"
#include "std_msgs/String.h"


/*
订阅方实现:
1.包含头文件
ROS中文本类型--->td_msgs/String.h
2.初始化ros节点
3.创建节点句柄
4.创建订阅者对象
5.处理订阅数据
6.sain()函数
*/

void doMsg(const std_msgs::String::ConstPtr &msg)
{
    //通过msg获取并操作订阅到的数据
    ROS_INFO("翠花订阅的数据:%s",msg->data.c_str());

}

int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    //2.初始化ros节点
    ros::init(argc,argv,"cuihua");
    //3.创建节点句柄
    ros::NodeHandle nh;
    //4.创建订阅者对象
    ros::Subscriber sub = nh.subscribe("fang",10,doMsg);
    //5.处理订阅数据

    ros::spin();//循环读取接收的数据,并调用回调函数处理




    return 0;
}

2.2.4配置CMakeLists.txt

add_executable(demo01_pub src/demo01_pub.cpp)
add_executable(demo02_sub src/demo02_sub.cpp)

target_link_libraries(demo01_pub
  ${catkin_LIBRARIES}
)
target_link_libraries(demo02_sub
  ${catkin_LIBRARIES}
)

2.2.5执行

1.启动 roscore;

2.启动发布节点;

3.启动订阅节点。
在这里插入图片描述

2.2.6注意

补充0:

vscode 中的 main 函数 声明 int main(int argc, char const *argv[]){},默认生成 argv 被 const 修饰,需要去除该修饰符

补充1:

ros/ros.h No such file or directory …

检查 CMakeList.txt find_package 出现重复,删除内容少的即可

参考资料:https://answers.ros.org/question/237494/fatal-error-rosrosh-no-such-file-or-directory/

补充2:

find_package 不添加一些包,也可以运行啊, ros.wiki 答案如下

You may notice that sometimes your project builds fine even if you did not call find_package with all dependencies. This is because catkin combines all your projects into one, so if an earlier project calls find_package, yours is configured with the same values. But forgetting the call means your project can easily break when built in isolation.


补充3:

订阅时,第一条数据丢失

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

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

2.3话题通信实操(python)

2.3.1分析

分析:

在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:
发布方
接收方
数据(此处为普通文本)

流程:
编写发布方实现;
编写订阅方实现;
为python文件添加可执行权限;
编辑配置文件;
编译并执行。

2.3.2发布方代码

#include "ros/ros.h"
#include "std_msgs/String.h"
#include "sstream"

/*
发布方实现:
1.包含头文件
ROS中文本类型--->td_msgs/String.h
2.初始化ros节点
3.创建节点句柄
4.创建发布者对象
5.编写发布逻辑并发布数据
*/



int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");
    //2.初始化ros节点
    ros::init(argc,argv,"erGouZi");
    //3.创建节点句柄
    ros::NodeHandle nh;
    //4.创建发布者对象
    ros::Publisher pub = nh.advertise<std_msgs::String>("fang",10);
    //5.编写发布逻辑并发布数据
    //要求以10HZ的频率发布数据,并且文本后添加编号
    //先创建被发布的消息
    std_msgs::String msg;
    //发布频率
    ros::Rate rate(10);
    //设置编号
    int count =0;
    //编写循环,循环中发布数据
    while (ros::ok())
    {
        count++;
        //msg.data = "hello";
        //实现字符串拼接数字
        std::stringstream ss;
        ss << "hello ---> " <<count;
        msg.data = ss.str();
        pub.publish(msg);

        //添加日志
        ROS_INFO("发布的数据是:%s",ss.str().c_str());

        rate.sleep();//根据前面制定的发送贫频率自动休眠 休眠时间 = 1/频率;

        ros::spinOnce();//官方建议添加回调函数
    }
    
    return 0;
}

2.3.3订阅方代码

#! /usr/bin/env python

import rospy
from std_msgs.msg import String #发布消息的类型

"""
使用py 实现消息订阅
1.导包
2.初始化ROS节点
3.创建订阅者对象
4.回调函数处理数据
spin

"""
def doMsg(msg):
    rospy.loginfo("我订阅的数据:%s",msg.data)


if __name__ == "__main__":
    # 2.初始化ROS节点
    rospy.init_node("huahua")#传入节点名称
    # 3.创建订阅者对象
    sub = rospy.Subscriber("che",String,doMsg,queue_size=10)
    # 4.回调函数处理数据
    #5.spin
    rospy.spin()

2.3.4添加可执行权限

终端下进入 scripts 执行:chmod +x *.py

2.3.5配置 CMakeLists.txt

catkin_install_python(PROGRAMS
  scripts/demo01_pub_p.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
catkin_install_python(PROGRAMS
  scripts/demo02_sub_p.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

2.3.6执行

1.启动 roscore;

2.启动发布节点;

3.启动订阅节点。
在这里插入图片描述
注:可以使用 rqt_graph 查看节点关系。

三、服务通信机制

服务是一种带有应答的通信机制,与话题的通信相比,其减少了Listener与Talker之间的RPC通信。
在这里插入图片描述

0、Talker注册
Talker启动,通过1234端口使用RPC向ROS Master注册发布者的信息,包含所提供的服务名;ROS Master会将节点的注册信息加入注册列表中。
1、Listener注册
Listener启动,同样通过RPC向ROS Master注册订阅者的信息,包含需要订阅的服务名。
2、ROS Master进行信息匹配
Master根据Listener的订阅信息从注册列表中进行查找,如果没有找到匹配的服务提供者,则等待该服务的提供者加入:如果找到匹配的服务提供者信息,则通过RPC向Listener发送Talker的TCP地址信息。
4、Listener与Talker建立网络连接
Listener接收到确认信息后,使用TCP尝试与Talker建立网络连接,并且发送服务的请求数据。
5、Talker向Listener发布服务应答数据
Talker接收到服务请求和参数后,开始执行服务功能,执行完成后,向Listener发送应答数据。

四、参数管理机制

参数类似于ROS中的全局变量,由ROS Master进行管理,其通信机制较为简单,不涉及TCP/UDP的通信。
在这里插入图片描述
1、Talker设置变量
Talker使用RPC向ROS Master发送参数设置数据,包含参数名和参数值;ROS Master会将参数名和参数值保存到参数列表中。
2、Listener查询参数值
Listener通过RPC向ROS Master发送参数查找请求,包含所要查找的参数名。
3、ROS Master向Listener发送参数值
Master根据Listener的查找请求从参数列表中进行查找,查找到参数后,使用RPC将参数值发送给Listener。

五、话题与服务的区别

话题和服务是ROS中最基础也是使用最多的通信方法。具体总结如表所示。
话题与服务的区别
在这里插入图片描述
总之,话题是ROS中基于发布/订阅模型的异步通信模式,这种方式将信息的产生和使用双方解耦,常用于不断更新的、含有较少逻辑处理的数据通信;而服务多用于处理ROS中的同步通信,采用客户端/服务器模型,常用于数据量较少但有强逻辑处理的数据交换。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/677460.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机网络】第二章 物理层(上)

文章目录 2.1 物理层的基本概念2.2 物理层下面的传输媒体2.3 传输方式2.4 编码与调制2.4.1 介绍2.4.2 常用编码2.4.3 编码习题2.4.4 基本调制方法2.4.5 混合调制 2.1 物理层的基本概念 物理层考虑的是怎样在连接各种计算机的传输媒体上传输数据比特流。 物理层为数据链路层屏蔽…

4.0、Java_IO流 - 流的概念细分

4.0、Java_IO流 - 流的概念细分 按照流的方向分类&#xff1a; 输入流&#xff1a;数据流从数据源到程序&#xff08;以 InputStream 、Reader 结尾的流&#xff09;&#xff1b; 输出流&#xff1a;数据流从程序到目的地&#xff08;以 OutputStream 、Writer 结尾的流&#x…

【雕爷学编程】Arduino动手做(120)---游戏摇杆扩展板

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

2023-06-23:redis中什么是缓存击穿?该如何解决?

2023-06-23&#xff1a;redis中什么是缓存击穿&#xff1f;该如何解决&#xff1f; 答案2023-06-23&#xff1a; 缓存击穿是指一个缓存中的热点数据非常频繁地被大量并发请求访问&#xff0c;当该热点数据失效的瞬间&#xff0c;持续的大并发请求无法通过缓存获取到数据&…

Triton教程 --- Triton 响应缓存

Triton教程 — Triton 响应缓存 Triton系列教程: 快速开始利用Triton部署你自己的模型Triton架构模型仓库存储代理模型设置优化动态批处理速率限制器模型管理自定义算子解耦后端和模型 概述 在本文档中&#xff0c;推理请求是模型名称、模型版本和输入张量&#xff08;名称、…

ChatGPT从入门到精通,深入认识ChatGPT

ChatGPT从入门到精通&#xff0c;一站式掌握办公自动化/爬虫/数据分析和可视化图表制作 全面AI时代就在转角 道路已经铺好了 “局外人”or“先行者” 就在此刻 等你决定1、ChatGPT从入门到精通&#xff0c;一站式掌握办公自动化/爬虫/数据分析和可视( 点击观看完整版本 )https…

TreeMap数据结构及源码解析.跟学黑马

TreeMap数据结构及源码解析 1.TreeMap的特点2.TreeMap的数据结构2.1二叉查找树2.1.1二叉查找树的定义2.1.2二叉查找树的查找操作 2.2平衡二叉树2.2.1平衡二叉树的定义2.2.2平衡二叉树的旋转 2.3红黑树2.3.1红黑树的定义 2.TreeMap的源码分析2.1get()获取方法分析2.2put()添加方…

企业级开发项目和自学项目到底有什么区别

前言 好久不见了各位&#xff01;最近几个月都未更新&#xff0c;是因为从春招开始就在投简历面试实习岗位&#xff0c;然后入职&#xff0c;最后成功成为了一个半成品后端练习生&#xff0c;想说的话有太多太多 下面就站在一个在校实习生的身份&#xff0c;结合自己最近几个月…

科普 | 眼图

本文简要说明眼图相关的知识&#xff0c;参考是德科技的文章 1。 科普 | 眼图 基本知识串扰眼图眼图的产生原理及作用创建眼图 - 眼图波形的采样过程眼图的产生原理及作用眼图可以看出哪些性能指标&#xff1f;如何评判眼图质量&#xff1f;眼图测试模板眼图与存储深度实时的眼…

短视频seo源码开发部署技术解析

短视频seo开发需要哪些技术 应用程序优化技术&#xff1a;包括应用程序的各种元素&#xff08;如标题、描述、关键字、图标等&#xff09;的优化和设置&#xff0c;以及应用程序内部链接和导航的合理布局和设置。 视频内容优化技术&#xff1a;包括视频标题、描述、标签、封面…

人工智能数据集处理——数据获取

目录 1、从csv和txt文件中读取数据 pandas中可使用read_csv读取csv或txt文件中的数据 使用read_csv()函数读取phones.csv文件中的数据,并指定编码格式为gbk 使用head()方法指定获取phones.csv文件中前3行的数据 使用read_csv() 函数读取 itheima_books.txt文件中的数据,并指…

【Redis】2、Redis 的 Java 客户端(Jedis 和 SpringDataRedis)

目录 零、Redis 的 Java 客户端有哪些&#xff1f;二、Jedis 客户端(1) 引依赖(2) 连接 Redis 服务并测试(3) Redis 连接池 三、SpringDataRedis 介绍四、SpringBoot 中集成 SpringDataRedis(1) 引入依赖(2) 配置文件中书写相关配置(3) RedisTemplate 的默认序列化方式(4) 自定…

高校学生考勤系统

摘 要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括高校学生考勤系统的网络应用&#xff0c;在外国高校学生考勤系统已经是很普遍的方式&#xff0c;不过国内的高校学生考勤可能还处于起步阶段。高校学生考勤系统具有管理…

Linux网络-数据链路层,MAC帧解析,ARP协议

目录 数据链路层VS网络层 以太网概念 以太网的帧格式&#xff08;报文格式&#xff09;&#xff08;也可以称之为MAC帧&#xff09; MAC地址的概念 MAC帧格式 局域网通信原理 MTU MTU说明 MTU对IP协议的影响 MTU对UDP协议的影响 MTU对TCP协议的影响 ARP协议 ARP协…

【算法题解】41. 二叉树的中序遍历

这是一道 简单 题 https://leetcode.cn/problems/binary-tree-inorder-traversal/ 题目 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2] 示例 2&#xff1a; 输入&#…

[易语言][部署]使用易语言部署paddleocr的onnx模型api接口推理直接调用

易语言如何部署paddleocr模型&#xff0c;如今paddleocr模型广泛被使用各种编程&#xff0c;为了能在易语言上使用因此开发一个通用接口&#xff0c;开发基本思路如下&#xff1a; 可见我们并没有使用什么通信协议或者命令行之类的方法&#xff0c;这种直接封装接口比其他方法更…

TCP 学习笔记

Win R 打开控制台输入CMD 打开小黑窗&#xff0c; 输入ipconfig 查询本机地址 “外网IP是全世界唯一的IP地址,仅分配给一个网络设备。而内网IP是由路由器分配给每一部内部使用的IP地址,而内网的所有用户都是通过同一个外网IP地址进行上网的,而内网的IP地址每个人的都不一样…

(四)WPF - 布局

一、布局过程 WPF 布局包括两个阶段&#xff1a;一个测量阶段和排列阶段 在测量阶段&#xff0c;容器遍历所有子元素&#xff0c;并询问子元素它们所期望的尺寸。在排列阶段&#xff0c;容器在合适的位置放置子元素。&#xff08;每个元素都被其父元素告知它自己的尺寸是多少…

【软件设计师暴击考点】下午题高频考点暴击系列

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;软件…

电脑选购必备的六大技巧

目录 1、CPU方面 2、显卡方面 3、电脑主板方面 4、内存和硬盘方面 5、电脑机箱和电源方面 6、装机过程要全程参与 今天小编给大家分享电脑选购组装必备的六大技巧&#xff0c;希望对大家实际选购、组装电脑提供一些帮助&#xff01; 买电脑要注意哪些问题 1、CPU方面 C…