当前位置:   article > 正文

ROS自主导航学习———ROS通信机制_setlocale(lc_all,"");

setlocale(lc_all,"");

前言

前面ROS很多都忘记了 ,现在来重新回顾一下内容

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

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

  • 服务通信(请求响应模式)

  • 参数服务器(参数共享模式)

  • Action通信

ROS常用API

第 3 章 ROS通信机制进阶 · GitBookhttp://www.autolabor.com.cn/book/ROSTutorials/di-3-zhang-ros-tong-xin-ji-zhi-jin-jie.html

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

以发布订阅的方式实现不同节点之间数据交互的通信模式。

话题通信实现模型是比较复杂的,该模型如下图所示,该模型中涉及到三个角色:

  • ROS Master (管理者)
  • Talker (发布者)
  • Listener (订阅者)

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之间的通信。注意整个过程是单向的。

其中在话题通信中值得注意的是

  • Subscriber接收消息会进行处理,一般这个过程叫做回调(Callback)。所谓回调就是提前定义好了一个处理函数(写在代码中),当有消息来就会触发这个处理函数,函数会对消息进行处理
  • ROS是一种分布式的架构,一个topic可以被多个节点同时发布,也可以同时被多个节点接收。

话题通信的基本操作

代码

  1. //topic_pub1.cpp
  2. #include"ros/ros.h"
  3. #include<std_msgs/String.h>
  4. #include<sstream>
  5. int main(int args ,char *argv[])
  6. {
  7. //设置编码 会在终端输出信息 防止乱码
  8. setlocale(LC_ALL,"");
  9. //初始化 ROS 节点:命名(唯一) 节点命名不能重复
  10. // 参数1和参数2 后期为节点传值会使用
  11. // 参数3 是节点名称,是一个标识符,需要保证运行后,在 ROS 网络拓扑中唯一
  12. ros::init(args,argv,"talker");
  13. //实例化句柄该类封装了 ROS 中的一些常用功能
  14. ros::NodeHandle nh;
  15. //实例化 发布者 对象
  16. //泛型: 发布的消息类型
  17. //参数1: 要发布到的话题
  18. //参数2: 队列中最大保存的消息数,超出此阀值时,先进的先销毁(时间早的先销毁)
  19. //n.advertise通过NodeHandle的对象n告诉ROS系统我要创建一个可以发布信息的对象了。这个信息是什么类型的呢?
  20. //<std_msgs::String>告诉ROS我要发布的是标准信息中的String类型。
  21. //那些信息叫啥名字呢?名字叫chatter。这个chatter就是我们之前提到的topic!
  22. ros::Publisher pub=nh.advertise<std_msgs::String>("chatter",10);
  23. std_msgs::String msg;
  24. std::string msg_fromt="day day up";
  25. int count =0; //计数器
  26. //逻辑(一秒10次) 可以制定循环的频率
  27. //程序如果在不断地发布信息,那么有时候我会想控制发布的信息的快慢,这行表示你希望你发布信息的速度为10Hz。
  28. //这个函数要和ros::Rate r.sleep()配合使用才能达到控制速度目的
  29. ros::Rate r(10);
  30. while(ros::ok())
  31. {
  32. std::stringstream ss;
  33. ss<<msg_fromt<<count;
  34. msg.data=ss.str();
  35. //发布消息
  36. pub.publish(msg);
  37. //输出消息
  38. ROS_INFO("发送的消息:%s",msg.data.c_str());
  39. r.sleep();
  40. count++;
  41. //回调函数
  42. ros::spinOnce();
  43. }
  44. return 0;
  45. }
  1. //topic_sub1.cpp
  2. // 1.包含头文件
  3. #include "ros/ros.h"
  4. #include "std_msgs/String.h"
  5. void doMsg(const std_msgs::String::ConstPtr& msg_p){
  6. ROS_INFO("我听见:%s",msg_p->data.c_str());
  7. }
  8. int main(int argc, char *argv[])
  9. {
  10. setlocale(LC_ALL,"");
  11. //2.初始化 ROS 节点:命名(唯一)
  12. ros::init(argc,argv,"listener");
  13. //3.实例化 ROS 句柄
  14. ros::NodeHandle nh;
  15. //4.实例化 订阅者 对象
  16. ros::Subscriber sub = nh.subscribe<std_msgs::String>("chatter",10,doMsg);
  17. //5.处理订阅的消息(回调函数)
  18. // 6.设置循环调用回调函数
  19. ros::spin();//循环读取接收的数据,并调用回调函数处理
  20. return 0;
  21. }

话题通信自定义msg  

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

其中  ros::spin() 是进入了循环执行回调函数,而 r

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/49882
推荐阅读
相关标签
  

闽ICP备14008679号