我使用的虚拟机软件:VMware Workstation 11使用的Ubuntu系统:Ubuntu 14.04.4 LTSROS 版本:ROS Indigo
注意:1 . ROS 提高篇这个专栏的教学有门槛。2 . 如果你没有学习前面的教程,请想学习前面的 beginner_Tutorials 和 learning_tf 的ROS 相关教程。
在查看代码之前,我们先来启动这个节点,看看运行效果:
新开一个终端,执行下面的命令,启动一个虚拟的 TurtleBot 机器人:
再开一个终端,启动 RViz :
1 .
这里,我定义了一个角度的angular_tolerance (角度公差)。它的作用是:在真正的机器人上,很容易发生角度转多了或转少了。一个小小的角度误差会照成机器人远离了下一个位置。凭经验发现大约一个公差 2.5度给出可接受的结果。
2 .
为了获得机器人的位置和方向,如果你的机器人是 TurtleBot,那么我们需要 /odom 坐标系和 /base_footprint 坐标系之间的转换;如果你的机器人是 Pi Robot 和 Maxwell, 那么我们需要 /odom 坐标系和 /base_link 坐标系。
3 .
在一个航段的开始,我们调用 get_odom() 函数来记录下这个时候机器人的位置(tran)和角度(rot)。
4 .接下来让我们来理解 get_odom() 是如何工作:
get_odom()函数首先使用 tf_listener 对象查找当前 odometry 坐标系和 base(基础)坐标系之间的变换。如果查找出现问题,我们抛出异常。否则,我们返回一个用坐标表示的点和一个用四元数表示的旋转。
其中:return (Point(*trans), quat_to_angle(Quaternion(*rot))) 这段语句。在 python 中使用 “ * ” 修饰的trans 和 rot 变量,表示传给一个函数的形参是一个列表。我们这里的 trans 是 x、y、z 轴坐标值;rot是 x、y、z、w 四元数值。
5 .
现在在回到主函数:
这个循环是为了前进 1m。
6 .
这个循环是为了旋转 180度。
Q: 我们可能会有疑问:在上面的代码中,为什么我们要使用 TransformListener 来访问 odometry 信息,而不是仅仅订阅一个 /odom 话题。
A: 原因是:发布的 /odom 话题里的数据”不完整“。什么意思?举例说明:TurtleBot 机器人使用了一个单轴陀螺仪给机器人的旋转提供了一个额外的估量。robot_pose_ekf 节点(在 TurtleBot 的启动文件中被启动)将它和轮子编码器的数据相结合,目的是为了得到更好的旋转的估计,而不是使用单独源。
我为什么说 /odom 话题里的数据并不完整呢,是因为,robot_pose_ekf 节点并没有将它里面更好的数据传递给 /odom 话题里,/odom 话题里的转据是通过轮子编码器数据估计出来的。并且,它将它自己的数据发布到 /odom_combined 话题里。此外,被发布的数据也不再是 Odometry 消息类型了,而是 PoseWithCovarianceStamped 消息类型。然而,它提供了一个我们需要的信息,这个信息就是:/odom 坐标系与 /base_link (or /base_footprint ) 坐标系之间的转换。 所以结果通常是,使用 tf 去监视 /odom 坐标系与 /base_link ( or base_footprint ) 坐标系之间的转换要比依赖 /odom 话题要安全的多。