一、发布自带的库里面的msg
此时我们只需要创建发布对象;
ros::Publisher 自定义发布对象
ros::Publisher pub = n.advertise<std_msgs::String>("topic",10);
<std::msgs::String>表示范型;
topic:自定义
10:表示最多缓存10条,增加一条消息要删除前面的一条
编写发布逻辑;
包名::结构体名 实例化结构体对象
设置发布频率;
为了验证发布是否正确,用ROS_INFO();将发布的消息打印出来;
以下是发布的std_msgs::String 类型的消息的示例:
#include"ros/ros.h"
#include"std_msgs/String.h"
int main(int argc,char ** argv)
{
//设置编码,防止中文出现乱码
setlocale(LC_ALL,"");
//初始化节点
ros::init(argc,argv,"haha01");
//初始化节点句柄
ros::NodeHandle n;
//创建发布对象
ros::Publisher pub = n.advertise<std_msgs::String>("fang",10);
//编写发布逻辑
std_msgs::String msg;
//设置发布频率,1表示1秒发布一次
ros::Rate rate(1);
int count = 0;
while(ros::ok())
{
count++;
//使用std::stringstream 拼接字符串与编号
std::stringstream ss;
ss <<"hello"<< count;
msg.data = ss.str();
//发布消息
pub.publish(msg);
//加入调试,打印消息
ROS_INFO("发布的数据是: %s",ss.str().c_str());
rate.sleep();
}
//ROS_INFO("hello world");
return 0;
}
二、订阅发布的消息
创建订阅对象;
编写回调函数(回调函数是为了处理订阅到的数据);
以下是订阅刚才发布的消息的示例:ConstPtr&表示拿到的消息的常量指针的引用
#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());
}
int main(int argc,char ** argv)
{
setlocale(LC_ALL,"");
ros::init(argc,argv,"hear01");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe<std_msgs::String>("fang",10,doMsg);
ros::spin();
return 0;
}
CMakeLists修改:
我是把发布方和订阅方都放在了一个src下,所以下图对应的add_executable里面的节点名字要改成自己定义的,否则就会报错,因为如果不改的话,就会生成以包名开头的节点,而又添加了其他的可执行文件,就会发生冲突。
add_executable(${PROJECT_NAME}_node src/haha01.cpp src/hear01.cpp src/demo03.cpp src/demo04.cpp )
如果写成该形式,则会报main函数多次定义;
xml文件不用修改;
三、发布自定义的msg
首先要在包下创建一个msg文件夹,然后创建自定义的msg结构体,下图是本人创建的结构体示例:
此时我们需要创建发布对象;
编写发布逻辑;
设置发布频率;
!头文件要包含刚才的结构体,采用#include"包名/结构体.h"
发布自定义msg示例如下,此时没有打印输出发布的消息,可以自行加入,方法同上:
#include"ros/ros.h"
#include"std_msgs/String.h"
#include"bag/person.h"
int main(int argc,char **argv)
{
setlocale(LC_ALL,"");
ros::init(argc,argv,"demo03");
ros::NodeHandle n;
ros::Publisher pub = n.advertise<bag::person>("chatter",10);
bag::person per;
per.name = "zhangsan";
per.age = 16;
per.height = 178;
ros::Rate rate(1);
while (ros::ok())
{
pub.publish(per);
rate.sleep();
/* code */
}
return 0;
}
四、订阅发布的自定义msg
创建订阅对象
创建订阅对象的时候,我们可以不写范型,直接写topic,它会自动搜索;
ros::Subscriber sub = n.subscribe("chatter",10,doperson);
编写回调函数
以下是订阅上面发布的自定义消息的示例:
#include"ros/ros.h"
#include"std_msgs/String.h"
#include"bag/person.h"
void doperson(const bag::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::init(argc,argv,"demo04");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("chatter",10,doperson);
ros::spin();
return 0;
}
因为有自定义msg,所以CMakeLists需要进行更多的配置,
同样xml文件也要进行简单的修改:
完成上述配置之后就可以编译了,然后运行相应的节点就可以查看效果了。