【4. ROS的主要通讯方式:Topic话题与Message消息】

在这里插入图片描述

1. 前言

本教程是B站阿杰视频的笔记
视频地址:https://www.bilibili.com/video/BV1qa41137ED
在这里插入图片描述

1.1 王者解释结点通讯:

  • 话题topic
  • 发布者publisher
  • 订阅者subsciber
    在这里插入图片描述

1.2 通讯小结

  1. 话题Topic是节点间进行持续通讯的一种形式。
  2. 话题通讯的两个节点通过话题的名称建立起话题通讯连接。3.话题中通讯的数据,叫做消息Message。
  3. 消息Message通常会按照一定的频率持续不断的发送,以保证消息数据的实时性。
  4. 消息的发送方叫做话题的发布者Pubplisher。
  5. 消息的接收方叫做话题的订阅者Subsciber。

2. 灵活的Topic话题图解

在这里插入图片描述

2.1 话题注意细节

在这里插入图片描述

2.2 外延补充

  1. —个ROS节点网络中,可以同时存在多个话题。
  2. 一个话题可以有多个发布者也可以有多个订阅者。
  3. 一个节点可以对多个话题进行订阅,也可以发布多个话题。
  4. 不同的传感器消息通常会拥有各自独立话题名称,每个话题只有一个发布者。
  5. 机器人速度指令话题通常会有多个发布者,但是同一时间只能有一个发言人。

3. Message消息图解

在这里插入图片描述

3.1 消息类型

ROS Index官网:https://index.ros.org/
在这里插入图片描述
搜索std_msgs
在这里插入图片描述
找到匹配的版本
在这里插入图片描述

3.2 查看标准消息类型std_msgs

选择Website,进入https://wiki.ros.org/std_msgs
在这里插入图片描述
下翻到 2.ROS Message Types

在这里插入图片描述
消息是嵌套的,由简单到复杂,类似C++的结构体

4. 使用C++实现Publisher发布者

在这里插入图片描述
这一期我们将按照这个场景来构建话题的发布者,一共有2个发布者,根据需求创建ssr_pkg包的chao_node和yao_node订阅节点

4.1 发布者的实现

打开之前创建的ssr_pkg,教程参照: 【初学ROS,年轻人的第一个Node节点】用VScode打开chao_node.cpp

在这里插入图片描述

4.2 消息分析

去ROS Index查找对应消息类型,进入https://wiki.ros.org/std_msgs,下翻到 2.ROS Message Types
在这里插入图片描述
超哥说的那句话不就是一个字符串吗
在这里插入图片描述

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

4.3 chao_node.cpp源程序

#include <ros/ros.h>
#include <std_msgs/String.h>
int main(int argc,char *argv[])
{
	ros::init(argc,argv,"chao_node" );
	printf("我的枪去而复返,你的生命有去无回!\n");
	ros::NodeHandle nh;
	ros::Publisher pub = nh.advertise<std_msgs ::String>("kuai_shang_che_kai_hei_qun", 10);
	ros::Rate loop_rate(10);
	while( ros::ok())
	{
		printf("我要开始刷屏了!\n");
		std_msgs::String msg;
		msg.data ="国服马超,带飞";
		pub.publish(msg);
		loop_rate.sleep();
	}
	return 0;
}

ctrl+s快捷保存
ctrl+shift+b快捷编译

4.4 运行调试chao_node节点

打开两个终端,分别运行两行代码

roscore
rosrun ssr_pkg chao_node

rostopic工具

rostopic list
rostopic echo /kuai_shang_che_kai_hei_qun
echo -e "\u56FD\u670D\u9A6C\u8D85\uFF0C\u5E26\u98DE"
rostopic hz /kuai_shang_che_kai_hei_qun

在这里插入图片描述

在这里插入图片描述
小结

  1. 确定话题名称和消息类型。
  2. 在代码文件中include消息类型对应的头文件。
  3. 在main函数中通过NodeHandler大管家发布一个话题并得到消息发送对象。
  4. 生成要发送的消息包并进行发送数据的赋值。
  5. 调用消息发送对象的publish()函数将消息包发送到话题当中。

在这里插入图片描述

5. 复制节点yao_node

chao_node.cpp复制到节点yao_node.cpp
在这里插入图片描述

5.1 修改C++源代码

