当前位置 博文首页 > qq_36498362的博客:ROS学习笔记九:topic写法

    qq_36498362的博客:ROS学习笔记九:topic写法

    作者:[db:作者] 时间:2021-09-05 22:12

    topic_demo

    功能描述:两个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
    在这里插入图片描述

    cs
    下一篇:没有了