• 【ROS入门】使用 ROS 话题(Topic)机制实现消息发布与订阅及launch文件的封装


    任务要求

    使用 ROS 话题(Topic)机制实现消息发布与订阅:

    • 创建一个发布者,每隔 100ms 依次发送斐波拉契数列的数字到话题/fibonacci 中;
    • 创建一个订阅者,订阅该话题,输出订阅结果。如,订阅者依次输出: 1 1 2 3 5 8…
    • 将发布者和订阅者分别封装成launch文件,并能成功实现上述功能

    话题模型

    在这里插入图片描述

    实现步骤

    创建工作空间并初始化

    $ mkdir -p ROS_Topic_Demo/src
    $ cd ROS_Topic_Demo
    $ catkin_make
    
    • 1
    • 2
    • 3

    上述命令,首先会创建一个工作空间以及一个 src 子目录,然后再进入工作空间调用 catkin_make命令编译。

    创建功能包并添加依赖

    在工作空间的src文件夹的目录下打开终端并创建功能包

    $ catkin_create_pkg ROS_Topic_Demo roscpp rospy std_msgs
    
    • 1

    创建发布者代码(C++)

    如何实现一个发布者:

    • 初始化ROS节点
    • 向 ROS Master注册节点信息,包括发布的话题名和话题中的消息类型
    • 创建消息数据
    • 按照一定频率循环发布消息

    在ROS_Topic_Demo下的src文件夹中创建一个cpp文件:

    $ touch topic_demo_pub_c.app
    
    • 1
    /*创建一个发布者,每隔 100ms 依次发送斐波拉契数列的数字到话题/fibonacci 中*/
    
    //1.头文件
    #include "ros/ros.h"    //万能头
    // #include "iostream"
    #include "std_msgs/String.h"    //普通文本类型的消息
    
    int main(int argc, char *argv[])
    {
        //设置编码(其实这行在这个任务里头没啥用,只不过拿来凑行数而已,应要说的话就是能在打印的时候看的更加清楚而已)。
        setlocale(LC_ALL,"");
    
        //2.初始化ROS节点
        //ros::init()函数需要查看 argc 和 argv,以便执行命令行提供的任何 ROS 参数和名称重映射。
        //参数1和参数2用于传参,参数3为节点名称,需要保持名称唯一
        ros::init(argc,argv,"Publisher");   
    
        //3.实例化ROS节点句柄
        //节点句柄用来管理ROS相关的api资源。调用api时,经常需要使用节点句柄进行调用。
        ros::NodeHandle n;  
    
        //4.实例化发布者对象
        //advertise()函数用于告诉ROS需要发布的主题名称。这将调用ROS Master节点,该节点将会记录谁在发布,谁在订阅。
        //调用 advertise() 后,Master节点会通知任何试图订阅该主题名称的节点,并进行配对。
        //advertise() 返回一个发布者对象,它允许您使用该对象通过调用 publish() 在该主题上发布消息。 
        //一旦返回的 Publisher 对象的所有副本都被销毁后,该主题将自动销毁。
        //第一个参数为话题名称,第二个参数为发布消息队列缓冲区的大小。
        ros::Publisher fibonacci_pub = n.advertise<std_msgs::String>("/fibonacci",100);
    
        //5.组织被发布的数据,并编写逻辑发布数据
        //数据(动态组织)
        std_msgs::String msg;
    
        int num = 1;
        int temp = 0;
    
        //设置循环频率
        ros::Rate time(10);
        ros::Rate time1(1);
    
        time1.sleep();	//确保发布的代码比订阅的代码晚运行,保证订阅者可以完整的订阅到发布者的信息,防止漏掉一开始的信息。
    
        while(ros::ok())
        {
            //发布消息
            std::stringstream ss;
            ss<<num;
            msg.data = ss.str();
            fibonacci_pub.publish(msg);
            //打印发送的消息
            ROS_INFO("发送数据:%s",msg.data.c_str());
            int former = num;
            num+=temp;
            temp=former;
            //设置休眠时间
            time.sleep();
        }
    
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    创建订阅方代码(C++)

    在ROS_Topic_Demo下的src文件夹中创建一个cpp文件:

    $ touch topic_demo_sub_c.app
    
    • 1
    //1.头文件
    #include "ros/ros.h"    
    #include "std_msgs/String.h" 
    
    //5.利用回调函数读取数据
    void callBack(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,"Subscriber");
    
        //3.实例化ROS节点句柄
        ros::NodeHandle n;
    
        //4.实例化发布者对象
        ros::Subscriber fibonacci_sub = n.subscribe<std_msgs::String>("/fibonacci",100,callBack);
    
        //6.设置循环调用回调函数
        ros::spin();    //循环读取接收的数据,并调用回调函数处理
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    配置CMakeLists.txt

    add_executable(topic_demo_pub_c src/topic_demo_pub_c.cpp)
    add_executable(topic_demo_sub_c src/topic_demo_sub_c.cpp)
    
    target_link_libraries(topic_demo_pub_c
      ${catkin_LIBRARIES}
    )
    
    target_link_libraries(topic_demo_sub_c
      ${catkin_LIBRARIES}
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    位置如图所示:

    在这里插入图片描述

    执行

    启动roscore

    $ roscore
    
    • 1

    在这里插入图片描述

    编译

    $ catkin_make
    
    • 1

    在这里插入图片描述

    启动发布和订阅节点

    $ source ./devel/setup.bash
    $ rosrun rosrun topic_demo topic_demo_sub_c
    
    • 1
    • 2

    再开一个终端

    $ source ./devel/setup.bash
    $ rosrun rosrun topic_demo topic_demo_pub_c
    
    • 1
    • 2

    效果如下:

    在这里插入图片描述

    launch封装

    在功能包添加 launch 文件夹,并添加 launch 文件

    在这里插入图片描述

    <launch>
        <node pkg="topic_demo" type="topic_demo_pub_c" name="Subscriber" output="screen"/>
        <node pkg="topic_demo" type="topic_demo_sub_c" name="Publisher" output="screen"/>
    launch>
    
    • 1
    • 2
    • 3
    • 4
    • node: 包含的某个节点
    • pkg: 功能包
    • type: 被运行的节点文件
    • name: 为节点命名
    • output: 设置日志的输出目标

    执行

    $ roslaunch topic_demo topic_demo_launch.launch
    
    • 1

    在这里插入图片描述

  • 相关阅读:
    华纳云:ApacheBeam中的延迟数据处理如何处理
    采空区沉降监测系统解决方案
    多线程学习
    数据库临时表(Temporary Table)
    多点开花,维也纳国际酒店多家门店荣膺当地十佳酒店好评
    修改 git 默认编辑器
    【C++ 学习 ㉝】- C++11 使用 using 定义别名
    深入理解强化学习——多臂赌博机:梯度赌博机算法的数学证明
    速卖通,国际站测评补单用什么环境,买家账号不会被风控,F号
    98.验证二叉搜索树
  • 原文地址:https://blog.csdn.net/PuddleRubbish/article/details/133148613