【总结学习】ROS——TF tree

本文主要介绍了ROS中的TF框架,讲解了如何进行坐标系转化,特别是TransformStamped消息中的父节点和子节点关系。重点在于理解TransformStamped用于将子坐标系下的点转换到父坐标系,并提供了转换函数transformPose的使用方法。同时,文章还提到了四元数与欧拉角的转化,并给出了相关参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


近期进行了机器人相关的项目,其中涉及了TF tree的概念,查阅浏览了相关材料,准备把相关知识总结一下,到时候也方便自己查看,若有侵权,实在抱歉,请联系我进行删除,感谢~

最重要的关键点

坐标系转化

通常来说 geometry_msgs/TransformStamped.msg 定义了两个坐标系的转换关系,在 TransformStamped 下Header 中的 frame_id 表示的是父节点, 与 Header 同一级别的 child_frame_id 表示的子节点。父节点与子节点在 TF tree 关系图中表示为,父节点——箭头指向——子节点 ,这也有助于根据 rqt_graph 中出现的节点图来判断节点之间的关系。

那么在 TransformStamped 中另外一个重要的部分是 transform ,官方对其描述为 # This represents the transform between two coordinate frames in free space,也就是说在这一部分中定义了两个坐标系的转换关系,具体地 transform 由 translation 以及 rotation 组成,分别代表了平移和旋转,因为任意两个坐标系都可以通过有限的平移和转旋所重合。

重点!!那么上面所说的 TransformStamped 描述的是 父节点中的坐标系向子节点坐标系转换呢,还是子节点内坐标系向父节点所代表的坐标系转化呢。答案是,其作用是将在 子坐标系下的A点的坐标,转换到A点在父坐标系下的新坐标。所以在使用该msgs时一定要区分清楚,想要将某一点的坐标转换到哪一个坐标系下,这个想要转换到的坐标系就是你的父节点所代表的坐标系。同时, transform 部分如何赋值呢,具体地为,针对 子结点所代表的坐标系的原点,得到这个原点在父坐标系下的位置,以及旋转角度,然后将其坐标和转旋直接填入到 transform 内对应的 translation.x/y/z 以及 rotation.x/y/z/w 即可。

坐标转化 TransformPose

void transformPose(const std::string &target_frame, const geometry_msgs::PoseStamped &stamped_in, geometry_msgs::PoseStamped &stamped_out) const

target_frame 为目标坐标系。假如原始 pose 的 frame_id 为 “odom”,想要转化到 "map"上,则 target_frame 为“map” 。stamped_in 为源pose,而stamped_out就是输出目标数据了,即转换完成的数据。

需要注意的是,在参数输入中,是不需要指定 源frame_id的,这是因

03-08
### ROS TF2 使用指南和常见问题解决 #### 安装与配置 为了使用 `tf2`,通常不需要单独安装该库,因为大多数ROS 2发行版已经包含了它。然而,在某些情况下可能需要额外组件的支持。例如,对于特定功能如监听器或广播器,可以利用Python接口来操作变换树[^2]。 #### 基本概念介绍 - **Transform Tree (TF tree)** 是一个有向无环图(DAG),节点代表坐标系之间的相对位置关系。 - **Static Transform Publisher**: 发布静态转换信息;适用于固定不变的关系。 - **Broadcasters 和 Listeners** : 广播当前时刻的空间变换数据以及订阅这些消息并查询历史记录。 #### Python API 示例 下面是一个简单的例子展示如何创建一个发布者和接收者的配对: ```python import rclpy from geometry_msgs.msg import TransformStamped from tf2_ros import StaticTransformBroadcaster, Buffer, TransformListener def handle_turtle_pose(msg, turtlename): stfbrd = StaticTransformBroadcaster(node) # 构建新的变换帧 transform = TransformStamped() transform.header.stamp = node.get_clock().now().to_msg() transform.header.frame_id = 'world' transform.child_frame_id = f'{turtlename}/base_link' # 设置平移分量 transform.transform.translation.x = msg.x transform.transform.translation.y = msg.y # 添加旋转四元数表示法... quaternion = euler_to_quaternion(0, 0, theta) # Assuming you have a function to convert Euler angles to Quaternion. transform.transform.rotation.w = quaternion[0] transform.transform.rotation.x = quaternion[1] transform.transform.rotation.y = quaternion[2] transform.transform.rotation.z = quaternion[3] stfbrd.sendTransform(transform) if __name__ == '__main__': rclpy.init() node = rclpy.create_node('my_tf_broadcaster') sub = node.create_subscription( Pose, '/turtle1/pose', lambda msg: handle_turtle_pose(msg, 'turtle1'), 10) try: while rclpy.ok(): rclpy.spin_once(node) except KeyboardInterrupt: pass node.destroy_node() rclpy.shutdown() ``` 这段代码展示了怎样通过监听海龟机器人的姿态变化并将之作为世界坐标系下的位姿更新发送出去。 #### 解决方案建议 如果遇到无法获取预期的变换结果的问题时,请确认以下几点: - 所有的广播源都正常工作并且频率合理; - 时间戳同步良好——即所有参与计算的时间标记应该尽可能接近实际发生时间; - 正确设置了父级(`frame_id`)和子级(`child_frame_id`)名称; - 如果涉及到多个不同步的消息流,则考虑引入缓存机制以确保一致性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值