🧭 ROS 2 坐标变换工具 TF 笔记 TF(Transform)用于描述 多个坐标系之间的空间关系 ,是机器人感知、定位、导航的核心基础之一。
📦 环境与依赖安装 Python 发布 TF 所需库 1 2 sudo apt install ros-$ROS_DISTRO -tf-transformationssudo pip install transforms3d
📌 说明:
tf_transformations:ROS 封装的坐标变换工具
transforms3d:底层数学库(欧拉角 / 四元数等)
🧱 静态坐标变换(Static TF) 适用于固定不变的坐标关系 (如雷达相对机体)
▶️ 发布静态变换 示例:发布 base_link → base_laser
1 2 3 4 5 ros2 run tf2_ros static_transform_publisher \ --x 0 --y 0 --z 0 \ --roll 0 --pitch 0 --yaw 0 \ --frame-id base_link \ --child-frame-id base_laser
📐 参数说明:
x y z:平移(单位:米)
roll pitch yaw:旋转(弧度)
frame-id:父坐标系
child-frame-id:子坐标系
🔍 查询坐标变换 1 ros2 run tf2_ros tf2_echo frame_a frame_b
👉 实时输出两个坐标系之间的变换关系
🌳 查看 TF 变换树 1 ros2 run tf2_ros view_frames
📄 说明:
在当前目录生成 frames.pdf 和 frames.gv
用于整体检查坐标系结构是否合理
🔄 动态坐标变换(Dynamic TF) 适用于随时间变化的坐标关系 (如运动目标、机械臂)
🛠 创建功能包 1 2 3 ros2 pkg create pkg_name \ --build-type ament_python \ denpendencies rclpy tf2_ros tf_transformations geometry_msgs
📦 依赖说明:
tf2_ros:TF 广播 / 监听
tf_transformations:姿态计算
geometry_msgs:TransformStamped 消息
📡 动态 TF 广播节点(Python) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 import rclpyimport mathfrom rclpy.node import Nodefrom tf2_ros import TransformBroadcasterfrom geometry_msgs.msg import TransformStampedfrom tf_transformations import quaternion_from_eulerclass DynamicTFBroadcaster (Node ): """ 动态 TF 广播器 功能:发布一个围绕 base_link 旋转的子坐标系 """ def __init__ (self ): super ().__init__('dynamic_tf_broadcaster' ) self .tf_broadcaster = TransformBroadcaster(self ) self .timer = self .create_timer(0.1 , self .publish_frame) self .angle = 0.0 def publish_frame (self ): t = TransformStamped() t.header.stamp = self .get_clock().now().to_msg() t.header.frame_id = 'base_link' t.child_frame_id = 'moving_frame' t.transform.translation.x = math.cos(self .angle) t.transform.translation.y = math.sin(self .angle) t.transform.translation.z = 0.0 q = quaternion_from_euler(0 , 0 , self .angle) t.transform.rotation.x = q[0 ] t.transform.rotation.y = q[1 ] t.transform.rotation.z = q[2 ] t.transform.rotation.w = q[3 ] self .tf_broadcaster.sendTransform(t) self .angle += 0.05 def main (args=None ): rclpy.init(args=args) node = DynamicTFBroadcaster() rclpy.spin(node) rclpy.shutdown() if __name__ == '__main__' : main()
✨ 效果:
moving_frame 绕 base_link 做圆周运动
常用于 TF 学习 / 调试验证
👂 订阅 TF(TF Listener) 用于查询并使用已有的坐标变换
🛠 创建功能包 1 2 3 ros2 pkg create pkg_name \ --build-type ament_python \ denpendencies rclpy tf2_ros tf_transformations geometry_msgs
📥 TF 监听节点(Python) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 import rclpyfrom rclpy.node import Nodefrom tf2_ros import Buffer, TransformListenerclass TFListenerNode (Node ): """ TF 监听节点 功能:获取 base_link → moving_frame 的变换 """ def __init__ (self ): super ().__init__('tf_listener_node' ) self .tf_buffer = Buffer() self .tf_listener = TransformListener(self .tf_buffer, self ) self .timer = self .create_timer(1.0 , self .get_transform) def get_transform (self ): try : result = self .tf_buffer.lookup_transform( 'base_link' , 'moving_frame' , rclpy.time.Time() ) self .get_logger().info( f'📐 坐标变换 base_link → moving_frame\n' f' 平移: ' f'x={result.transform.translation.x:.3 f} , ' f'y={result.transform.translation.y:.3 f} , ' f'z={result.transform.translation.z:.3 f} \n' f' 旋转: ' f'x={result.transform.rotation.x:.3 f} , ' f'y={result.transform.rotation.y:.3 f} , ' f'z={result.transform.rotation.z:.3 f} , ' f'w={result.transform.rotation.w:.3 f} ' ) except Exception as e: self .get_logger().warning(f'⚠️ 无法获取 TF: {e} ' ) def main (args=None ): rclpy.init(args=args) node = TFListenerNode() rclpy.spin(node) rclpy.shutdown() if __name__ == '__main__' : main()
❗ 常见失败原因:
坐标系尚未发布
名称拼写错误
TF 数据未缓存
时间戳问题
🖥 GUI 工具:rqt 📦 安装 1 2 3 4 5 6 sudo apt install \ ros-$ROS_DISTRO -rqt \ ros-$ROS_DISTRO -rqt-common-plugins \ ros-$ROS_DISTRO -rqt-graph rm -rf ~/.config/ros.org/rqt_gui.ini
▶️ 启动
🧩 常用插件
📊 Graph :节点 / 话题拓扑
⚙️ Parameter :参数查看与修改
📡 Topics :话题监控
💾 布局保存:File → Save Layout
🌈 可视化工具:RViz2 📦 安装 1 sudo apt install ros-$ROS_DISTRO -rviz2
▶️ 启动
🧠 使用要点
添加 Displays:TF / LaserScan / PointCloud
设置 Fixed Frame(通常为 base_link 或 map)
支持保存 .rviz 配置文件
✅ 总结一句话
TF 是 ROS 的”空间语言”, 静态描述结构,动态描述运动, rqt 看关系,RViz 看世界。 🌍✨