#include <ros/ros.h>
#include <std_msgs/String.h>
int main(int argc,char *argv[])
{
	ros::init(argc,argv,"yao_node" );
	printf("过去生于未来!\n");
	ros::NodeHandle nh;
	ros::Publisher pub = nh.advertise<std_msgs ::String>("gie_gie_dai_wo", 10);
	ros::Rate loop_rate(10);
	while( ros::ok())
	{
		printf("我要开始刷屏了!\n");
		std_msgs::String msg;
		msg.data ="求上车+++";
		pub.publish(msg);
		loop_rate.sleep();
	}
	return 0;
}

ctrl+s快捷保存
ctrl+shift+b快捷编译

5.2 修改CMakeLists.tet文件

增加yao_node节点配置
在这里插入图片描述

add_executable(chao_node src/chao_node.cpp)
target_link_libraries (chao_node
	${catkin_LIBRARIES}
)
add_executable(yao_node src/yao_node.cpp)
target_link_libraries(yao_node
	${catkin_LIBRARIES}
)

5.3 运行调试yao_node节点

运行新节点前,需要保留下面两个终端

roscore
rosrun ssr_pkg chao_node
rosrun ssr_pkg yao_node

采用rostopic查看消息
rostopic工具

rostopic list
rostopic echo /gie_gie_dai_wo
echo -e "\u56FD\u670D\u9A6C\u8D85\uFF0C\u5E26\u98DE"
rostopic hz /gie_gie_dai_wo

在这里插入图片描述

6. 使用C++实现Subscriber订阅者

根据需求创建atr_pkg包的ma_node订阅节点
在这里插入图片描述

6.1 创建订阅者节点

创建Package软件包

  • 创建在~/catkin_ws/src文件夹里
  • catkin_create_pkg<包名><依赖项列表>
catkin_creat_pkg atr_pkg rospy roscpp std_msgs

在这里插入图片描述
新建src文件夹的ma_node.cpp文件
在这里插入图片描述

6.2 消息分析

在这里插入图片描述

6.3 添加chao_node节点的订阅

修改ma_node代码

#include <ros/ros.h>
#include <std_msgs/String.h>
void chao_callback(std_msgs::String msg)
{
	printf(msg.data.c_str());
	printf("\n");
}
int main(int argc,char *argv[])
	ros::init(argc,argv,"ma_node" );
	ros::NodeHandle nh;
	ros::Subscriber sub = nh.subscribe("kuai_shang_che_kai_hei_qun",10,chao_callback);
	while ( ros::ok())
	{
		ros::spinOnce();
	}
return 0;

6.4 修改CMakeLists.tet文件

增加ma_node节点配置
在这里插入图片描述


add_executable(ma_node src/ma_node.cpp)
target_link_libraries(ma_node
	${catkin_LIBRARIES}
)

ctrl+s快捷保存
ctrl+shift+b快捷编译

6.5 运行调试ma_node

打开3个终端,分别运行3行代码

roscore
rosrun ssr_pkg chao_node
rosrun atr_pkg ma_node

在这里插入图片描述

在这里插入图片描述

6.6 调整和优化

修改ma_node节点,添加chao_node节点的订阅

ma_node.cpp源程序

#include <ros/ros.h>
#include <std_msgs/String.h>
void chao_callback(std_msgs::String msg)
{
	ROS_INFO(msg.data.c_str());

}
int main(int argc,char *argv[])
{
	setlocale(LC_ALL,"");
	ros::init(argc,argv,"ma_node" );
	ros::NodeHandle nh;
	ros::Subscriber sub = nh.subscribe("kuai_shang_che_kai_hei_qun",10,chao_callback);
	while ( ros::ok())
	{
		ros::spinOnce();
	}
	return 0;
}

在这里插入图片描述
打印如下
在这里插入图片描述
[]时间戳表示【格林尼治时间1970年1月1日0时0分0秒】距离现在多少秒。

6.7 添加yao_node节点的订阅

修改ma_node节点,添加yao_node节点的订阅

ma_node.cpp源程序

#include <ros/ros.h>
#include <std_msgs/String.h>
void chao_callback(std_msgs::String msg)
{
	ROS_INFO(msg.data.c_str());
}
void yao_callback(std_msgs::String msg)
{
	ROS_WARN(msg.data.c_str());
}
int main(int argc,char *argv[])
{
	setlocale(LC_ALL,"");
	ros::init(argc,argv,"ma_node" );
	ros::NodeHandle nh;
	ros::Subscriber sub = nh.subscribe("kuai_shang_che_kai_hei_qun",10,chao_callback);
	ros::Subscriber sub_2 = nh.subscribe("gie_gie_dai_wo",10,yao_callback);
	while ( ros::ok())
	{
		ros::spinOnce();
	}
	return 0;
}

