需求:
创建自定义消息,该消息包含人的信息:姓名、身高、年龄等。
流程:
- 按照固定格式创建 msg 文件
- 编辑配置文件
- 编译生成可以被 Python 或 C++ 调用的中间文件
1.定义msg文件
功能包下新建 msg 目录,添加文件 Person.msg
string name
uint16 age
float64 height
2.编辑配置文件
package.xml中添加编译依赖与执行依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
<!--
exce_depend 以前对应的是 run_depend 现在非法
-->
CMakeLists.txt编辑 msg 相关配置
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
# 需要加入 message_generation,必须有 std_msgs
## 配置 msg 源文件
add_message_files(
FILES
Person.msg
)
# 生成消息时依赖于 std_msgs
generate_messages(
DEPENDENCIES
std_msgs
)
#执行时依赖
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES demo02_talker_listener
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
3.编译
编译后的中间文件查看:
C++ 需要调用的中间文件(.../工作空间/devel/include/包名/xxx.h)
Python 需要调用的中间文件(.../工作空间/devel/lib/python3/dist-packages/包名/msg)
C++实现
需求:
编写发布订阅实现,要求发布方以10HZ(每秒10次)的频率发布自定义消息,订阅方订阅自定义消息并将消息内容打印输出。
分析:
在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:
- 发布方
- 接收方
- 数据(此处为自定义消息)
流程:
- 编写发布方实现;
- 编写订阅方实现;
- 编辑配置文件;
- 编译并执行
0.vscode 配置
为了方便代码提示以及避免误抛异常,需要先配置 vscode,将前面生成的 head 文件路径配置进 c_cpp_properties.json 的 includepath属性
"/xxx/yyy工作空间/devel/include/**" //配置 head 文件的路径
1.发布方
#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"
/*
发布者:发布人的消息
1.包含头文件;
2.初始化ROS节点
3.创建节点句柄
4.创建发布者对象
5.编写发布者逻辑,发布数据。
*/
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
ROS_INFO("这是消息发布方");
// 2.初始化ROS节点
ros::init(argc,argv,"banZhuanRen");
// 3.创建节点句柄
ros::NodeHandle nh;
// 4.创建发布者对象
ros::Publisher pub = nh.advertise<plumbing_pub_sub::Person>("Chat",10);
// 5.编写发布者逻辑,发布数据。
//5.1.被发布的数据
plumbing_pub_sub::Person person;
person.name = "张三";
person.age = 1;
person.height = 1.73;
//5.2.设置发布的频率
ros::Rate rate(1);
//5.3.循环发布数据
while (ros::ok())
{
//修改数据
person.age += 1;
//核心:数据发布
pub.publish(person);
ROS_INFO("发布的消息:%s,%d,%.2f",person.name.c_str(),person.age,person.height);
//休眠
rate.sleep();
//建议
ros::spinOnce();
}
return 0;
}
配置
执行
2.订阅方
#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"
/*
订阅方:订阅消息
1.包含头文件;
#include "plumbing_pub_sub/Person.h"
2.初始化ROS节点
3.创建节点句柄
4.创建订阅者对象
5.处理订阅的数据
6.调用spin()函数
*/
void doPerson (const plumbing_pub_sub::Person::ConstPtr& person){
ROS_INFO("订阅人的信息:%s,%d,%.2f",person->name.c_str(),person->age,person->height);
}
int main(int argc, char *argv[])
{
setlocale(LC_ALL,"");
ROS_INFO("订阅方实现");
// 2.初始化ROS节点
ros::init(argc,argv,"jiaZhang");
// 3.创建节点句柄
ros::NodeHandle nh;
// 4.创建订阅者对象
ros::Subscriber sub = nh.subscribe("Chat",10,doPerson);
// 5.处理订阅的数据
// 6.调用spin()函数
ros::spin();
return 0;
}