目录
- 新建消息文件
- 更改包xml文件中的依赖关系
- 更改cmakelist文件中的配置
- 执行时依赖
- 改变cmakelist
- 编译顺序
- 发布者程序
- 调用者程序
- 新建launch文件
- 程序测试
新建消息文件
在功能包目录下,新建msg文件夹,下面新建mymsg.msg文件,其内容为
string name
float64 value
发布者包含该消息,生成头文件,由发布者publisher包含该消息头文件即可
更改包xml文件中的依赖关系
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
<!--
exce_depend 以前对应的是 run_depend 现在非法
-->
更改cmakelist文件中的配置
新增了message_generation
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation
)
配置 msg 源文件
add_message_files(
FILES
mymsg.msg
)
执行时依赖
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES demo02_talker_listener
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)
改变cmakelist
新生成的.h文件位于devel/include文件夹下,在订阅及发布方的cmakelist中添加:
include_directories(
# include
${catkin_INCLUDE_DIRS}
"/root/work/ws/devel/include/"
)
这样工程才能找到生成的消息文件
编译顺序
编译时先编译带有自定义消息mymsg.msg的功能包,再编译整体的功能,其顺序不能出错,不然可能生成不了头文件
catkin_make --pkg publisher
catkin_make
发布者程序
// 1.包含头文件
#include "ros/ros.h"
#include "std_msgs/String.h" //普通文本类型的消息
#include <sstream>
#include "publisher/mymsg.h"
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<publisher::mymsg>("test",10);
int count = 0; //消息计数器
ros::Duration(0.5).sleep();
//这里是每秒通过一次,剩余时间则阻塞在下面的r.sleep
ros::Rate r(1);
//节点不死
while (ros::ok())
{
//使用 stringstream 拼接字符串与编号
publisher::mymsg msg;
msg.name="liu";
msg.value=count;
//发布消息
pub.publish(msg);
//加入调试,打印发送的消息
// ROS_INFO("发送的消息:%s",msg.data.c_str());
//根据前面制定的发送贫频率自动休眠 休眠时间 = 1/频率;
r.sleep();
count++;//循环结束前,让 count 自增
//暂无应用
ros::spinOnce();
}
return 0;
}
调用者程序
// 1.包含头文件
#include "ros/ros.h"
#include "std_msgs/String.h"
#include "publisher/mymsg.h"
//这里创建了回调函数,接收信息后传递的是std_msgs::String类型的常指针
void doMsg(const publisher::mymsg::ConstPtr& msg_p){
ROS_INFO("订阅信息:%s,%.2f", msg_p->name.c_str(), msg_p->value);
}
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<publisher::mymsg>("test",10,doMsg);
//5.处理订阅的消息(回调函数)
ros::spin();//循环读取接收的数据,并调用回调函数处理
return 0;
}
新建launch文件
两个包文件夹下新建launch目录,下有launch文件,以subscriber包为例
<launch>
<!-- screen表示输出到屏幕上 -->
<node pkg="subscriber" type="subscriber_node" name="listener" output="screen" />
</launch>
默认生成的cmakelist,节点可执行程序名为包名__node
程序测试
source ./devel/setup.bash
roslaunch subscriber start.launch
roslaunch publisher start.launch