赞
踩
前面ROS很多都忘记了 ,现在来重新回顾一下内容
ROS 中的基本通信机制主要有如下三种实现策略:
话题通信(发布订阅模式)
服务通信(请求响应模式)
参数服务器(参数共享模式)
Action通信
以发布订阅的方式实现不同节点之间数据交互的通信模式。
话题通信实现模型是比较复杂的,该模型如下图所示,该模型中涉及到三个角色:
ROS Master 负责保管 Talker 和 Listener 注册的信息,并匹配话题相同的 Talker 与 Listener,帮助 Talker 与 Listener 建立连接,连接建立后,Talker 可以发布消息,且发布的消息会被 Listener 订阅
ROS中的通信方式中,topic是常用的一种。对于实时性、周期性的消息,使用topic来传输是最佳的选择。topic是一种点对点的单向通信方式,这里的“点”指的是node,也就是说node之间可以通过topic方式来传递信息。topic要经历下面几步的初始化过程:首先,publisher节点和subscriber节点都要到节点管理器进行注册,然后publisher会发布topic,subscriber在master的指挥下会订阅该topic,从而建立起sub-pub之间的通信。注意整个过程是单向的。
其中在话题通信中值得注意的是
代码
- //topic_pub1.cpp
- #include"ros/ros.h"
- #include<std_msgs/String.h>
- #include<sstream>
-
- int main(int args ,char *argv[])
- {
- //设置编码 会在终端输出信息 防止乱码
- setlocale(LC_ALL,"");
-
- //初始化 ROS 节点:命名(唯一) 节点命名不能重复
- // 参数1和参数2 后期为节点传值会使用
- // 参数3 是节点名称,是一个标识符,需要保证运行后,在 ROS 网络拓扑中唯一
- ros::init(args,argv,"talker");
-
- //实例化句柄该类封装了 ROS 中的一些常用功能
- ros::NodeHandle nh;
-
- //实例化 发布者 对象
- //泛型: 发布的消息类型
- //参数1: 要发布到的话题
- //参数2: 队列中最大保存的消息数,超出此阀值时,先进的先销毁(时间早的先销毁)
-
- //n.advertise通过NodeHandle的对象n告诉ROS系统我要创建一个可以发布信息的对象了。这个信息是什么类型的呢?
- //<std_msgs::String>告诉ROS我要发布的是标准信息中的String类型。
- //那些信息叫啥名字呢?名字叫chatter。这个chatter就是我们之前提到的topic!
-
- ros::Publisher pub=nh.advertise<std_msgs::String>("chatter",10);
-
- std_msgs::String msg;
-
- std::string msg_fromt="day day up";
- int count =0; //计数器
- //逻辑(一秒10次) 可以制定循环的频率
- //程序如果在不断地发布信息,那么有时候我会想控制发布的信息的快慢,这行表示你希望你发布信息的速度为10Hz。
- //这个函数要和ros::Rate r.sleep()配合使用才能达到控制速度目的
- ros::Rate r(10);
-
- while(ros::ok())
- {
- std::stringstream ss;
-
- ss<<msg_fromt<<count;
- msg.data=ss.str();
-
- //发布消息
- pub.publish(msg);
-
- //输出消息
- ROS_INFO("发送的消息:%s",msg.data.c_str());
-
- r.sleep();
- count++;
-
- //回调函数
- ros::spinOnce();
-
- }
- return 0;
- }

- //topic_sub1.cpp
- // 1.包含头文件
- #include "ros/ros.h"
- #include "std_msgs/String.h"
-
- void doMsg(const std_msgs::String::ConstPtr& msg_p){
- ROS_INFO("我听见:%s",msg_p->data.c_str());
-
- }
- int main(int argc, char *argv[])
- {
- setlocale(LC_ALL,"");
- //2.初始化 ROS 节点:命名(唯一)
- ros::init(argc,argv,"listener");
- //3.实例化 ROS 句柄
- ros::NodeHandle nh;
-
- //4.实例化 订阅者 对象
- ros::Subscriber sub = nh.subscribe<std_msgs::String>("chatter",10,doMsg);
- //5.处理订阅的消息(回调函数)
-
- // 6.设置循环调用回调函数
- ros::spin();//循环读取接收的数据,并调用回调函数处理
-
- return 0;
- }



ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty.... 但是,这些数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性,当传输一些复杂的数据,比如: 激光雷达的信息... std_msgs 由于描述性较差而显得力不从心,这种场景下可以使用自定义的消息类型
其中 ros::spin() 是进入了循环执行回调函数,而 r
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。