ROS Topic in roscpp 通信

简介: Topic是ROS里一种异步通信的模型,,一般是节点间分工明确,有的只负责发送,有的只负责 接收处理。对于绝大多数的机器人应用场景,比如传感器数据收发,速度控制指令的收发, Topic模型是最适合的通信方式。

topic 简介

Topic是ROS里一种异步通信的模型,,一般是节点间分工明确,有的只负责发送,有的只负责 接收处理。对于绝大多数的机器人应用场景,比如传感器数据收发,速度控制指令的收发, Topic模型是最适合的通信方式。

ROS中的通信方式中,topic是常用的一种。对于实时性、周期性的消息,使用topic来传输是 最佳的选择。topic是一种点对点的单向通信方式,这里的“点”指的是node,也就是说node之 间可以通过topic方式来传递信息。topic要经历下面几步的初始化过程:首先,publisher节点 和subscriber节点都要到节点管理器进行注册,然后publisher会发布topic,subscriber在 master的指挥下会订阅该topic,从而建立起sub-pub之间的通信。注意整个过程是单向的。其 结构示意图如下:
在这里插入图片描述
Subscriber接收消息会进行处理,一般这个过程叫做回调(Callback)。所谓回调就是提前定义 好了一个处理函数(写在代码中),当有消息来就会触发这个处理函数,函数会对消息进行 处理。
上图就是ROS的topic通信方式的流程示意图。topic通信属于一种异步的通信方式。

topic demo 收发实列

1、创建gps消息

在代码中,会用到自定义类型的gps消息,因此就需要来自定义gps消息,在msg路径下 创建 gps.msg。
在这里插入图片描述

float32 x       #x坐标 
float32 y       #y坐标
string state      #工作状态 

以上就定义了一个gps类型的消息,可以把它理解成一个C语言中的结构体,类似于

struct    gps
 {            
     string    state;            
    float32    x;        
     float32    y;
 }

在程序中对一个gps消息进行创建修改的方法和对结构体的操作一样。
当创建完了msg文件,记得修改 CMakeLists.txt和 package.xml,从而让系统能够编译自定义消息。在CMakeLists.txt中需要改动

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation    #generate new msg must add    #需要添加的地方 
)

add_message_files(FILES    gps.msg)    #catkin在cmake之上新增的命令,指定从哪个消息文件生成

generate_messages(DEPENDENCIES    std_msgs) #DEPENDENCIES后面指定生成msg需要依赖其他什么消息,由于gps.msg用到了flaot32这种ROS标准消息,因此需 要再把std_msgs作为依赖

package.xml 中需要的改动

  <build_depend>message_generation</build_depend>     <!-- #generate new msg must add-->
  <exec_depend>message_runtime</exec_depend>          <!-- #generate new msg must add-->

当你完成了以上所有工作,就可以回到工作空间,然后编译了。编译完成之后会在 devel 路 径下生成 gps.msg 对应的头文件,头文件按照C++的语法规则定义了 topic_demo::gps 类型的 数据。
在这里插入图片描述
要在代码中使用自定义消息类型,只要 #include <topic_demo/gps.h> ,然后声明,按照对结 构体操作的方式修改内容即可。

topic_demo::gps    mygpsmsg; 
 mygpsmsg.x    =    1.6;
 mygpsmsg.y    =    5.5; 
 mygpsmsg.state    =    "working";

2、消息发布节点

定义完了消息,开始写ROS代码。通常会把消息收发的两端分成两个节点来写,一个节点就是一个完整的C++程序。
在src下建立talker.cpp发送节点
在这里插入图片描述
源码如下:

#include <ros/ros.h>
#include <topic_demo_jone/gps.h>  //引入生成的消息类型

int main(int argc, char **argv)
{
  
   ros::init(argc,argv,"talker_jone");//用于解析ROS参数,第三个参数为本节点名  注意要与后面修改的Cmakelist.txt文件对应

   ros::NodeHandle nh ;    //实例化句柄,初始化node

   topic_demo_jone::gps msg;//自定义gps消息并初始化

   msg.x=1;
   msg.y=2;
   msg.state="working";


   ros::Publisher pub = nh.advertise<topic_demo_jone::gps>("gps_info",1);//创建publisher,往 "gps_info"话题上发布消息  gps_info就是topic的名称
   
   ros::Rate loop_rate(1);//定义发布的频率,1HZ

   while (ros::ok())    //循环发布msg
   {
     msg.x=msg.x*1.3;//处理msg
     msg.y=msg.y*1.1;//处理msg

     ROS_INFO("Talker_jone:GPS: x=%f , y=%f",msg.x,msg.y);//打印 要发布的信息
 
     pub.publish(msg); //发布消息

     loop_rate.sleep();//根据前面的定义的loop_rate,设置1s的暂停
   }
    return 0;
}

机器人上几乎所有的传感器,几乎都是按照固定频率发布消息这种通信方式来传输数据,只 是发布频率和数据类型的区别。

3、消息接收节点

源码如下

#include <ros/ros.h>
#include <topic_demo_jone/gps.h>
#include <std_msgs/Float32.h>

void gpsCallback(const topic_demo_jone::gps::ConstPtr &msg )
{
     std_msgs::Float32 distance;    //计算离原点(0,0)的距离
     distance.data=sqrt(pow(msg->x,2) + pow(msg->y,2));
     
     ROS_INFO( "Listener :Distance to origin = %f , state = %s"  ,distance.data,  msg->state.c_str() ); //打印计算的距离  和msg中的state            
}

