当前位置 博文首页 > qq_36498362的博客:ROS学习笔记九:topic写法
功能描述:两个node,一个发布模拟的GPS消息(格式为自定义,包括坐标和工作状态),另一个接收并处理该信息(计算到原点的距离)
步骤:
1.package
2.msg
3.talker.cpp
4.listener.cpp
5.CMakeList.txt&package.xml
1.package
cd ~ /catkin_ws/src
catkin_create_pkg topic_demo roscpp rospy std_msgs
2.msg
cd topic_demo/
mkdir msg
cd msg
vi gps.msg
gps.msg(包括坐标、状态)
float32 x
float32 y
string state
编译之后生成对应的头文件 ~/catkin_ws/devel/include/topic_demo/gps.h
3.talker.cpp
//ROS头文件
#include <ros/ros.h>
//自定义msg产生的头文件
#include <topic_demo/gps.h>
int main(int argc, char **argv)
{
//用于解析ROS参数,第三个参数为本节点名
ros::init(argc, argv, "talker");
//实例化句柄,初始化node,句柄提供一套工具来对node进行操作,比如创建publisher
ros::NodeHandle nh;
//自定义gps msg
topic_demo::gps msg;
//初始化msg的值
msg.x = 1.0;
msg.y = 1.0;
msg.state = "working";
//创建publisher,第一个参数是publish的topic名称,第二个参数是消息在publish时存储的队列长度
ros::Publisher pub = nh.advertise<topic_demo::gps>("gps_info", 1);
//定义发布的频率
ros::Rate loop_rate(1.0);
//循环发布msg
while (ros::ok())
{
//以指数增长,每隔1秒更新一次
msg.x = 1.03 * msg.x ;
msg.y = 1.01 * msg.y;
ROS_INFO("Talker: GPS: x = %f, y = %f ", msg.x ,msg.y);
//以1Hz的频率发布msg
pub.publish(msg);
//根据前面定义的频率, sleep 1s
loop_rate.sleep();//根据前面的定义的loop_rate,设置1s的暂停
}
return 0;
}
思路:首先ros::init初始化,然后创建一个句柄,使用NodeHandle提供的advertise方法创建一个publisher,然后使用这个publisher往需要的topic上不停地发送自定义的message,用while循环实现周期性地发布。
4.listener.cpp
//ROS头文件
#include <ros/ros.h>
//包含自定义msg产生的头文件
#include <topic_demo/gps.h>
//ROS标准msg头文件
#include <std_msgs/Float32.h>
//传入参数是一个常指针,指向topic_demo::gps的消息
void gpsCallback(const topic_demo::gps::ConstPtr &msg)
{
//计算离原点(0,0)的距离
std_msgs::Float32 distance;
distance.data = sqrt(pow(msg->x,2)+pow(msg->y,2));
//float distance = sqrt(pow(msg->x,2)+pow(msg->y,2));
ROS_INFO("Listener: Distance to origin = %f, state: %s",distance.data,msg->state.c_str());
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle n;
//调用句柄的subscribe创建一个Subscriber,第一个参数是监听的topic,与publisher的topic一样
//第二个参数是消息队列的长度,第三个参数是一个指针,指向处理这个消息的回调函数
ros::Subscriber sub = n.subscribe("gps_info", 1, gpsCallback);
//ros::spin()用于调用所有可触发的回调函数。将进入循环,不会返回,类似于在循环里反复调用ros::spinOnce()。
ros::spin();
return 0;
}
5.CMakeList.txt&package.xml
CMakeList.txt
package.xml