ROS入门笔记(十):编写与测试简单的消息发布器和订阅器(C++)

文章目录

  • 01 导读
  • 02 功能包的创建
  • 03 功能包的源代码编写
    • 3.1 编写发布器节点(talker.cpp)
    • 3.2 编写订阅器节点(listener.cpp)
  • 04 功能包的编译配置(编译节点)
  • 05 功能包的编译
  • 06 测试消息发布器和订阅器
    • 6.1 启动发布器
    • 6.2 启动订阅器

01 导读

  • 开发的功能包都放在catkin_ws这样一个工作空间里;
  • 新建的功能包取名为topic_example,在这个功能包中分别编写两个节点程序talker.cpp和listener.cpp,发布节点(talker)向话题(chatter)发布std_msgs::String类型的消息,订阅节点(listener)从话题(chatter)订阅std_msgs::String类型的消息;
  • 这里消息传递的具体内容是一句问候语“how are you …”,通信网络结构如图所示:

话题编程流程

  • 创建发布者
  • 创建订阅者
  • 添加编译选项
  • 运行可执行程序

02 功能包的创建

在catkin_ws/src/目录下新建功能包topic_example,并在创建时显式的指明依赖roscpp和std_msgs。打开命令行终端,输入命令:

$ cd ~/catkin_ws/src#创建功能包topic_example时,显式的指明依赖roscpp和std_msgs,
#依赖会被默认写到功能包的CMakeLists.txt和package.xml中
$ catkin_create_pkg topic_example roscpp std_msgs

03 功能包的源代码编写

功能包中需要编写两个独立可执行的节点,一个节点用来发布消息,另一个节点用来订阅消息,所以需要在新建的功能包topic_example/src/目录下新建两个文件talker.cpp和listener.cpp,并将下面的代码分别填入。

3.1 编写发布器节点(talker.cpp)

『节点』(Node) 是指 ROS 网络中可执行文件。接下来,我们将会创建一个发布器节点(“talker”),它将不断的在 ROS 网络中广播消息。

如何实现一个发布者

  • 初始化ROS系统;
  • 在 ROS 网络内广播我们将要在 chatter 话题上发布 std_msgs/String 类型的消息;
  • 以每秒 10 次的频率在 chatter 上发布消息。
 // ros/ros.h 是一个实用的头文件,它引用了 ROS 系统中大部分常用的头文件。
#include "ros/ros.h"   /*这引用了 std_msgs/String 消息, 它存放在 std_msgs package 里,是由 String.msg 文件自动生成的头文件。需要关于消息的定义,可以参考 msg 页面。*/
#include "std_msgs/String.h" #include <sstream>int main(int argc, char **argv)
{// 初始化 ROS;     // 可以指定节点名称,节点的名称必须唯一。ros::init(argc, argv, "talker");// 为这个进程的节点创建一个句柄;/* 第一个创建的 NodeHandle 会为节点进行初始化,最后一个销毁的 NodeHandle 则会释放该节点所占用的所有资源。*/ros::NodeHandle n;//创建一个Publisher,发布名为chatter的topic,消息类型为std_mags::String/*告诉 master 我们将要在 chatter(话题名)上发布 std_msgs/String 消息类型的消息。这样 master 就会告诉所有订阅了chatter 话题的节点,将要有数据发布。第二个参数是发布序列的大小。如果我们发布的消息的频率太高,缓冲区中的消息在大于 1000 个的时候就会开始丢弃先前发布的消息。*//*NodeHandle::advertise() 返回一个 ros::Publisher 对象,它有两个作用: 1) 它有一个 publish() 成员函数可以让你在topic上发布消息; 2) 如果消息类型不对,它会拒绝发布。*/  ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);//设置循环的频率以 10Hz 的频率运行。/*ros::Rate 对象可以允许你指定自循环的频率。它会追踪记录自上一次调用 Rate::sleep() 后时间的流逝,并休眠直到一个频率周期的时间。*/ros::Rate loop_rate(10);int count = 0;while (ros::ok())   // 一旦 ros::ok() 返回 false, 所有的 ROS 调用都会失效。{// 初始化std_msgs::String类型的消息std_msgs::String msg;std::stringstream ss;ss << "hello world " << count;msg.data = ss.str();ROS_INFO("%s", msg.data.c_str());//向所有订阅 chatter 话题的节点发送消息。chatter_pub.publish(msg);// 循环等待回调函数ros::spinOnce();// 按照循环频率延时; 调用 ros::Rate 对象来休眠一段时间以使得发布频率为 10Hz。loop_rate.sleep();++count;}return 0;
}