int main(int argc, char ** argv)
{
    ros::init(argc, argv, "listener_jone");
    
    ros::NodeHandle nh ;

    ros::Subscriber sub = nh.subscribe("gps_info", 1, gpsCallback);    //设置回调函数gpsCallb ack

    ros::spin();//ros::spin()用于调用所有可触发的回调函数,将进入循环,不会返回,类似于在循环里反复 调用spinOnce()            //而ros::spinOnce()只会去触发一次

    return 0;
}

在topic接收方,有一个比较重要的概念,就是回调(CallBack),回调就是预先 给gps_info 话题传来的消息准备一个回调函数,你事先定义好回调函数的操作,计算到原点的距离。只有当有消息来时,回调函数才会被触发执行。具体去触发的命令就是ros::spin() ,它会反复的查看有没有消息来,如果有就会让回调函数去处理。
因此千万不要认为,只要指定了回调函数,系统就回去自动触发,你必须 ros::spin()或 者ros::spinOnce()才能真正使回调函数生效。

3、CMakeLists.txt文件修改

在 CMakeLists.txt 添加以下内容,生成可执行文件

add_executable(talker_jone src/talker.cpp )      #生成可执行文件talker_jone  节点的名字
add_dependencies(talker_jone topic_demo_generate_messages_cpp)   #必须添加add_dependencies,否则找不到自定义的msg产生的头文件
target_link_libraries(talker_jone ${catkin_LIBRARIES})

add_executable(listener_jone src/listener.cpp )      #生成可执行文件listener 
add_dependencies(listener_jone topic_demo_generate_messages_cpp)
target_link_libraries(listener_jone ${catkin_LIBRARIES})

4、编译运行

回到工作空间
运行指令 ,进行编译

catkin_make

之后运行ros

roscore

然后运行talker_jone 节点

rosrun topic_demo_jone talker_jone

然后运行listener_jone 节点

rosrun topic_demo_jone listener_jone

结果如下 x,y逐渐增大 不断向外发送
在这里插入图片描述

操作命令

在实际应用中,应该熟悉topic的几种使用命令,列出各自的命令及其作 用。
命令 ————————作用
rostopic list 列出当前所有的topic
rostopic info topic_name 显示某个topic的属性信息
rostopic echo topic_name 显示某个topic的内容
rostopic pub topic_name ... 向某个topic发布内容
rostopic bw topic_name 查看某个topic的带宽
rostopic hz topic_name 查看某个topic的频率
rostopic find topic_type 查找某个类型的topic
rostopic type topic_name 查看某个topic的类型(msg)

以刚写的例子进行测试

rostopic list

列出了当前运行的topic 看到了刚写的 gps_info
在这里插入图片描述

 rostopic info /gps_info

看到gps_info 的信息 发布者,订阅者
在这里插入图片描述

rostopic echo /gps_info 

看到topic 的内容
在这里插入图片描述

实操遇到的问题汇总(关于ROS topic)

double类型数据不能创建

相关实践学习
Docker镜像管理快速入门
本教程将介绍如何使用Docker构建镜像,并通过阿里云镜像服务分发到ECS服务器,运行该镜像。
阿里云资源编排ROS使用教程
资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。编排模板同时也是一种标准化的资源和应用交付方式,并且可以随时编辑修改,使基础设施即代码(Infrastructure as Code)成为可能。 产品详情:https://www.aliyun.com/product/ros/
相关文章
|
9月前
|
存储 缓存 算法
【ROS】如何让ROS中节点获取数据 III --参数服务器通信及ros常用工具指令介绍
相较于之前的通信模型,参数服务器是最为简单的。在之前的模型中,ROSMASTER都是扮演一个帮二者连接在一起的桥梁。
198 0
|
6天前
|
机器人 C++ Python
[ROS2] --- 通信接口
[ROS2] --- 通信接口
[ROS2] --- 通信接口
|
6天前
|
传感器
[ROS2] --- topic
[ROS2] --- topic
37 0
|
8月前
|
存储 API C++
ROS Topic 相关API接口与命令行介绍
ROS Topic 相关API接口与命令行介绍
351 0
|
9月前
|
XML 机器人 C++
【4. ROS的主要通讯方式:Topic话题与Message消息】(2)
【4. ROS的主要通讯方式:Topic话题与Message消息】(2)
157 0
|
9月前
|
传感器 机器人 C++
【4. ROS的主要通讯方式:Topic话题与Message消息】(1)
【4. ROS的主要通讯方式:Topic话题与Message消息】(1)
216 0
|
9月前
|
算法 C语言 C++
【ROS】服务通信、话题通信的应用
现在可以直接使用键盘来控制乌龟运动了
73 0
|
9月前
|
算法 中间件 C语言
【ROS】如何让ROS中节点实现数据交换Ⅱ --服务通信
在ros中,一个节点想要获取某种服务(例如:一个节点想要获取此时的相机数据,节点就需要向相机发送一个请求,而相机接收到请求后可以根据消息类型将数据类型返回),这就是基本的服务通信使用场景。
102 0
|
9月前
|
消息中间件 算法 机器人
【ROS】如何让ROS中节点实现数据交换Ⅰ--ROS话题通信
比较常用的目前就这一些,之后的命令现用现学就好了
179 1
|
9月前
|
Ubuntu 机器人 定位技术
ros_gazebo/turtlebot3 室内仿真导航,提取camera/image和pose位姿真值,并将topic 时间同步对齐,最后制作成kitti 格式的数据集。
ros_gazebo/turtlebot3 室内仿真导航,提取camera/image和pose位姿真值,并将topic 时间同步对齐,最后制作成kitti 格式的数据集。
269 0

推荐镜像

更多