在这里插入图片描述

打开4个终端,分别运行4行代码

roscore
rosrun ssr_pkg chao_node
rosrun ssr_pkg yao_node
rosrun atr_pkg ma_node

在这里插入图片描述

6.8 rqt_graph查看节点消息流

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

6.9 小结

  1. 确定话题名称和消息类型。
  2. 在代码文件中include <ros.h>和消息类型对应的头文件。
  3. 在main函数中通过NodeHandler大管家订阅一个话题并设置消
    息接收回调函数。
  4. 定义一个回调函数,对接收到的消息包进行处理。
  5. main函数中需要执行ros::spinOnce(),让回调函数能够响应接收到的消息包。

在这里插入图片描述

7. 使用launch文件启动多个ROS节点

7.1 使用launch文件启动节点

该文件类型是XML语法,类似http文本。
在这里插入图片描述
批量启动ros节点文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.2 编写运行launch文件

新建launch文件夹的kai_hei.launch文件
在这里插入图片描述
在这里插入图片描述
kai_he.launch源码

launch>
	<node pkg="ssr_pkg" type="yao_node" name="yao_node" />
	<node pkg="ssr_pkg" type="chao_node" name=" chao_node" />
	<node pkg="atr_pkg" type="ma_node" name="ma_node" output="screen"/>
</launch>

在这里插入图片描述

7.3 调试launch文件

运行下面指令,启动launch的三个节点

roslaunch atr_pkg kai_hei.launch

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

采用rqt_graph命令查看节点流图

在这里插入图片描述
修改kai_he.launch源码,添加launch-prefix=" gnome-terminal -e",开一个新终端运行显示chao_node节点

launch>
	<node pkg="ssr_pkg" type="yao_node" name="yao_node" />
	<node pkg="ssr_pkg" type="chao_node" name=" chao_node" launch-prefix=" gnome-terminal -e"/>
	<node pkg="atr_pkg" type="ma_node" name="ma_node" output="screen"/>
</launch>

在这里插入图片描述
运行下面指令,启动launch的三个节点

roslaunch atr_pkg kai_hei.launch

在这里插入图片描述

7.4 launch小结

  1. 使用launch文件,可以通过roslaunch指令一次启动多个节点。
  2. 在launch文件中,为节点添加output="screen”属性,可以让节点信息输出在终端中。(ROS_WARN不受该属性控制)
  3. 在launch文件中,为节点添加launch-prefix="gnome-terminal -e"属性,可以让节点单独运行在一个独立终端中。

在这里插入图片描述

8. 使用Python编写Publisher发布者节点

8.1 订阅者节点的Python实现

在这里插入图片描述
ctrl+alt+t打开终端,只需一次编译
创建python包

cd catkin_ws/src/
catkin_create_pkg ssr_pkg rospy std_msgs
cd ..
catkin_make

在这里插入图片描述
VScode打开,创建scripts
在这里插入图片描述
创建chao_node.py在这里插入图片描述

8.2 编写chao_node.py代码

先引入python包,设置中文utf-8显示

  • ros>=20.04,采用python3
  • ros<20.04,采用python

在这里插入图片描述
对比学习C++发布节点
在这里插入图片描述
在这里插入图片描述
NodeHandle变为rospy

chao_node.py源码

