在配置ROS导航包时,使用robot_pose_ekf包进行imu,编码器,视觉里程计三者的融合(起码两个),用来精确机器人的位姿信息.
关于robot_pose_ekf要订阅哪些话题,以及因为它的使用tf树如何调整,参见需要努力的阿蒙.
在上面的配置好以后,运行该包的launch文件,发现会报错:Covariance specified for measurement on topic xxx is zero和
Filter time older than xxx message buffer.wiki 上也有写,但没说怎么解决.意思就是发布两个传感器信息的时候,都需要带有一个协方差矩阵,为什么,这是扩展卡尔曼滤波的 原因,我暂时也不懂.
解决方法:我用的是型号为razor_imu_9dof的IMU,它有官方提供的软件包,会带有covariance.编码器所得里程计方面,我是直接用的turtlebot里面的矩阵.在turtlebot包里,如下图路径中,create_node包里的covariance中,定义了几个矩阵.
然后在我们的工作空间中的导航包里的发布odom消息的源文件中,如下图路径,使用这个矩阵.
这个矩阵有两种,分机器人静止和动起来的时候用,所以要在发送odom的语句处添加判断语句:
ODOM_POSE_COVARIANCE = [1e-3, 0, 0, 0, 0, 0,
0, 1e-3, 0, 0, 0, 0,
0, 0, 1e6, 0, 0, 0,
0, 0, 0, 1e6, 0, 0,
0, 0, 0, 0, 1e6, 0,
0, 0, 0, 0, 0, 1e3]
ODOM_POSE_COVARIANCE2 = [1e-9, 0, 0, 0, 0, 0,
0, 1e-3, 1e-9, 0, 0, 0,
0, 0, 1e6, 0, 0, 0,
0, 0, 0, 1e6, 0, 0,
0, 0, 0, 0, 1e6, 0,
0, 0, 0, 0, 0, 1e-9]
ODOM_TWIST_COVARIANCE = [1e-3, 0, 0, 0, 0, 0,
0, 1e-3, 0, 0, 0, 0,
0, 0, 1e6, 0, 0, 0,
0, 0, 0, 1e6, 0, 0,
0, 0, 0, 0, 1e6, 0,
0, 0, 0, 0, 0, 1e3]
ODOM_TWIST_COVARIANCE2 = [1e-9, 0, 0, 0, 0, 0,
0, 1e-3, 1e-9, 0, 0, 0,
0, 0, 1e6, 0, 0, 0,
0, 0, 0, 1e6, 0, 0,
0, 0, 0, 0, 1e6, 0,
0, 0, 0, 0, 0, 1e-9]
if sensor_state.requested_right_velocity == 0 and \
sensor_state.requested_left_velocity == 0 and \
sensor_state.distance == 0:
odom.pose.covariance = ODOM_POSE_COVARIANCE2
odom.twist.covariance = ODOM_TWIST_COVARIANCE2
else:
odom.pose.covariance = ODOM_POSE_COVARIANCE
odom.twist.covariance = ODOM_TWIST_COVARIANCE
(这是turtlebot发布里程计的python源码中的语句.路径在这里:
sensor_state是用create_node包里面的一个消息类型TurtlebotSensorState定义的.在我们的源文件中要引用这种消息类型,就牵扯到如何在一个包中使用其他包里的消息类型,方法在这里. )
但是我们并不应该用turtlebot 的判断语句,直接订阅上层发布的速度消息,自己添加一条判断上层规划的速度指令即可.
现在我们得到了odom_combined消息。想让这个消息被movebase使用,看看这里怎么使用。这里主要是看rbx_bringup包里提供的一个节点:odom_ekf.py,很简单,odom和odom_combined它们消息类型是不同的,前者是geometry_msgs/Twist,后者是geometry_msgs/PoseWithCovarianceStamped ,两者的区别:后者的内容是前者的一部分。odom_ekf.py就是将它们转化用的。转化后还要在发布融合信息的launch文件里将odom_combined话题remap成odom_ekf.就可以给movebase使用啦~嘤嘤嘤~!