第3章 编写ROS程序-3

1、订阅者程序

我们继续使用 turtlesim 作为测试平台,订阅 turtlesim_node发布的/turtle1/pose 话题。 这一话题的消息描述了海龟的位姿 (位置和朝向) 。尽管目前你已经对这一程序的某些部分感到熟悉了,但这里还是有三个新的知识点。

编写回调函数      发布和订阅消息的一个重要的区别是订阅者节点无法知道消息什么时候到达。为了应对这一事实,我们必须把响应收到消息事件的代码放到回调函数里,ROS 每接收到一个新的消息将调用一次这个函数。订阅者的回调函数类似于:

void function_name(const package_name::type_name &msg)
{
. . .
}

其中参数 package_name 和 type_name 和发布消息时的相同,它们指明了我们想订阅的话题的消息类。回调函数的主体有权限访问接收到消息的所有域,并以它认为合适的方式存储、使用或丢弃接收到的数据。 与往常一样, 我们必须包含定义该类的头文件。

本例程中,回调函数接收类型为 turtlesim::Pose 的消息,所以我们需要的头文件是 turtlesim/Pose.h。(我们可以使用 ros-topic
info 命令来确定这是正确的消息类型) 。这个回调函数仅仅是通过 ROS_INFO_STREAM 在终端打印消息数据,包括 x、y 和 theta 数据成员。 (我们可以使用 rosmsg 来查看这个消息类型拥有哪些数据域) 。与这里不同,一个真正的程序当然会使用消息来做一些有意义的事情。

注意订阅者的回调函数的返回值类型为 void。其实这样安排是合理的, 因为调用此函数是 ROS 的工作, 返回值也要交给 ROS,所以我们的程序无法获得返回值, 当然非 void 的返回值类型也就没有意义了。

创建订阅者对象      为了订阅一个话题,我们需要创建一个ros::Subscriber对象:

ros::Subscriber sub = node_handle.subscribe (topic_name,queue_size, pointer_to_callback_function);

这个构造函数有三个形参,其中大部分与 ros::Publisher 声明中的类似:

---node_handle 与我们之前多次见到的节点句柄对象是相同的。

---topic_name 是我们想要订阅的话题的名称,以字符串的形式表示。本例程中是"turtle1/pose"。再次强调,我们忽略了前斜线使其成为相对名称。

---queue_size 是本订阅者接收消息的队列大小,是一个整数。通常,你可以使用一个较大的整数,例如 1000,而不用太多关心队列处理过程。

---最后一个参数是指向回调函数的指针,当有消息到达时要通过这个指针找到回调函数。在 C++中,你可以通过对函数名使用符号运算符(&,“取址”)来获得函数的指针。在我们的实例中,其方法如下: &poseMessageReceived

你可能注意到了,创建 ros::Subscriber 对象时,我们没有在任何地方显式地提到消息类型。C++编译器会根据我们提供的函数指针中的数据类型判断出正确的消息类型。

给ROS控制权       最后的复杂之处在于只有当我们明确给ROS许可时,它才会执行我们的回调函数。实际上有两个略微不同的方式来做到这一点,其中一个版本如下所示:

ros::spinOnce();
这个代码要求 ROS 去执行所有挂起的回调函数,然后将控制权限返回给我们。

另一个方法如下所示:
ros::spin();

这个方法要求 ROS 等待并且执行回调函数,直到这个节点关机。

换句话说,ros::spin()大体等于这样一个循环:
while(ros::ok( )) 
{
ros::spinOnce();
}

使用 ros::spinOnce()还是使用 ros::spin()的建议如下:你的程序除了响应回调函数,还有其他重复性工作要做吗?如果答案是“否”,那么使用 ros::spin();否则,合理的选择是写一个循环,做其他需要做的事情, 并且周期性地调用 ros::spinOnce()来处理回调。本程序使用 ros::spin(),因为程序唯一的工作就是接收和打印接收到的位姿消息。

2、编译并运行subpose

编译和运行这个例程的步骤与我们之前看到的两个例程相同。

不要忘记确认为你的包添加了 turtlesim 依赖库,因为我们使用了 turtlesim/Pose 消息类型。

当 turtlesim_node 和 pubvel 两个程序同时运行时, 程序的输出如表 3.6 所示。

程序代码:

时间: 2024-10-13 11:36:52

第3章 编写ROS程序-3的相关文章

第3章 编写ROS程序

