• ROS话题通信案例(一)——发布者订阅者传递消息(C++)


    参考视频:【奥特学园】ROS机器人入门课程《ROS理论与实践》零基础教程_哔哩哔哩_bilibili

    参考文档:http://www.autolabor.com.cn/book/ROSTutorials/

    话题通信实现模型是比较复杂的,该模型如下图所示,该模型中涉及到三个角色:

    • ROS Master (管理者)
    • Talker (发布者)
    • Listener (订阅者)

    ROS Master 负责保管 Talker 和 Listener 注册的信息,并匹配话题相同的 Talker 与 Listener,帮助 Talker 与 Listener 建立连接,连接建立后,Talker 可以发布消息,且发布的消息会被 Listener 订阅。

    需求:

    编写发布订阅实现,要求发布方以10HZ(每秒10次)的频率发布文本消息,订阅方订阅消息并将消息内容打印输出。

    分析:

    在模型实现中,ROS master 不需要实现,而连接的建立也已经被封装了,需要关注的关键点有三个:

    1. 发布方
    2. 接收方
    3. 数据(此处为普通文本)

    流程:

    1. 编写发布方实现;
    2. 编写订阅方实现;
    3. 编辑配置文件;
    4. 编译并执行。

     1.发布方发布消息

    #include "ros/ros.h"
    #include "std_msgs/String.h"
    /*
        发布方实现:
            1.包含头文件;
              ROS中文本类型 ----> std_msgs/String.h
            2.初始化ROS节点;
            3.创建节点句柄;
            4.创建发布者对象;
            5.编写发布逻辑并发布数据v
    */
    
    int main(int argc, char  *argv[])
    {
        // 2.初始化ROS节点;
        ros::init(argc, argv,"erGouZi");
        // 3.创建节点句柄;
        ros::NodeHandle nh;
        // 4.创建发布者对象;
        ros::Publisher pub = nh.advertise<std_msgs::String>("House",10);
        // 5.编写发布逻辑并发布数据v
        //先创建被发布的消息
        std_msgs::String msg;
        //编写循环,循环中发布数据
        while(ros::ok())
        {
            msg.data="hello,I'm erGouZi";
            pub.publish(msg);
        }
    
        return 0;
    }

     配置

     执行

    1. ctrl+shift+B
    2. roscore
    3. cd 文件夹
    4. 编译source ./devel/setup.bash
    5. 运行rosrun 包  映射名

     打印出发布的消息并编号

    #include "ros/ros.h"
    #include "std_msgs/String.h"
    #include <sstream>
    /*
        发布方实现:
            1.包含头文件;
              ROS中文本类型 ----> std_msgs/String.h
            2.初始化ROS节点;
            3.创建节点句柄;
            4.创建发布者对象;
            5.编写发布逻辑并发布数据v
    */
    
    int main(int argc, char  *argv[])
    {
        setlocale(LC_ALL,"");
        // 2.初始化ROS节点;
        ros::init(argc, argv,"erGouZi");
        // 3.创建节点句柄;
        ros::NodeHandle nh;
        // 4.创建发布者对象;
        ros::Publisher pub = nh.advertise<std_msgs::String>("House",10);
        // 5.编写发布逻辑并发布数据;
        //要求以 10HZ 的频率发布数据,并且文本后添加编号
        //先创建被发布的消息
        std_msgs::String msg;
        //发布频率
        ros::Rate rate(10);
        //设置编号
        int count = 0;
        //休眠以防没注册完已发布数据
        ros::Duration(3).sleep();
        //编写循环,循环中发布数据
        while(ros::ok())
        {
            count++;
            //msg.data="hello,I'm erGouZi";
            //实现字符串凭借数字
            std::stringstream ss;
            ss << "hello ...>" <<count;
            msg.data = ss.str();
            pub.publish(msg);
            //添加日志
            ROS_INFO("发布的数据是:%s",ss.str().c_str());
            rate.sleep();
            ros::spinOnce();//官方建议,处理回调函数
        }
    
        return 0;
    }

     执行

     2.订阅者订阅消息

    #include "ros/ros.h"
    #include "std_msgs/String.h"
    /*
        订阅方实现:
            1.包含头文件;
              ROS中文本类型 ----> std_msgs/String.h
            2.初始化ROS节点;
            3.创建节点句柄;
            4.创建订阅方对象;
            5.处理订阅的数据。
            6.spin()函数
    */
    
    void doMsg(const std_msgs::String::ConstPtr &msg)
    {
      //通过msg获取并操作订阅到的数据
      ROS_INFO("翠花订阅的数据:%s",msg->data.c_str());
    }
    
    int main(int argc, char *argv[])
    {
      setlocale(LC_ALL,"");
      // 2.初始化ROS节点;
      ros::init(argc,argv,"cuiHua");
      // 3.创建节点句柄;
      ros::NodeHandle nh;
      // 4.创建订阅方对象;
      ros::Subscriber sub = nh.subscribe("House",10,doMsg);
      // 5.处理订阅的数据。
    
      ros::spin();
      
      return 0;
    }

     配置

     执行

    1. 编译
    2. 启动 roscore;
    3. 启动发布节点;
    4. 启动订阅节点。

     3.计算图

    命令行:rqt_graph

  • 相关阅读:
    windows10上安装 .NET Framework 3.5
    Mac上安装Tomcat服务器
    实验室中搭建Spark集群和PyCUDA开发环境
    训练实录
    Hello World
    存储管理
    java脚本实现selenium架构下的复选框、上传文件的操作
    java脚本,selenium工具,自动发QQ邮件
    用java脚本,selenium2.0工具,切换窗口经验总结
    六、排队论模型
  • 原文地址:https://www.cnblogs.com/caiyishuai/p/15002401.html
Copyright © 2020-2023  润新知