#!/usr/bin/env python3
#coding=utf-8
import rospy
from std_msgs.msg import String
if _name__ == "_main_":
	rospy.init_node ( " chao_node ")
	rospy.logwarn("我的枪去而复返,你的生命有去无回!")
	pub = rospy.Publisher( "kuai_shang_che_kai_hei_qun" ,String , queue_size=10)
	rate = rospy. Rate( 10)
	while not rospy.is_shutdown():
		rospy.loginfo("我要开始刷屏了")
		msg = String()
		msg.data =“国服马超,带飞"
		pub.publish(msg)
		rate.sleep(

在这里插入图片描述

8.3 py文件添加可执行的权限

在这里插入图片描述
在所在文件夹打开终端

chmod +x chao_node.py

8.4 运行调试chao_node.py

打开两个终端分别运行两条指令

roscore
rosrun ssr_pkg chao_node.py

在这里插入图片描述
rostopic工具

rostopic list
rostopic echo /kuai_shang_che_kai_hei_qun
echo -e "\u56FD\u670D\u9A6C\u8D85\uFF0C\u5E26\u98DE"


在这里插入图片描述
python前面经过第一次编译,后期不需要编译可以直接运行,也不需要CMake文件配置

8.5 编写yao_node.py代码

直接复制chao_node.py改为yao_node.py,权限也会一起传递
在这里插入图片描述
yao_node.py源码

#!/usr/bin/env python3
#coding=utf-8
import rospy
from std_msgs.msg import String
if _name__ = "__main_":
	rospy.init_node ( "yao_node")
	rospy.logwarn("过去生于未来! ")
	pub = rospy. Publisher( "gie_gie_dai_wo" ,String , queue_size=10)
	rate = rospy.Rate(10)
	while not rospy.is_shutdown():
		rospy.loginfo("我要开始刷屏了")
		msg = String()
		msg.data = "求上车+++"
		pub.publish(msg)
		rate.sleep()

8.6 运行调试yao_node.py

打开两个终端分别运行两条指令

roscore
rosrun ssr_pkg yao_node.py

在这里插入图片描述

rostopic工具

rostopic list
rostopic echo /gie_gie_dai_wo
echo -e "\u56FD\u670D\u9A6C\u8D85\uFF0C\u5E26\u98DE"


在这里插入图片描述

9. 使用Python实现Subscriber订阅者

根据需求创建atr_pkg包的ma_node订阅节点
在这里插入图片描述

9.1 创建订阅者节点

创建Package软件包

  • 创建在~/catkin_ws/src文件夹里
  • catkin_create_pkg<包名><依赖项列表>
cd catkin_ws/src/
catkin_creat_pkg atr_pkg rospy std_msgs
cd ..
catkin_make

在这里插入图片描述

VScode打开,创建scripts文件夹,创建ma_node.py
在这里插入图片描述

9.2 编写ma_node.py代码

先引入python包,设置中文utf-8显示

  • ros>=20.04,采用python3
  • ros<20.04,采用python

在这里插入图片描述
对比学习C++发布节点
在这里插入图片描述

在这里插入图片描述

NodeHandle变为rospy

修改ma_node代码

#!/usr/bin/env python3
#coding=utf-8
import rospy
from std_msgs.msg import String
def chao_callback(msg):
	rospy. loginfo(msg.data)
ifname== "_main_":
	rospy.init_node ( "ma_node" )
	sub = rospy.Subscriber("kuai_shang_che_kai_hei_qun" ,String , chao_callback,queue_size=10)
	rospy.spin ()

在这里插入图片描述

9.3 py文件添加可执行的权限

在这里插入图片描述

在所在文件夹打开终端

chmod +x ma_node.py

9.4 运行调试ma_node

打开3个终端,分别运行3行代码

roscore
rosrun ssr_pkg chao_node.py
rosrun atr_pkg ma_node

在这里插入图片描述

9.5 添加yao_node节点的订阅

修改ma_node节点,添加yao_node节点的订阅

ma_node.py源程序

#!/usr/bin/env python3
#coding=utf-8
import rospy
from std_msgs.msg import String
def chao_callback(msg):
	rospy. loginfo(msg.data)
def yao_callback(msg):
	rospy. logwarn(msg.data)
ifname== "_main_":
	rospy.init_node ( "ma_node" )
	sub = rospy.Subscriber("kuai_shang_che_kai_hei_qun" ,String , chao_callback,queue_size=10)
	sub_2 = rospy.Subscriber("gie_gie_dai_wo" ,String , yao_callback,queue_size=10)
	rospy.spin ()

在这里插入图片描述

9.6 编写launch启动文件

新建launch文件夹的kai_hei.launch文件
在这里插入图片描述
kai_he.launch源码

launch>
	<node pkg="ssr_pkg" type="yao_node.py" name="yao_node" />
	<node pkg="ssr_pkg" type="chao_node.py" name=" chao_node" />
	<node pkg="atr_pkg" type="ma_node.py" name="ma_node" launch-prefix=" gnome-terminal -e"/>
</launch>

9.7 运行调试

打开2个终端,分别运行2行代码

roscore
roslaunch atr_pkg kai_hei.launch

在这里插入图片描述

9.8 rqt_graph查看节点消息流

打开一个终端,输入

rqt_graph

在这里插入图片描述

10. 总结

本节学习了ROS机器人的主要通讯方式,尝试C++和python两种语言编写Topic话题与Message消息,接下来会介绍机器人的运动操作。完美撒花!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2345VOR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值