一、话题订阅方的实现(C++)
打开终端,cd到工作空间目录, 输入code .打开vscode
创建订阅者demo02_sub.cpp文件。
code:
#include "ros/ros.h"
#include "std_msgs/String.h"
#include<sstream>
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::init(argc,argv, "CuiHua");//初始化节点
ros::NodeHandle nh;//创建节点句柄
ros::Subscriber sub = nh.subscribe("fang",10,doMsg);//发布者对象
//话题“fang”与发布者话题一致
ros::spin();
return 0;
}
ctrl+shift+B 编译一下,没有报错则继续。
配置CMkeList.txt文件(和前面发布方操作保持一致)
修改如下
打开终端,先运行核心roscore;
小插曲
出现过这种报错,大致意思是已经有roscore在运行,可是关闭终端在打开还会警告,于是搜索了一下。
彻底关闭这些进程的方法:
终端输入
killall -9 roscore
killall -9 rosmaster
问题解决。
小插曲
配置环境变量
source ./devel/setup.bash
先运行发布者节点:
然后运行订阅者节点:
可以发现一个问题,翠花订阅到的数据 “不全面”, 体现在开头。
理解:发送前面的数据时,发布者还没在roscore注册完。
发布者:我消息发出去了,接没接到是你的问题0-0
解决:注册后,加入休眠ros::Duration(3).sleep();(休眠3秒钟)
达到延迟第一条数据的发送。
修改代码后,编译并运行,结果如下:
演示完结。
二、ROS中回调函数与Spin()的理解
ros::spin() 函数使用起来比较简单,一般在主程序的最后,添加语句。
ros::Subscriber sub = n.subscribe( " chatter " , 1000 , chatterCallback);
/**
* ros::spin() 会一直调用回调函数chatterCallback(),一次调用1000条数据。
* 当用户输入Ctrl+C或ROS主进程关闭时,退出。
*/
ros::spin();
ros::spin()行是节点开始读取主题和在消息到达时,回调函数 messageCallback被调用的主循环。当用户按Ctrl+C组合键时,节点会退出消息循环,于是循环结束。
找到的一个相关教程:
(有待学习并掌握的知识点)
when we call ros::spin(), it keeps taking the callback from the callback queue and executing them one by one in an infinite loop (acting as a “spinning” thread).
The first version of the listener node implementation looks like below.
订阅者代码的模版
#include "ros/ros.h"
#include "std_msgs/String.h"
void ChatterCallback(const std_msgs::String::ConstPtr& msg) {
ROS_INFO(" I heard: [%s]", msg->data.c_str());
}
int main(int argc, char **argv) {
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("chatter", 1, ChatterCallback);
ros::spin();
return 0;
}
对C中回调函数的理解
参考文档
目前对spin()及回调函数的理解还很模糊,有待后续补充。
三、自定义消息类型(开坑)
官方文档自定义消息教程
.msg 文件分为 2部分:fields and constants.(字段和常量)
官方注释:
Fields are the data that is sent inside of the message.
Constants define useful values that can be used to interpret those fields (e.g. enum-like constants for an integer value).
大致流程:
1.按照固定格式创建 msg 文件
2.编辑配置文件
2.编译生成可以被 Python 或 C++ 调用的中间文件
明天实操
四、package.xml
该文件定义了有关包的属性,例如包名称、版本号、作者、维护者以及对其他 catkin 包的依赖关系。
1.基本结构:
< package >
< /package >
2.required tags:
< name > The name of the package
< version > The version number of the package (required to be 3 dot-separated integers)
< description > A description of the package contents
< maintainer > The name of the person(s) that is/are maintaining the package
< license > The software license(s) (e.g. GPL, BSD, ASL) under which the code is released.
3.构建、运行和测试依赖项
< buildtool_depend >
< build_depend >
< run_depend >
< test_depend >