话题通信
话题通信是基于发布订阅模式的,即一个节点发布消息,另一个节点订阅该消息。
流程:编写发布方实现–编写订阅方实现–(用python实现时,为python文件编写可执行权限)–编写配置文件–编译执行
要求:编写发布订阅实现,要求发布以10Hz(每秒10次)的频率发布文本,订阅方订阅消息并将消息内容打印输出。
前期准备工作:创建一个ROS功能包–vscode中编译ros(修改.vscode/tasks.json 文件)
src目录下创建ros功能包、设置包名、添加依赖
话题发布
- C++实现
–>在ros功能包下的src目录新建demo01_pub.cpp文件(必要时修改 .vscode/c_cpp_properties.json文件)
发布者C++代码如下:
#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
/*
发布方实现:
1.包含头文件
ROS中文本类型 -->std_msgs/String.h
2.初始化ros节点
3.创建节点句柄;
4.创建发布者对象
5.编写发布逻辑并发布数据
*/
int main(int argc, char *argv[])
{
setlocale(LC_ALL,""); //防止中文乱码
//初始化ROS节点;
ros::init(argc,argv,"ergouzi");
//创建节点句柄;
ros::NodeHandle nh;
//创建发布者对象;
ros::Publisher pub = nh.advertise<std_msgs::String>("fang",10);
//编写发布逻辑并发布数据
//要求以 10Hz 的频率发布数据,并且文本后添加编号
//先创建被发布的消息
std_msgs::String msg;
//发布频率
ros::Rate rate(10);
//设置编号
int count = 0;
//编写循环,循环中发布数据
while (ros::ok())
{
count++;
//实现字符串拼接数字
std::stringstream ss;
ss << "hello --> " << count;
//msg.data = "hello";
msg.data = ss.str();
pub.publish(msg);
//添加日志;
ROS_INFO("发布的数据是:%s",ss.str().c_str());
rate.sleep();
}
return 0;
}
修改Cmakelist.txt文件并编译执行
执行:启动roscore
rosrun plumbing_pub_sub demo01_pub
发布话题完毕
2. Python实现
话题订阅
- C++实现
–>在ros功能包下的src目录新建demo02_sub.cpp文件(必要时修改 .vscode/c_cpp_properties.json文件)
订阅者C++代码如下:
#include "ros/ros.h"
#include "std_msgs/String.h"
/*
发布方实现:
1.包含头文件
ROS中文本类型 -->std_msgs/String.h
2.初始化ros节点
3.创建节点句柄;
4.创建订阅者对象
5.处理订阅的数据
6.声明一个spin()函数
*/
void doMsg(const std_msgs::String::ConstPtr &msg){
//通过msg获取并操作订阅到的数据
ROS_INFO("翠花订阅到的数据:%s",msg->data.c_str());
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
//初始化ros节点
ros::init(argc,argv,"cuihua");
//创建节点句柄;
ros::NodeHandle nh;
//创建订阅者对象
ros::Subscriber sub = nh.subscribe("fang",10,doMsg);
//处理订阅的数据
ros::spin();
return 0;
}
配置CMakeList.txt文件
执行:启动roscore
rosrun plumbing_pub_sub demo02_sub
话题订阅发布结果如下:
- Python实现
-
1.在功能包下新建scripts文件夹,新建文件demo01_pub_p.py
发布方代码:
#! /usr/bin/env python
#1.导包
import rospy
from std_msgs.msg import String
if __name__ == "__main__":
#2.初始化ROS节点:命名(唯一)
rospy.init_node("santai")
#3.实例化发布者对象
pub = rospy.Publisher("che",String,queue_size=10)
#4.组织被发布的数据,并编写逻辑发布数据
msg = String() #创建 msg 对象
msg_front = "hello"
count = 0 #计数器
# 设置循环频率
rate = rospy.Rate(10)
rospy.sleep(3)
while not rospy.is_shutdown():
count += 1
#拼接字符串
msg.data = msg_front + str(count)
pub.publish(msg)
rospy.loginfo("写出的数据:%s",msg.data)
rate.sleep()
-
2.在scripts目录下新建demo02_sub_p.py
订阅方实现:
#! /usr/bin/env python
#1.导包
import rospy
from std_msgs.msg import String
def doMsg(msg):
rospy.loginfo("I heard:%s",msg.data)
if __name__ == "__main__":
#2.初始化 ROS 节点:命名(唯一)
rospy.init_node("huahua")
#3.实例化订阅者对象
sub = rospy.Subscriber("che",String,doMsg,queue_size=10)
#4.处理订阅的消息(回调函数)
#5.设置循环调用回调函数
rospy.spin()
- 3.为python代码添加可执行权限
chmod +x *.py
ll
-
4.编译执行
启动roscore
启动发布节点:
source ./devel/setup.bash
rosrun plumbing_pub_sub demo01_pub_p.py
启动订阅节点:
source ./devel/setup.bash
rosrun plumbing_pub_sub demo02_sub_p.py
注:订阅者不能完全订阅发布者消息,解决办法:对发布代码加一行:rospy.sleep(3),休眠3秒钟