ROS手动编写消息发布器和订阅器topic demo(C++)

1.首先创建 package

cd ~/catkin_ws/src

catkin_create_pkg topic_demo roscpp rospy std_msgs

2. 编写 msg 文件

cd topic_demo

mkdir msg

cd msg

vim gps.msg

将以下代码写入:

float32 x
float32 y
string state
 

x 是横坐标,y 是纵坐标,state 是状态

还记得以前说的吗:点击打开链接

修改 package.xml 文件:

<build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>

其中 exec_time 也可能是 run_time,看原来的 package.xml 怎么写的。

修改 CMakeLists.txt:

接下来进入工作空间:

cd ~/catkin_ws

编译:

catkin_make
 

如果类似这样就说明成功了。

进入 devel/include/

cd devel/include/

可以看到有我们的程序包名:

进入,可以看到生成的:

3. 编写 talker.cpp

进入 package 下的 src 目录:

cd ~/catkin_ws/src/topic_demo/src

创建 talker.cpp

vim talker.cpp

将以下代码写入:

#include <ros/ros.h>                         //类似 C 语言的 stdio.h 
#include <topic_demo/gps.h>                  //要用到 msg 中定义的数据类型

int main(int argc,char **argv){    
   ros::init(argc,argv,"talker");            //解析参数,命名节点为 talker
   ros::NodeHandle nh;                       //创建句柄,相当于一套工具,可以实例化 node,并且对 node 进行操作
   topic_demo::gps msg;                      //创建 gps 消息
   msg.x = 1.0;                              //设置 x 初值
   msg.y = 1.0;                              //设置 y 初值
   msg.state = "working";                    //设置 state 初值
   ros::Publisher pub = nh.advertise<topic_demo::gps>("gps_info",1);//创建 publisher 对象
   ros::Rate loop_rate(1.0);                 //创建 rate 对象,定义循环发布的频率,1 HZ
   while(ros::ok()){                         //只要没有关闭,一直循环
      msg.x = 1.03 * msg.x;                  //以指数增长,每隔 1s
      msg.y = 1.01 * msg.y;
      ROS_INFO("Talker:GPS: x = %f,y = %f",msg.x,msg.y); //打印函数,类似 printf()
      pub.publish(msg);                      //发布消息
      loop_rate.sleep();                     //根据定义的发布频率,sleep
   }
   return 0;
}
 

其中 nh.advertise<topic_demo::gps>("gps_info",1);

advertise<topic_demo::gps> 是一个函数模板,<topic_demo::gps> 是将其类型定为 gps 类型,这个函数有两个参数,第一个是 topic 名称,消息在 publisher 上会先存在一个消息队列中,第二个参数决定了消息队列的长度。

保存退出,创建 listener.cpp

vim listener.cpp
 

将以下代码写入:

#include <ros/ros.h>
#include <topic_demo/gps.h>
#include <std_msgs/Float32.h>   //ROS自带的浮点类型,类似 float,但是不同

void gpsCallback(const topic_demo::gps::ConstPtr &msg){   //回调函数,参数类型为 ConstPtr 类型的指针,它被定义在之前编译生成的 gps.h 中,指向 gps 的消息
   std_msgs::Float32 distance;                 //声明一个距离变量 distance
   distance.data = sqrt(pow(msg->x,2)+pow(msg->y,2));  //之所以是 distance.data,是因为 Floa32 是一个结构体,成员变量 data 才存储着值
   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;
   ros::Subscriber sub = n.subscribe("gps_info",1,gpsCallback);  //
   ros::spin();
   return 0;
}

n.subscribe(),第一个参数指明需要监听哪个 topic,第二个是 subscribe 的消息队列长度,第三个参数一般是个指针,指向了处理此消息的回调函数。也就是你希望对接收到的消息进行怎么样的处理,都写在第三个参数所指向的函数中。

目前的工作已经完成的差不多了,最后

4. 修改 CMakeLists.txt

将以下语句加入

保存退出

5. 编译运行

启动 master

roscore

进入工作空间

cd ~/catkin_ws
 

编译

catkin_make

分别运行

rosrun topic_demo talker 

rosrun topic_demo listener

运行结果:

原文地址:https://www.cnblogs.com/NikkiNikita/p/9450736.html