3.2 编写订阅器节点(listener.cpp)

如何实现一个订阅者

  • 初始化ROS系统
  • 订阅 chatter 话题
  • 进入自循环,等待消息的到达
  • 当消息到达,调用 chatterCallback() 函数
#include "ros/ros.h"
#include "std_msgs/String.h"// 这是一个回调函数,当接收到 chatter 话题的时候就会被调用
void chatterCallback(const std_msgs::String::ConstPtr& msg)
{//将接收到的消息打印出来ROS_INFO("I heard: [%s]", msg->data.c_str());
}int main(int argc, char **argv)
{// 初始化Ros节点;ros::init(argc, argv, "listener");// 创建节点句柄;ros::NodeHandle n;//创建一个subacriber,订阅名为chatter的topic,注册回调函数chattercallbackros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);// 循环等待回调函数;ros::spin();return 0;
}

04 功能包的编译配置(编译节点)

说明:

  • C++代码必须通过编译生成可执行文件;
  • python代码是可执行文件,不需要编译;

如何编译代码

  • 设置需要编译的代码和生成的可执行文件;
  • 设置链接库;
  • 设置依赖。

创建功能包topic_example时,显式的指明依赖roscpp和std_msgs,依赖会被默认写到功能包的CMakeLists.txt和package.xml中。

在 CMakeLists.txt 文件末尾加入几条语句:

include_directories(include ${catkin_INCLUDE_DIRS})add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})

这会生成两个可执行文件, talkerlistener, 默认存储到 devel space 目录下,具体是在~/catkin_ws/devel/lib/<package name> 中.

05 功能包的编译

$ cd ~/catkin_ws
$ catkin_make -DCATKIN_WHITELIST_PACKAGES="topic_example"
$ source ~/catkin_ws/devel/setup.bash   # 刷新环境

06 测试消息发布器和订阅器

6.1 启动发布器

第一步,打开一个命令行终端:

$ roscore

第二步,再打开一个命令行终端:

# 用rosrun <package_name> <node_name>启动功能包中的发布节点。
$ source ~/catkin_ws/devel/setup.bash    # 激活catkin_ws工作空间(必须有,必不可少)
$ rosrun topic_example talker        # (C++版本)

你将看到如下的输出信息:

[INFO] [WallTime: 1314931831.774057] hello world 1314931831.77
[INFO] [WallTime: 1314931832.775497] hello world 1314931832.77
[INFO] [WallTime: 1314931833.778937] hello world 1314931833.78
[INFO] [WallTime: 1314931834.782059] hello world 1314931834.78
[INFO] [WallTime: 1314931835.784853] hello world 1314931835.78
[INFO] [WallTime: 1314931836.788106] hello world 1314931836.79

发布器节点已经启动运行。现在需要一个订阅器节点来接受发布的消息。

6.2 启动订阅器

$ source ~/catkin_ws/devel/setup.bash     # 激活catkin_ws工作空间(必须有,必不可少)
$ rosrun topic_example listener           # (C++)

你将会看到如下的输出信息:

[INFO] [WallTime: 1314931969.258941] /listener_17657_1314931968795I heard hello world 1314931969.26
[INFO] [WallTime: 1314931970.262246] /listener_17657_1314931968795I heard hello world 1314931970.26
[INFO] [WallTime: 1314931971.266348] /listener_17657_1314931968795I heard hello world 1314931971.26
[INFO] [WallTime: 1314931972.270429] /listener_17657_1314931968795I heard hello world 1314931972.27
[INFO] [WallTime: 1314931973.274382] /listener_17657_1314931968795I heard hello world 1314931973.27
[INFO] [WallTime: 1314931974.277694] /listener_17657_1314931968795I heard hello world 1314931974.28
[INFO] [WallTime: 1314931975.283708] /listener_17657_1314931968795I heard hello world 1314931975.28

你已经测试完了发布器和订阅器。

