网站如何做进一步优化免费网站建设源码
【4. ROS的主要通讯方式:Topic话题与Message消息】
- 1. 前言
 - 1.1 王者解释结点通讯:
 - 1.2 通讯小结
 
- 2. 灵活的Topic话题图解
 - 2.1 话题注意细节
 - 2.2 外延补充
 
- 3. Message消息图解
 - 3.1 消息类型
 - 3.2 查看标准消息类型`std_msgs`
 
- 4. 使用C++实现Publisher发布者
 - 4.1 发布者的实现
 - 4.2 消息分析
 - 4.3 `chao_node.cpp`源程序
 - 4.4 运行调试chao_node节点
 
- 5. 复制节点yao_node
 - 5.1 修改C++源代码
 - 5.2 修改CMakeLists.tet文件
 - 5.3 运行调试yao_node节点
 
- 6. 使用C++实现Subscriber订阅者
 - 6.1 创建订阅者节点
 - 6.2 消息分析
 - 6.3 添加chao_node节点的订阅
 - 6.4 修改CMakeLists.tet文件
 - 6.5 运行调试ma_node
 - 6.6 调整和优化
 - 6.7 添加yao_node节点的订阅
 - 6.8 rqt_graph查看节点消息流
 - 6.9 小结
 
- 7. 使用launch文件启动多个ROS节点
 - 7.1 使用launch文件启动节点
 - 7.2 编写运行launch文件
 - 7.3 调试launch文件
 - 7.4 launch小结
 
- 8. 使用Python编写Publisher发布者节点
 - 8.1 订阅者节点的Python实现
 - 8.2 编写chao_node.py代码
 - 8.3 py文件添加可执行的权限
 - 8.4 运行调试chao_node.py
 - 8.5 编写yao_node.py代码
 - 8.6 运行调试yao_node.py
 
- 9. 使用Python实现Subscriber订阅者
 - 9.1 创建订阅者节点
 - 9.2 编写ma_node.py代码
 - 9.3 py文件添加可执行的权限
 - 9.4 运行调试ma_node
 - 9.5 添加yao_node节点的订阅
 - 9.6 编写launch启动文件
 - 9.7 运行调试
 - 9.8 rqt_graph查看节点消息流
 
- 10. 总结
 

1. 前言
本教程是B站阿杰视频的笔记
 视频地址:https://www.bilibili.com/video/BV1qa41137ED
 
1.1 王者解释结点通讯:
- 话题topic
 - 发布者publisher
 - 订阅者subsciber

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

2.1 话题注意细节

2.2 外延补充
- —个ROS节点网络中,可以同时存在多个话题。
 - 一个话题可以有多个发布者也可以有多个订阅者。
 - 一个节点可以对多个话题进行订阅,也可以发布多个话题。
 - 不同的传感器消息通常会拥有各自独立话题名称,每个话题只有一个发布者。
 - 机器人速度指令话题通常会有多个发布者,但是同一时间只能有一个发言人。
 
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 


 小结
- 确定话题名称和消息类型。
 - 在代码文件中include消息类型对应的头文件。
 - 在main函数中通过NodeHandler大管家发布一个话题并得到消息发送对象。
 - 生成要发送的消息包并进行发送数据的赋值。
 - 调用消息发送对象的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 小结
- 确定话题名称和消息类型。
 - 在代码文件中include <ros.h>和消息类型对应的头文件。
 - 在main函数中通过NodeHandler大管家订阅一个话题并设置消
息接收回调函数。 - 定义一个回调函数,对接收到的消息包进行处理。
 - 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小结
- 使用launch文件,可以通过roslaunch指令一次启动多个节点。
 - 在launch文件中,为节点添加
output="screen”属性,可以让节点信息输出在终端中。(ROS_WARN不受该属性控制) - 在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消息,接下来会介绍机器人的运动操作。完美撒花!
