2.1 话题通信 · Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程
042话题通信(C++)3_订阅方实现_Chapter2-ROS通信机制_哔哩哔哩_bilibili
1.新建demo02_sub.cpp文件,搭建框架
头文件有红色的话,编译一下就没红了
2.包含头文件
3.初始化ROS节点
cuiHua——节点名称,具有唯一性
4.创建节点句柄
5.创建订阅者对象
doMsg——回调函数
fang——话题名称
6.处理订阅到的数据
main函数外
doMsg参数是订阅到的数据,传入的是const修饰的std_msgs::String类型的常量指针引用
ROS_INFO打印函数,msg是指针的引用,通过箭头调用data,打印是c封装的字符串因此.c_str
需要打印中文,因此添加该函数:
7.spin()函数
因为main函数是从头依次执行,在执行到27行时,有回调函数,回调函数每订阅一次就执行一次,main函数依次执行只能执行一次,因此需要spin加入回头再次调用回调函数
8.配置文件
9.编译(ctrl+shift+B)
10.运行
roscore
发布数据
订阅数据
注意:两个终端都先进入demo03文件夹中,两个终端都需要
source ./devel/setup.bash
11.结果
12.全代码
流程:
- 编写发布方实现;
- 编写订阅方实现;
- 编辑配置文件;
- 编译并执行。
发布方:
/*
需求: 实现基本的话题通信,一方发布数据,一方接收数据,
实现的关键点:
1.发送方
2.接收方
3.数据(此处为普通文本)
PS: 二者需要设置相同的话题
消息发布方:
循环发布信息:HelloWorld 后缀数字编号
实现流程:
1.包含头文件
2.初始化 ROS 节点:命名(唯一)
3.实例化 ROS 句柄
4.实例化 发布者 对象
5.组织被发布的数据,并编写逻辑发布数据
*/
// 1.包含头文件
#include "ros/ros.h"
#include "std_msgs/String.h" //普通文本类型的消息
#include <sstream>
int main(int argc, char *argv[])
{
//设置编码
setlocale(LC_ALL,"");
//2.初始化 ROS 节点:命名(唯一)
// 参数1和参数2 后期为节点传值会使用
// 参数3 是节点名称,是一个标识符,需要保证运行后,在 ROS 网络拓扑中唯一
ros::init(argc,argv,"talker");
//3.实例化 ROS 句柄
ros::NodeHandle nh;//该类封装了 ROS 中的一些常用功能
//4.实例化 发布者 对象
//泛型: 发布的消息类型
//参数1: 要发布到的话题
//参数2: 队列中最大保存的消息数,超出此阀值时,先进的先销毁(时间早的先销毁)
ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10);
//5.组织被发布的数据,并编写逻辑发布数据
//数据(动态组织)
std_msgs::String msg;
// msg.data = "你好啊!!!";
std::string msg_front = "Hello 你好!"; //消息前缀
int count = 0; //消息计数器
//逻辑(一秒10次)
ros::Rate r(1);
//节点不死
while (ros::ok())
{
//使用 stringstream 拼接字符串与编号
std::stringstream ss;
ss << msg_front << count;
msg.data = ss.str();
//发布消息
pub.publish(msg);
//加入调试,打印发送的消息
ROS_INFO("发送的消息:%s",msg.data.c_str());
//根据前面制定的发送贫频率自动休眠 休眠时间 = 1/频率;
r.sleep();
count++;//循环结束前,让 count 自增
//暂无应用
ros::spinOnce();
}
return 0;
}
订阅方:
/*
需求: 实现基本的话题通信,一方发布数据,一方接收数据,
实现的关键点:
1.发送方
2.接收方
3.数据(此处为普通文本)
消息订阅方:
订阅话题并打印接收到的消息
实现流程:
1.包含头文件
2.初始化 ROS 节点:命名(唯一)
3.实例化 ROS 句柄
4.实例化 订阅者 对象
5.处理订阅的消息(回调函数)
6.设置循环调用回调函数
*/
// 1.包含头文件
#include "ros/ros.h"
#include "std_msgs/String.h"
void doMsg(const std_msgs::String::ConstPtr& msg_p){
ROS_INFO("我听见:%s",msg_p->data.c_str());
// ROS_INFO("我听见:%s",(*msg_p).data.c_str());
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
//2.初始化 ROS 节点:命名(唯一)
ros::init(argc,argv,"listener");
//3.实例化 ROS 句柄
ros::NodeHandle nh;
//4.实例化 订阅者 对象
ros::Subscriber sub = nh.subscribe<std_msgs::String>("chatter",10,doMsg);
//5.处理订阅的消息(回调函数)
// 6.设置循环调用回调函数
ros::spin();//循环读取接收的数据,并调用回调函数处理
return 0;
}