ROS入门笔记(十):编写与测试简单的消息发布器和订阅器(C++)相关推荐

  1. ROS入门笔记(十一):编写与测试简单的Service和Client (Python)

    ROS入门笔记(十一):编写与测试简单的Service和Client (Python) 文章目录 01 导读 02 功能包的创建 03 在功能包中创建自定义服务类型 3.1 定义srv文件 3.2 在 ...

  2. ROS学习笔记十:用C++编写一个简单的服务和客户端

    ROS学习笔记十:用C++编写一个简单的服务和客户端 这一节主要介绍如何使用C++编写一个简单的服务和客户端节点. 编写服务节点 由于在前面的练习中,已经向beginner_tutorials软件包中 ...

  3. ROS入门笔记(十二):动作编程 (C++)

    ROS入门笔记(十二):动作编程 (C++) 文章目录 01 导读 02 功能包的创建 03 在功能包中创建action(动作) 3.1 自定义action 3.2 在package.xml中添加功能 ...

  4. ROS入门笔记(九):编写ROS的第一个程序hello world(重点)

    ROS入门笔记(九):编写ROS的第一个程序hello world(重点) 文章目录 1 Catkin工作空间 1.1 创建catkin工作空间 1.2 编译工作空间 1.3 设置环境变量 1.4 检 ...

  5. ROS入门笔记(七):详解ROS文件系统

    ROS入门笔记(七):详解ROS文件系统 文章目录 01 Catkin编译系统 1.1 Catkin特点 1.2 Catkin工作原理 1.3 使用`catkin_make`进行编译 02 Catki ...

  6. ROS入门笔记(六): ROS系统架构

    ROS入门笔记(六): ROS系统架构 文章目录 1 ROS系统架构 1.1 文件系统(重点) 1.2 计算图 1.3 开源社区 1 ROS系统架构 1.1 文件系统(重点) 文件系统:主要指在硬盘里 ...

  7. WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍...

    WPF自学入门(十一)WPF MVVM模式Command命令 在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式.正 ...

  8. ROS入门笔记(十三):分布式通信

    ROS入门笔记(十三):分布式通信 文章目录 01 如何实现分布式多机通信 1.1 设置IP地址,确保底层链路的连通 1.2 在从机端设置ROS_MASTER_URI,让从机找到ROS Master ...

  9. ROS入门笔记(四):ROS实践(小海龟仿真)— ROS Topics

    ROS入门笔记(四):ROS实践(小海龟仿真)- ROS Topics 文章目录 1 基础知识 1.1 运行ROS Master所在主机的资源地址 1.2 ROS常用命令 1.2.1 查看所有以ros ...

最新文章

  1. 从源码分析DEARGUI之动态绘图的两种方法
  2. 【渣硕的数学笔记】数值分析
  3. svn文件重进更改服务器路径,svn 设置 服务器路径
  4. 面试官:如何实现幂等性校验?
  5. CSS单位之战:EM与。 REMs ...打架! ?
  6. python之父的名字-Python 常见双下划线关键字的用法
  7. 【50】了解new和delete的合理替换时机
  8. Linux的IO机制
  9. 性能测试之工具对比-ngrinder jmeter loadunner及ngrinder安装使用方法
  10. 05-用两个栈实现一个队列
  11. Java:pdf文件中添加图片
  12. SpringCloud2020 学习笔记(十五)Spring Cloud Eureka 自我保护机制 关闭
  13. C语言BMP图像的读取、存入、水平镜像、竖直镜像、马赛克模糊处理、灰度二值化处理
  14. Java程序设计 试卷A
  15. git问题:Please make sure you have the correct access rights and the repository exists.
  16. android读写access数据库,Android中利用远程Microsoft Access数据库应用程序
  17. 【IDEA】idea 调试技巧 异常断点 断点之前显示异常字段
  18. Bzoj 3875 骑士游戏
  19. 个人微信ipad协议 8.0.37
  20. 地球 three.js 城市 3d

热门文章

  1. 不超过20位的小数正则_盘点贵州省的GDP增长:跃居全国20位,超过了两个难以超越的省份...
  2. 由SGA组件内存移动导致前台业务超时问题处理过程
  3. 下载丨7月数据库技术通讯:LINUX OS配置问题导致数据库重启
  4. 云图说|一张图看懂一站式DevOps利器——华为云DevCloud
  5. 做数仓运维,你必须要认识这个眼观六路耳听八方的“能人”
  6. 集成学习中的随机森林
  7. 提升漏洞修复率,DevSecOps真的很有一套
  8. 探究Python源码,终于弄懂了字符串驻留技术
  9. 干货分享丨玩转物联网IoTDA服务系列五-智能家居煤气检测联动
  10. 618物流压力怎么扛?