ROS机器人030-机器人实现:map、odom、base_link、base_laser四者关系的提速理解

为了更好的集成和重用软件模块,驱动,模型以及库的开发人员需要一个坐标系的共享公约。该坐标系的共享规约让开发者为移动基座创建驱动和模型提供了一个规范。同样,开发人员用与本规范兼容的一些移动机器人基座软件能很容易的创建相应的库和应用。

1.世界坐标(map)
该map坐标系是一个世界固定坐标系,其Z轴指向上方。一般与机器人所在的世界坐标系一致,相对于map坐标系的移动平台的姿态,不应该随时间显著移动。map坐标是不连续的,这意味着在map坐标系中移动平台的姿态可以随时发生离散的跳变。
典型的设置中,定位模块基于传感器的监测,不断的重新计算世界坐标中机器人的位姿,从而消除偏差,但是当新的传感器信息到达时可能会跳变。
map坐标系作为长期的全局参考是很有用的,但是跳变使得对于本地传感和执行器来说,其实是一个不好的参考坐标。
2.里程计坐标系(odom)
odom 坐标系是一个世界固定坐标系。在odom 坐标系中移动平台的位姿可以任意移动,没有任何界限。这种移动使得odom 坐标系不能作为长期的全局参考。然而,在odom 坐标系中的机器人的姿态能够保证是连续的,这意味着在odom 坐标系中的移动平台的姿态总是平滑变化,没有跳变。
在一个典型设置中,odom 坐标系是基于测距源来计算的,如车轮里程计,视觉里程计或惯性测量单元。
odom 坐标系作为一种精确,作为短期的本地参考是很有用的,但偏移使得它不能作为长期参考,这里要区分开odom topic,这是两个概念,一个是坐标系,一个是根据编码器(或者视觉等)计算的里程计。但是两者也有关系,odom topic 转化得位姿矩阵是odom–>base_link的tf关系。这时可有会有疑问,odom和map坐标系是不是重合的?(这也是我写这个博客解决的主要问题)可以很肯定的告诉你,机器人运动开始是重合的。但是,随着时间的推移是不重合的,而出现的偏差就是里程计的累积误差。那map–>odom的tf怎么得到?就是在一些校正传感器合作校正的package比如gmapping会给出一个位置估计(localization),这可以得到map–>base_link的tf,所以估计位置和里程计位置的偏差也就是odom与map的坐标系偏差。所以,如果你的odom计算没有错误,那么map–>odom的tf就是0.
3.基座标(base_link)
该base_link坐标刚性地连接到移动机器人基座。base_link可以安装在基座中的任意方位;对于每个硬件平台,在基座上的不同地方都会提供一个明显的参考点,机器人本体坐标系,与机器人中心重合,当然有些机器人(PR 2)是base_footprint,其实是一个意思。
**4.激光雷达坐标系(base_laser)**激光雷达的坐标系,与激光雷达的安装点有关,其与base_link的tf为固定的。

坐标之间的关系

在机器人系统中,我们使用一棵树来关联坐标系,因此每个坐标系都有一个父坐标系和任意子坐标系,如下:

map --> odom --> base_link

世界坐标系是odom坐标系的父,odom坐标系是base_link的父。虽然直观来说,map和odom应连接到base_link,这是不允许的,因为每坐标系只能有一个父类。

坐标系权限

odom到base_link的转换是由里程计源计算和发布的。然而,定位模块不发布map到base_link的转换(transform)。相反,定位模块先接收odom到base_link的 transform,并使用这个信息发布map到odom的transform。

通俗的讲

odom和map坐标系在机器人运动开始是重合的。但是,随着时间的推移是不重合的,而出现的偏差就是里程计的累积误差。那map–>odom的tf就是在一些校正传感器合作校正的package比如gmapping会给出一个位置估计(localization),这可以得到map–>base_link的tf,所以估计位置和里程计位置的偏差也就是odom与map的坐标系偏差。所以,如果你的odom计算没有错误,map–->odom的tf

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要获取mapbase_link之间的机器人角度,可以使用ROS2中的tf2库。tf2库提供了一个TransformListener类,它可以订阅tf2变换,并提供了一些方法来查询和转换变换。 以下是获取机器人角度的步骤: 1. 创建一个TransformListener对象: ``` tf_buffer = tf2_ros.Buffer() tf_listener = tf2_ros.TransformListener(tf_buffer) ``` 2. 在机器人运行时,订阅tf2中的/map到/base_link变换: ``` try: trans = tf_buffer.lookup_transform('map', 'base_link', rospy.Time()) except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException): rospy.logwarn("Failed to get transform from map to base_link") ``` 3. 从变换中获取机器人的角度: ``` roll, pitch, yaw = tf.transformations.euler_from_quaternion([trans.transform.rotation.x, trans.transform.rotation.y, trans.transform.rotation.z, trans.transform.rotation.w]) ``` 其中,roll、pitch和yaw是机器人在x、y和z轴上的旋转角度。 完整的代码示例如下: ``` import rospy import tf2_ros import tf rospy.init_node('tf_listener') tf_buffer = tf2_ros.Buffer() tf_listener = tf2_ros.TransformListener(tf_buffer) while not rospy.is_shutdown(): try: trans = tf_buffer.lookup_transform('map', 'base_link', rospy.Time()) roll, pitch, yaw = tf.transformations.euler_from_quaternion([trans.transform.rotation.x, trans.transform.rotation.y, trans.transform.rotation.z, trans.transform.rotation.w]) rospy.loginfo("Robot angle: %.2f degrees", yaw*180/3.14) except (tf2_ros.LookupException, tf2_ros.ConnectivityException, tf2_ros.ExtrapolationException): rospy.logwarn("Failed to get transform from map to base_link") rospy.sleep(0.1) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值