第十六章 添加你自己的移动机器人:第一部分
没有比从头开始搭建一个属于自己的机器人更加令人兴奋的事情了。虽然前人们早就设计好了各种各样的机器人,但总是不能满足各种各样的需求,而且你或许也想积累一些设计建造机器人的经验是吧?这些都驱使着我们去搭建一个你自己独有的机器人。那么问题来了,如何使用 ROS 去控制它呢?
在本章中,我们将会一步一步的讲解如何将一个新的机器人引入 ROS,并最终实现使用本书中所讲的 ROS 程序库和工具去控制它的目标。这些方法是通用的,适用于任何从零开始设计出的机器人,即便你所用的零件可能还没有 ROS 的相关支持(当然,随着 ROS 的不断发展,这种情况会越来越少)。
小龟机器人
我们将要搭建的是一个室内移动机器人。这个机器人的设计灵感来源于一款名叫 Elise 的古董机器人(见图16-1)。Elise 是英国神经科学家(也是控制论大师)Grey Walter 于20世纪40年代的一系列机器人作品之一。作为研究领域的先锋人物,Walter 当时制作机器人的主要目的是用于研究动物的行为。他坚信,通过设计制造出能够像动物一样进行复杂运动的机器人,我们可以更好的理解生物体的工作原理。这一研究领域后来逐渐发展为人工生命学。
Walter 的机器人在技术上带来了巨大的突破:纯手工打造,仅依赖模拟机械就能在室内自由行进,避开(或者推开)障碍物,甚至在电量不足时主动回到充电站充电。在那个时代背景下,这些特性足以让人惊叹。Walter 的这个“小龟机器人”有两个从动轮和一个用于控制航向的主动轮,分别位于三角形底盘的三个顶点。跟前轮在一块的还有一个光电二极管,用于判断光源的方向,从而让机器人趋光行进(除此之外,凭借电路设计技巧,还可以实现使机器人不至过于靠近光源的功能)。
除了手工制作和模拟机这两点外,这个机器人很容易让人联想到近50多年后才出现的家用清洁机器人。
由于这个机器人有着像屋顶一样的保护壳,行动起来又显得非常笨重缓慢,Walter 给它取名为"小龟"。为了表示对 Walter 所做贡献的敬意,在本章中我们将要搭建的机器人就叫做“小龟机器人”。当然,我们并不会真的把它做出来,我们要做的是解释清楚如何使用 ROS 去控制它,如何给它建立一个仿真模型,然后你再自己去把这个机器人实现。
使用 ROS 去控制这个“小龟机器人”的步骤大致如下:
- 确定 ROS 消息接口
- 编写机器人电机的驱动
- 编写机器人物理结构的模型
- 为3中编写的模型增加物理特性,用于在 Gazebo 中进行仿真
- 使用 tf 对外发布坐标变换数据,并使用 rviz 进行可视化
- 增加传感器,注意要带有驱动和仿真的支持
- 添加一些标准的机器人算法,如导航等
从现在开始到下一章结束,我们会完成上面的每个步骤,详细讲解需要作出哪些决策。在最后,你就能掌握在自己的机器人上运行 ROS 的方法了。注意,这个方法对任何机器人都是通用的,哪怕你的机器人可能与“小龟机器人”大不相同。
ROS 消息接口
控制机器人首先得控制运动底盘。常见的做法是专门写一个与底盘硬件交互的结点(具体交互方式可随意),然后对外暴露出一组标准的 ROS 接口。在这里,ROS 中最核心,也是最常见的“抽象”概念表现的非常明显:无论是什么机器人,使用 ROS 时我们都会尽可能的让它的对外接口看起来与其他机器人差不多。这样就可以最大程度的复用建立在标准接口上的 ROS 配套工具和函数库。
要定义消息接口,首先得搞清楚机器人的特点。对于小龟机器人而言,其基本特点主要有二:一是可移动,二是只能在地面运动(即不能飞行也不能攀爬),这样的描述显然不够充分。如果要进一步细化,不难发现,可以拿三轮车对小龟机器人做类比。换言之,小龟机器人可以沿 x 轴前后移动,可以绕 z 轴旋转,还可以同时进行上述两种运动,但是无法直接沿 y 轴横向移动,也不能沿 z 轴升起降落,更不能绕着 x或 y 轴进行翻滚。因此,使用如下的一对目标速度控制小龟机器人就足够了:
vx
沿 x 轴运动的线速度,约定正值为向前运动
vyaw
绕 z 轴运动的旋转速度,约定正值为顺时针旋转
相应的,我们期待机器人的位姿反馈信息为一个三元组(x,y,yaw),分别代表机器人的质心坐标和朝向。
事实上,ROS 中已经有一些现成的消息接口,可以用于表示上述的控制指令和位姿信息,并且早已用于大量的移动机器人平台:
geometrymsgs/Twist(cmd_val topic)
用于表示机器人的目标运动速度,可作为控制指令发给机器人
nav_msgs/Odometry (odom topic)
用于表示当前机器人的位姿信息,可作为反馈信息由机器人发出
让我们来使用 rosmsg show 命令看看这些消息类型中包含了什么,
首先是 geometry_msgs/Twist:
内容很简单,首先是分解到每个坐标轴上的线速度,共三个,其次是绕每个坐标轴旋转的角速度,同样也是三个。有些速度值我们用不着,不过没关系,忽略它们就好了。
然后是nav_msgs/Odometry:
很多 ROS 消息中都包含一个叫做 header 的部分,类型为 std_msgs/Header。机器人系统中,许多消息之间的转换和同步都依赖header中的数据,比如消息产生的时间和地点。 tf 程序库就利用了消息的 header 部分,从而将原本很复杂的坐标转换变得非常简单,从而实现将多个激光雷达在不同位置,时刻扫描的距离数据进行融合等功能。
这个消息的内容稍显复杂,下面分别进行说明:首先,为了表达机器人的位置和朝向,我们只需要 Odometry 中的 pose/pose/position 和 pose/pose/position 两项数据,而且无需理会其中的 covariance (仅当传感器因各种原因无法测得准确数据时才需要纳入考虑范围)。而在 pose/pose/position 中,只有x,y 这两个是有用的。pose/pose/orientation 稍微麻烦一点,我们需要构造出一个合法的四元数来表征一个三维空间的旋转(尽管小龟机器人实际上只能绕 z 轴旋转)。四元数的构造已经超出了本书的内容范围,这里不做讲解,不过你可以在网上找到详细的教程,也可以利用 ROS 中的一些工具来完成(建议你去看看 tf 程序库的文档)。
可能你会发现,哪怕我们已经忽略了用不着的数据,cmd_vel/odom 这个消息接口对于我们那个只能在地上爬来爬去的小龟机器人而言,多余的内容还是太多了。但是,最好还是不要去自行定义消息,这会对程序的兼容性产生不好的影响,也会给我们使用已有的ROS工具和程序库带来阻碍。设计消息接口时,我们必须对机器人的独特性和互操作性进行权衡,力求更多地去复用已有的工具和程序库。对于移动机器人而言,cmd-vel/odom 更加强大和灵活,它不仅能表征三维空间下的任意位姿,还可以表示结果的不确定度。事实上,一大批常见的工具就是基于这个消息接口,实现了对地上跑的,空中飞的等各种各样移动机器人的操作。
综上所述,我们将采取与ROS 社区主流一致的做法来设计小龟机器人的消息接口,即使用cmd_vel/odom。
硬件驱动
到目前为止,我们已经确定了机器人的消息接口,下一步就是写出机器人的电机控制结点和编码器(一种传感器,测量电机转动的角度)读取结点了,或者说是针对硬件接口写出驱动。这里具体的代码跟机器人所用硬件的设计和通讯方式有关。硬件接口的种类很多,可能是USB,也可能是自行定义的通讯协议。运气好的话,社区里可能已经有了相应协议的实现,这样就能省去不少功夫(当然前提是这些代码已经被很好的组织了起来并且有合适的开源许可)。
在驱动中,有一件事情是无论如何都要做的。那就是对 cmd_vel/odom 接口中的数据进行数学转换。原因在于,像小龟机器人这样的机器人,如果单看 cmd-vel/odom 接口,其描述的运动状态很容易让人联想到一个独轮车---毕竟 cmd-vel/odom 中确实认为机器人只有一个轮子,这个轮子可以控制机器人的方向,还可以控制机器人的运动速度。然而我们的小龟机器人并不是独轮车,不适用独轮车的控制和数据反馈接口,因此必须进行一定转换。以移动为例,小龟机器人实际能接收的控制指令是三个轮子各自的速度,对外反馈的是每个轮子的转动情况。这时,就要参考机器人的运动参数(如轮子尺寸,车轴长度等)对 cmd-vel/odom 中的数据进行三角转换。这样的转换一般都比较简单直接,如果遇到了稍复杂的情况,请仔细查阅有关机器人动态特性的书籍。
虽然在这里我们不能提供通用的移动平台驱动代码,但是 ROS 中已有许多样例,可供你编写时参考。为方便起见,我们将假定已经写好了一个支持cmd-vel/odom 接口的驱动,然后继续讲解 ROS 集成的剩余步骤。接下来的任务,就是对机器人进行建模,并将模型用于仿真。
对机器人建模:使用 URDF
为了能在小龟机器人上使用 ROS 的一些标准工具,我们需要编写它的的运动学模型。换言之,就是描述一下机器人的物理结构,比如有几个轮子,都安装在哪儿,轮子转动的方向如何等等。这些信息可以被 rviz 用来对机器人的状态进行可视化,也可以用作 Gazebo 仿真的参考,还可能会被一些诸如导航程序栈之类的软件系统拿来实现更复杂的功能。
在 ROS 中,我们用统一机器人描述范式(URDF)来表示机器人模型。URDF 使用 XML编写,表达能力强大,从两轮的玩具机器人到可行走的人形机器人都可以使用 URDF 进行建模。URDF 与仿真描述范式(SDF)很像,后者用于在 Gazebo 中建立机器人仿真环境(具体用法见本书第11,14章)。对比 URDF 和 SDF,虽然 SDF 包含一些在仿真中挺有用的额外特性,但是绝大部分 ROS 工具都需要 URDF,而且Gazebo 本身也可以理解 URDF。因此在建模时最好还是选择 URDF。
本小节中,我们会从零开始给小龟机器人建立一个 URDF 模型。如果你想了解 URDF 的完整语法和特性,请查阅 URDF 的文档。
开始建模前,让我们先看看小龟机器人有哪些必要的组件:
- 一个底盘
- 两个连在底盘上的后轮
- 一个连在底盘上的脚轮
- 一个连在脚轮上的前轮
想象一下,这些组件可以构成一棵树:底盘是树干,连接着两个后轮和前面的脚轮。而脚轮则连接着前轮。事实上,URDF 也只能对那些运动学结构可以描述为一棵树的机器人建模,闭环结构是不行的。不过,除了少数用于工业生产的特定机器人外,闭环结构的机器人并不常见。
接下来,我们要把上面对组件的树状描述转换为 URDF。在URDF 中,我们主要关注的是连接段和连接点:
- 一个连接段就是一个刚体,如底盘,轮子等
- 一个连接点将两个连接段连在一起,并且定义了其中一个连接段相对于另一个的运动方式
我们先给底盘建立一个连接段,如Example 16-1 所示:
这一段 URDF 声明了一个叫做 base_link 的连接段(在 ROS 中,习惯上我们会用base-link而不是chassis来命名底盘),并且在可视化工具中将其用一个0.6m*0.3m*0.3m 的box(长方体)来表示。所有的 URDF 连接段的坐标原点一开始都会默认位于其中心。除此之外,我们还给这个盒子填充了名为 silver 的颜色。这个颜色是在RBGA空间定义的,其中R,G,B 分别代表红,绿和蓝三种颜色的百分比,A 则表示颜色的的透明度,0表示全透明,1表示完全不透明。
如果想看看这段 URDF 对应模型的样子,只要将其保存为tortoisebot.urdf,并使用 roslaunch urdf_tutorial/display.launch 进行可视化即可。
执行上述命令后,rviz 会自动打开,显示一个不透明的银色盒子,如图 16-2 所示。
另一个常用来对 URDF 模型进行可视化的工具是 urdftographiz。这个工具可以将 URDF 解析为拓扑图形,并详细展示连接段和连接点之间的连接关系。对于我们的小龟机器人,你可以运行 urdftographiz tortoisebot.urdf 这条命令,然后用pdf 阅读器打开tortoise.pdf ,即可看到模型可视化后的结果。
底盘的连接段建好后,我们再把前脚轮加上去。这个组件同样可以用一个不透明盒子来表示。不同的是,脚轮“盒子”的朝向是竖直方向,连接位置则是底盘的前部。具体的 URDF 代码见 Example16-2。
这一段 URDF 声明了一个连接段 front_caster,还有一个连接点front-caster-joint,后者将 front-caster(视为child) 和 base-link(视为parent)连在一起。首先是连接点类型 type ,取值为 continuous,配合 axis 标签,表示连在上面的连接段可以绕着 z 轴进行任意旋转(绕行轴取决于 axis )。URDF 中允许的连接点类型见表格 16-1。然后是相对位置 origin,表示child连接段(即frontcaster)相对于parent 连接段(即baselink)的位置偏移。
类型 | 描述 |
---|---|
continuous | 连接段可以相对单个坐标轴进行任意旋转 |
revolute | 类似continous,但增加了旋转的角度范围 |
prismatic | 连接段可以沿着单个坐标轴平移,而且有移动范围限制 |
planar | 连接段可以“贴着”一个平面进行平移和旋转 |
floating | 连接段可以进行任意的平移和旋转 |
fixed | 连接段不能进行任何运动 |
把上面的 URDF 添加到tortoisebot.urdf 中(放在</robot>标签之前),保存,再次启动可视化工具:
现在从 rviz 中就能看到我们添加的两个连接段了,脚轮对应的连接段还显示出了三个坐标轴,分别用红,蓝,绿标出,见图16-3。
从图中来看,脚轮的位置应该是对的。如果你想检查确认一下连接点是否工作正常,只要在 URDF 可视化工具的启动命令中加上 gui:=true 这个额外的参数即可:
输入上述命令,现在除了 rviz 外,还出现了一个叫 joint-state-publisher 的小窗口,如图16-4所示。
joint-state-publisher可以用来调整新添加的连接点。滑动滑块,在rivz中脚轮会相对于底盘前后滑动。将 URDF 可视化工具和调整工具配合使用,会给URDF 模型的检查,调试和修改过程带来许多方便。
可能你会产生疑问:到目前为止我们还没有一个真实的机器人,甚至没有一个完整的机器人仿真模型,那 joint-state-publisher 是怎样工作的呢?下面我们来分析一下背后的工作原理。首先看整体的流程,如图16-5 所示。
- 启动时,URDF模型会被加载到参数服务器中,参数名为默认的标准名 robot_description。可以使用rosparam get /robot-description 来查看参数服务器中的模型。
- 上文中的 joint-state-publisher 会根据滑块的位置,向/join-states 话题发布 sensor-msgs/JointState 类型的消息。消息内容代表了机器人系统中连接点的位置。可以使用 rostopic /joint-states 查看发布的消息。
- 另一个比较重要的节点是 robotstatepublisher,它会从参数服务器中读取URDF 模型,并订阅/jointstate 话题。这个节点完成的主要工作是利用每个连接点的1维位置信息和机器人的运动学模型,计算出6维(位置和朝向)的坐标变换树,从而表示出各个连接段空间中的相对位置(用专业一点的说法是进行正向运动学解算)。坐标变换树会被封装为 tf2_msgs/TFMessage 类型的消息,从 /tf 话题发布出去。
- 最后,rviz 会读取 URDF 模型,并订阅/tf 话题,从而对连接段的位置和朝向进行可视化。
看起来相当复杂!不过好在整个流程的模块性很强,所以其中涉及到的大部分 ROS 组件都可以复用。比如说上面的 robot-state-publisher 就常常被用于处理机器人的前向运动学解算问题,这样一来,驱动的编写者只需要发布单个连接点的状态信息就可以了,而不用把整个坐标变换树求解出来,工作量大大减少。类似的,rviz 在 ROS 中的使用也很广泛,尤其是在坐标变换方面的数据可视化上。说白了,URDF 的模型显示工具其实就是在组合了许多 ROS 常见工具的基础上,增加了供用户输入连接点位置信息的图形界面。ROS 设计哲学(源于 UNIX 哲学)正是在这样的实践中体现出来的:构建可复用的小工具,然后通过配置和组合将他们变成你需要的东西。
再次回到我们的小龟机器人。现在把所有的轮子加上去,首先加上前轮,如 Example16-3 所示:
这段 URDF 为前轮声明了一个圆柱形的连接段,同时新增了一个属性为 continuous的连接点,将前轮与脚轮连接起来。连接点的origin标签中,我们通过增加y,x 轴的偏移,让前轮位于脚轮的底部,再通过绕 x 轴的旋转,让圆柱面与地面接触。再次运行 URDF 可视化工具,现在弹出的joint-state-publisher窗口中会有两个滑块,分别用于调节脚轮和前轮的连接点。你可以调节一下,检查连接段和连接点是否配置正确。
最后把剩下的两个后轮加上去,代码见 Example16-4:
这段 URDF 为后轮声明了两个连接段和两个 continuous 类型的连接点。连接点将后轮连接在底盘后部的两侧。打开可视化工具,应该能看到如图16-6 的效果。
到此为止,我们已经为小龟机器人建好了一个看起来不错的运动学模型,只是外观并不是十分漂亮。事实上,通过对高品质 meshes 的使用,机器人的外观可以得到很大的改善,在这里我们就不做展开了。接下来要介绍的内容是如何对小龟机器人进行仿真。
在 Gazebo 中进行仿真
我们的小龟机器人模型已经包含了机器人的运动学特征和外观,但是还缺少仿真所需的物理特性。为了能在 Gazebo 中进行仿真,我们需要对模型中每个连接段添加下面的这些属性标签:
<collision>
与visual 标签类似,这个标签也定义了连接段的大小和形状,只不过不是为了外观,而是为了设定与其他物体的交互关系(即怎样算是与其他物体“碰撞”)。collision 标签中的 geometry 项可以与 visual 中的相同,不过一般是不同的,比如说在 visual 中你可以用一个复杂的 meshes 让连接段看起来更真实,但是为了提高碰撞检测的效率,collision 中应当选用简单的形状,比如盒子,圆柱体等等。
<inertial>
这个标签定义了连接段的质量和转动惯量。仿真中使用牛顿定律进行运动解算时会用到它们。
先添加collision标签,编辑之前的URDF模型文件tortoise.urdf,将 visual 标签的 geometry 部分复制一份,然后于首尾加上collision 标签即可。如 Examaple16-5 所示。注意 collision 中不用添加 material 标签。
再添加inertial 标签。在此之前,我们需要得到每个连接段的准确质量。对于真正的机器人而言,这一步工作会很麻烦。虽然可以参考 机器人CAD 设计文件中的标注信息,但是一般来说还是需要对机器人进行拆解并进行精确测量的。当然也可以通过实验的方式避免拆解,不过在这种实验中,对质量进行合理的估计和修正要求很高,因此实验的设计难度较大。
对于小龟机器人来说就不用那么麻烦了。如果质量的数量级没错的话,我们就能得到合理的仿真结果。因此为方便起见,我们设定底盘的质量为1kg,脚轮和前后轮的的质量为0.1kg。至于转动惯量则可以通过一些基本的计算公式得到。最终计算结果被分别填在了 Example16-6 16-7 16-8 中。只要将其插入到 tortoise.urdf 中的相应位置即可。
如果你看不懂这些数字的含义,没关系,我们写书的也不懂。甚至很多专门从事刚体动态仿真的人都未必能充分理解它们。重要的是掌握对这些物理量进行近似估计的方法。
当你在 ROS 中计算转动惯量时,可以使用以下的方法在Gazebo 中进行可视化的调试:点击View->“Center of Mass/Inertia”,可以看到转动惯量矩阵和每个连接段质量的可视化图形。如果你发现visual 或 collision 中定义的物体不太可能具有这样的转动惯量数据(转动惯量过小或者过大),那么就说明你计算出的转动惯量值是有问题的。
一切就绪,可以在Gazebo 中仿真我们的小龟机器人了。有很多办法能完成这项任务,不过为了强调与 ROS 工具协同工作的重要性(而不是仅仅使用Gazebo),我们会按照下面的模式来,使用roslaunch自动完成仿真工作。
- 将 URDF 模型加载进参数服务器中
- 打开Gazebo(使用一个空的仿真环境)
- 发起 ROS 服务请求,在Gazebo 中实例化一个机器人,并读取参数服务器中的 URDF 模型
整个流程看起来好像有点绕,不过实际上这样做是非常灵活的。以从参数服务器中获取 URDF 模型为例,当 URDF 模型被加载进参数服务期中后,不仅是Gazebo,其他任何 ROS 节点均可从中获取模型。如 rviz 就会读取模型用于可视化,导航程序栈中的 path planner 更是必须依赖机器人外形和大小才能进行路径规划。习惯上, URDF 模型在参数服务器中对应的名字是 /robot-description(可以改成其他的名字,不过这样一来就得手动修改许多 ROS 工具中的默认设置)。不难发现,一个编写良好的 ROS 工具从不会擅自猜测机器人的物理结构,而是会选择从 URDF 模型中读取,并参照模型调整自己的行为。
在编写我们的 launch 文件前,先补做一件之前遗漏的事情:把我们所有的代码打包成一个 ROS 包,包名为 tortoisebot。请在你的工作区创建一个叫做tortoisebot 的文件夹,进入此文件夹,添加一个适当的 package.xml 文件(可以通过catkin-create-pkg 自动完成),然后将tortoisebot.urdf 移动到这里。一切妥当后就可以开始编写 launch 文件了。这个 launch 文件的作用是根据先前的步骤打开Gazebo并进行仿真,具体的代码见 Example16-9。
在上面的 launch 文件中,我们先将 URDF 模型加载进参数服务器中,对应的参数名为/robot-description。接下来借助Gazebo 包中的帮助 launch 文件运行一个仿真环境为空的Gazebo。当URDF模型和Gazebo 都准备好后,我们就可以使用同样来自 Gazebo 包的 spawn_model 工具读取参数服务器中的模型,并实例化一个小龟机器人。
将上面的文件保存为 tortoisebot/tortoisebot.launch 然后使用下面的命令试一试:
工作正常的话,Gazebo 会自动打开,仿真界面中会出现我们的小龟机器人,如图 16-7 所示。
可以使用 Gazebo 的图形界面来查看你的机器人,比如通过View->Wireframe 和View->Joints 功能,你就能看到机器人的整体结构,如图 16-8 所示。由于Gazebo 默认关闭了同一模型中连接段的冲突检测,所以你可能会观察到部分连接段发生重叠的现象,比如脚轮和底盘之间。
机器人已经加载到仿真工具中了,那么接下来如何控制它呢?我们在本章前面曾说过,小龟机器人支持通过 cmd_vel/odom 接口接收控制指令和反馈位置信息。对于真实的机器人而言,这个接口是通过硬件驱动实现的,而在仿真中则可以用更简单的办法做到:加载一些特定的Gazebo 插件即可。对于小龟机器人,我们加载的是differential drive插件,它可以接收 cmdvel 类型的消息,并将其转换为左右后轮对应的转速(请注意,这里跟 Grey Walter 的Elise机器人不同,由于Gazebo没有将 cmdvel 中的指令转换为前轮转速的插件,我们将驱动轮从前轮改成了后轮)。
为了加载这个插件,URDF 模型中需要增加一些内容,代码见 Example16-10:
上面的配置中,需要向插件提供的信息包括:两个差分轮对应的连接点(left-wheel-joint,right-wheel-joint),轮子的大小(直径0.07)和间距(0.25),机器人底盘对应的连接段(base_link)等。最后还需要让插件向 /jointstates 发布轮子的位置消息。
将上面这段 XML 插入 tortoisebot.urdf 中<robot>标签内的任意位置即可。再次使用 roslaunch 启动仿真,打开的Gazebo跟之前一样,但是后台已经准备好接收从 cmd_vel 发来的控制指令了。 可以使用 rostopic 检查效果:
看起来一切正常,手动发送几个指令试试。通过rostopic 发送以下指令:沿 x 轴平移速度为0,绕 z 轴旋转速度为0.5rad/s:
如果看到机器人开始原地顺时针旋转,说明控制成功。不过使用 rostopic 直接发送指令还是太麻烦了,这里我们推荐使用teleop-twist-keyboard 工具,它可以将对键盘的操作转换为cmd_vel 消息(也可以使用本书112页“键盘驱动”一节中的办法自行编写键盘控制节点)。
现在可以使用屏幕上出现的键盘按键来移动机器人了。注意观察机器人转向时脚轮的行为,我们并没有对脚轮的旋转做任何编程,因此其行为完全取决于我们之前定义的模型,以及相关的动力学定律。
当你要仿真一个在Gazebo 中不断移动的机器人时,可以用以下办法使之始终保持在视野中央:右键单击 Gazebo 窗口左侧模型树中的机器人名称,然后选择 “Follow”。
除此之外,还可以用 rostopic 检查 odom 接口有没有正确反馈位置信息,尤其是 pose/pose 一项:
如果能看到不断变化的位置和朝向信息(在机器人运动时),说明反馈正常。这个消息是由差分驱动控制器发出的,它会将观察到的轮子运动情况转换为机器人整体的位置信息,使用的坐标系与 cmd_vel 中控制指令的相同。
小结
本章中,我们初步将一个全新的机器人引入了 ROS 。具体来说,探讨了 ROS 中移动机器人的标准接口,研究了编写硬件驱动中的一些常见问题,还为小龟机器人编写了一个功能性的模型。包括仿真所需的必要物理特性等。下一章中,我们会进一步完善我们的小龟机器人模型,使用 rviz 进行更充分的可视化,添加必要的传感器,还会试着运行一些标准算法,如导航。