ROS话题通信机制自定义数据C++实现

ROS话题通信的理论查阅ROS话题通信流程理论

ROS话题通信的自定义数据的准备可以查阅ROS话题通信流程自定义数据格式

在ROS话题通信机制实现中,ROS master 不需要实现,且连接的建立也已经被封装了,需要关注的关键点有三个:

  • 发布方(二狗子)
  • 订阅方(翠花)
  • 数据(此处为普通文本)

创建ROS工程

创建一个ROS工程包括以下几个步骤:

  • 创建一个topic_ws的ROS工作空间
  • 启动VScode
  • VScode 编译ROS
  • 创建ROS功能包

详细操作可以查阅VScode创建ROS项目 ROS集成开发环境

VScode 配置

为了方便代码提示以及避免误抛异常,需要先配置 vscode,将前面生成的 head 文件路径配置进 c_cpp_properties.json 的 includepath属性:
在这里插入图片描述

发布方(二狗子)

  • 基本流程

    • 1.包含头文件
    • 2.初始化 ROS 节点:命名(唯一)
    • 3.实例化 ROS 句柄
    • 4.实例化 发布者 对象
    • 5.组织被发布的数据,并编写逻辑发布数据
  • 代码实现

    #include "ros/ros.h"
    #include "plumbing_pub_sub/Person.h"
    
    /*
        1.包含头文件 
        2.初始化 ROS 节点:命名(唯一)
        3.实例化 ROS 句柄
        4.实例化 发布者 对象
        5.组织被发布的数据,并编写逻辑发布数据
    
    */
    
    
    int main(int argc, char  *argv[])
    {   
        //设置编码
        setlocale(LC_ALL,"");
    
        //2.初始化 ROS 节点:命名(唯一)
        // 参数1和参数2 后期为节点传值会使用
        // 参数3 是节点名称,是一个标识符,需要保证运行后,在 ROS 网络拓扑中唯一
        ros::init(argc,argv,"banZhuRen");
        //3.实例化 ROS 句柄
        ros::NodeHandle nh;//该类封装了 ROS 中的一些常用功能
    
        //4.实例化 发布者 对象
        //泛型: 发布的消息类型
        //参数1: 要发布到的话题
        //参数2: 队列中最大保存的消息数,超出此阀值时,先进的先销毁(时间早的先销毁)
        ros::Publisher pub = nh.advertise<plumbing_pub_sub::Person>("liaoTian",10);
    
        //5.组织被发布的数据,并编写逻辑发布数据
        //数据(动态组织)
        plumbing_pub_sub::Person person;
        person.name = "ZhangSan";
        person.age = 25;
        person.height = 1.75;
        // msg.data = "你好啊!!!";
        int count = 0; //消息计数器
    
        //逻辑(一秒1次)
        ros::Rate rate(1);
    
        ros::Duration(3.0).sleep();  //休眠3s等待 publisher 注册完成,不然订阅者读不到第一条消息
    
        //节点不死
        while (ros::ok())
        {
    
            //发布消息
            pub.publish(person);
            //加入调试,打印发送的消息
            ROS_INFO("我叫:%s,今年%d岁,高%.2f米", person.name.c_str(), person.age, person.height);
    
            //根据前面制定的发送贫频率自动休眠 休眠时间 = 1/频率;
            rate.sleep();
    
            //修改数据
            person.age += 1;
    
            //暂无应用
            ros::spinOnce();
        }
    
    
        return 0;
    }
    
  • 验证是否有问题

    • 编辑配置文件
      修改 plumbing_pub_sub 功能包下的CMakeLists.txt,找到add_executable、add_dependencies和target_link_libraries,修改成如图所示:
      在这里插入图片描述

    • 按快捷键 ctrl + shift + B 编译

    • 开启一个Terminal,运行 roscore 命令;再开启一个新的Terminal,运行source ./devel/setup.bash rosrun plumbing_pub_sub demo_pub_person_c ;再开启一个Terminal,运行rostopic echo fang,查看订阅数据
      在这里插入图片描述

订阅方(翠花)

  • 基本流程

    • 1.包含头文件
    • 2.初始化 ROS 节点:命名(唯一)
    • 3.实例化 ROS 句柄
    • 4.实例化 订阅者 对象
    • 5.处理订阅的消息(回调函数)
    • 6.设置循环调用回调函数
  • 代码实现

    // 1.包含头文件 
    #include "ros/ros.h"
    #include "plumbing_pub_sub/Person.h"
    
    
    /*
        1.包含头文件 
        2.初始化 ROS 节点:命名(唯一)
        3.实例化 ROS 句柄
        4.实例化 订阅者 对象
        5.处理订阅的消息(回调函数)
        6.设置循环调用回调函数
    */
    
    
    void doPerson(const plumbing_pub_sub::Person::ConstPtr &person)
    {
        //通过Person获取并操作订阅到的数据
        ROS_INFO("订阅的人信息:%s, %d, %.2f", person->name.c_str(), person->age, person->height);
    
    }
    
    
    int main(int argc, char  *argv[])
    {
        setlocale(LC_ALL,"");
        //2.初始化 ROS 节点:命名(唯一)
        ros::init(argc, argv, "jiaZhang");
        //3.实例化 ROS 句柄
        ros::NodeHandle nh;
    
        //4.实例化 订阅者 对象
        ros::Subscriber sub = nh.subscribe<plumbing_pub_sub::Person>("liaoTian", 10, doPerson);
        //5.处理订阅的消息(回调函数)
    
        //6.设置循环调用回调函数
        ros::spin();//循环读取接收的数据,并调用回调函数处理
    
        return 0;
    }
    

发布方的订阅方声明的话题必须一直,案例中的话题是 liaoTian

编辑配置文件

修改 plumbing_pub_sub 功能包下的CMakeLists.txt,找到add_executable、add_dependencies和target_link_libraries,修改成如图所示:
在这里插入图片描述

编译并执行

  • 编译代码
    按快捷键 ctrl + shift + B 编译
    在这里插入图片描述

  • 执行代码

    • 1.启动 roscore;
      开启一个Terminal,启动 roscore
      在这里插入图片描述

    • 2.启动发布节点;
      开启一个新的Terminal

      cd topic_ws/
      source ./devel/setup.bash 
      rosrun plumbing_pub_sub demo_pub_person_c 
      

      在这里插入图片描述

    • 3.启动订阅节点。

      cd topic_ws/
      source ./devel/setup.bash 
      rosrun plumbing_pub_sub demo_sub_person_c 
      
      

      在这里插入图片描述

注意

订阅的第一条数据丢失

  • 原因:
    发送第一条数据时, publisher 还未在 roscore 注册完毕,但是数据已经再发送
  • 解决方法:
    注册后,加入休眠 ros::Duration(3.0).sleep(); 延迟第一条数据的发送。
  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值