1.创建工作区和功能包 在我们写任何程序之前,第一步是创建一个容纳我们的功能包的工作区,然后再创建功能包本身. 创建工作区  使用标准的mkdir命令行去创建一个目录,我们将把这个新的目录称作工作区目录. 创建工作区还需要最后一步,即在工作区目录中创建一个叫做src的子目录,该子目录用于存放功能包的源代码. 创建功能包   创建一个新ROS功能包的命令应该在你工作区中的src目录下运行,如下所示: catkin_create_pkg package-name 这个命令主要是创建了一个存放这个功能

Qtcreator编写ros程序:无法启动进程"catkin_make" -DCMAKE_BUILD_TYPE=Debug

利用Qtcreator编写ROS程序,你必须先进行相应的配置:在启动qtcreator环境时先把ros环境添加进.(即~/.bashrc文件) 1 版本问题 QT4 与 QT5 sudo    gedit ~/.local/share/applications/DigiaQtOpenSource-qtcreator.desktop     (qt5       默认安装的路径下) 当打开文件是空时,关闭.按照路径打开文件 cd ~/.local/share/applications/ gedit

第 2 章 编写 C# 程序

2.1  Visual Studio 2005开发环境 2.2  控制台应用程序 试试看:创建一个简单的控制台应用程序 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { // Output text to the

【C#入门经典(第五版)】第二章 编写C#程序

第二章 编写C#程序 1. CTS:通用类型系统(Common Type System);--->公共类型系统. 2. CLR:公共语言运行库(Common Language Runtime); 3. CIL: 通用中间语言(Common Intermediate Language); 4. JIT编译器:Just-In-Time; 5. GAC:全局程序集缓存(Global Assembly Caches); 6. 垃圾回收: 7. 链接: 8. ADO.NET:Active Data Obj

第4章 编写Java程序,使用while循环语句计算1+1/2!+1/3!+...+1/20!之和

package four; public class fouronetwo { public static void main(String args[]){ double sum = 0,a = 1; int i = 1; while(i <= 20) { sum = sum+a; i = i+1; a = a*(1.0/i); } System.out.println(sum); } } 解释:当i=1, sum=1, i=2, a=1*(1/2); 当i=2, sum=1+1*1/2, i

第4章 编写Java程序,应用for循环打印菱形

package four; public class fouroneone { public static void main(String args[]){ for(int i=1;i<=7;i+=2){ for(int kong=7;kong>i-1;kong--){ System.out.print(" "); } for(int xing=1;xing<=i;xing++){ System.out.print("* "); } System

编写第一个ROS程序-发布器(Publisher)

在上一篇文章中我们安装好了ROS环境.本篇文章我们将熟悉ROS中的一些概念(Concept),并尝试使用C++来实现一个发布器(Publisher)和一个订阅器(Subscriber). 该文章是个人学习ROS的过程记录,参考的书是中文版<ROS机器人编程:原理与应用>,英文版为A Systematic Approach to Learning Robot Programming with ROS,该书代码托管在作者wsnewman的github上,感谢作者的辛苦付出. 该篇文章分为以下几个部

Python编程入门-第三章 编写程序 -学习笔记

第三章 编写程序 1.编辑源程序.运行程序 可通过IDLE中File>New File新建一个文本以编辑源程序,编辑完成可通过Run>Run Module(或者F5快捷键)来运行程序.Python源文件都以.py格式存储. 2.从命令行运行程序 除了上述利用IDLE的集成功能运行程序的方式外,当然也可以通过命令行运行程序,命令格式为:python ‘源文件名称.py’. 3.编译源代码 当运行py格式文件时,Python会自动创建相应的.pyc文件,该文件包含编译后的代码即目标代码,目标代码基

iOS游戏框架Sprite Kit基础教程第1章编写第一个Sprite Kit程序

iOS游戏框架Sprite Kit基础教程第1章编写第一个Sprite Kit程序 程序是为了实现特定目标或解决特定问题而用计算机语言编写的命令序列的集合.本章将以编写第一个Sprite Kit程序为主线,为开发者讲解什么是Sprite Kit.苹果账号的注册.Xcode的下载和安装.编写程序.调试等内容.选自iOS游戏框架Sprite Kit基础教程Swift版上册大学霸 1.1  Sprite Kit介绍 从iOS 7开始添加了Sprite Kit.本节将为开发者讲解什么是Sprite Ki