ROS中map,odom坐标系的理解以及acml和robot_pose_ekf的对比和小车漂移方法解决

之前一直不知道odom,map到底是什么关系,看了这个博客:https://blog.csdn.net/u012686154/article/details/88174195 才了解了一些。这边记录我自己的看法,看下是否正确:

1 ROS中map,odom坐标系的理解

我想解决的问题是:计算出小车在真实世界(这个坐标系称为map)的位置

我可以得到的数据:

gazebo的传感器(比如 libgazebo_ros_diff_drive.so)会在/odom topic下面发布小车在map坐标系的坐标。但是这个坐标只是根据传感器得到的,gazebo无法保证它是正确的。

于是新增了一个概念:odom坐标系。意思是gazebo本来计算的是小车在map上的坐标,但是这个这个坐标和真实值有偏差,因此把该坐标看成小车在odom坐标系上的坐标,然后odom坐标系相对于map有相对偏差。

坐标变换从base_footprint->map 变化为了:base_footprint->odom->map

2 odom坐标系的总结

  1. 只是一个概念上的坐标系,实际不存在
  2. 如果说完全相信传感器的数据,那么可以认为odom坐标系就是map坐标系
  3. 如何计算odom坐标系相对于map坐标系的位置:首先获得差速计推算出的小车坐标p,然后使用雷达再次估算小车的位置g(此时认为g比较准确,因此认为g就是小车在map上的坐标),那么差速计得到的坐标可以看成是小车在odom的坐标+odom相对于map的偏差,因此odom在map上的坐标就是p-g

3 acml和robot_pose_ekf的区别

先说下他们的共同点:

  • 都是可以估算出robot在map上的位置。
  • 虽然它们都会在某个topic发布小车的坐标,并且发布一个tf变换。tf变换可以看成一个特殊的topic,里面说明了两个坐标系的相对位置。在实际开发中,一般直接使用这个tf变换,而不是使用发布出来的坐标。

区别是:

  • acml估算的方法是输入雷达信号,然后直接算出位置。

  • robot_pose_ekf是通过将imu信号和原来里程计估算出来的坐标整合以后算出一个新的坐标。

  • 真正计算坐标的位置,更多是通过坐标变换进行的

    • acml发布了一个map到odom的变换,
    • robot_pose_ekf发布了一个odom到base_footprint的变换

比较让人困惑的是:acml应该只是知道base_footprint到odom的坐标,它怎么知道map到odom的坐标的?

我的理解是,acml觉得自己准确率非常高,因此把自己计算出的坐标当成了map上的坐标,而通过获得base_footprint到另一个坐标系的坐标,就可以获得该坐标系到map的坐标了。现在这个坐标系被称为了odom而已。

amcl能否和robot_pose_ekf一起使用?

我的理解是可以。理论上来说,因为robot_pose_ekf算出了odom到base_link的变化,而amcl计算出的odom到map的变化其实是通过map到base_link变化得到的,(base_link->map)表示base_link相对于map的坐标,那么有:

(base_link->map) = (base_link->odom) + (odom->map)

而acml计算的odom->map:

(odom->map) = (base_link->map) - (base_link->odom)

把它代入上面,发现算出来的还是acml计算出的base_link对于map的坐标,而base_link到odom的坐标不管是什么都不会产生影响。

但是实际上来说,很多包可能会用到odom坐标系,如果说不太相信里程计的话还是使用一下amcl比较好。

下面是详细解释:

从acml的描述可以看出来:

amcl transforms incoming laser scans to the odometry frame (~odom_frame_id). So there must exist a path through the tf tree from the frame in which the laser scans are published to the odometry frame.

The drawing below shows the difference between localization using odometry and amcl. During operation amcl estimates the transformation of the base frame (~base_frame_id) in respect to the global frame (~global_frame_id) but it only publishes the transform between the global frame and the odometry frame (~odom_frame_id). Essentially, this transform accounts for the drift that occurs using Dead Reckoning. The published transforms are future dated

我的理解是:acml和GPS差不多,根据雷达信息可以直接估算出机器人在map上面的坐标。但是acml提供了一个功能,就是可以指定一个别的坐标系,它帮你把map上的坐标转为该坐标系相对于map的坐标。这个坐标系一般是指定为odom。

4 小车漂移的解决方法

我的现象:小车在运动过程中一会儿飘过来,然后突然飘回去。

一开始我觉得可能是odom不准,后来把里程计坐标直接看成map上的坐标,发现小车不再飘了。于是发现是gmapping发布的map到odom的坐标不准。如果说遇到这种情况,可以按照下面的步骤排除:

  1. 如果说用的是差速计控制的小车,可以去网上找一份键盘控制小车的代码
  2. 让小车原地转圈
  3. 如果说小车原地转圈也会飘一定不是里程计的问题。事实上,如果开的不太远,里程计应该是非常准的

解决方法:

  1. 里程计不准可以使用robot_pose_ekf
  2. gmapping不准可以直接放弃使用gmapping发布坐标,完全相信里程计。就是里程计直接发布map到base_footprint的tf变换
  3. 如果是场景非常空旷,可以在场景中加入一些障碍物,不然雷达不会起效
  4. 可以把gmapping的miniScore改的小一点,甚至是负数。因为雷达在空旷的地区置信度为0,而出现一些小的障碍物就会导致置信度>0,转而使用雷达。而我们希望多使用差速计。

你可能感兴趣的:(ROS,算法,python,机器人,自动驾驶,人工智能)