ROS2中的TF(Transform)系统:机器人坐标系的管理神器

ROS 2 TF 概述

TF(Transform) 是ROS中用于跟踪多个坐标系之间变换关系的库。在ROS 2中,TF系统被重构为 TF2,提供了更高效、更灵活的坐标变换管理。


核心概念

1. 坐标系(Frame)

  • 每个机器人部件、传感器或环境物体都有自己的坐标系
  • 例如:base_link(机器人基座)、laser(激光雷达)、camera(相机)

2. 变换(Transform)

  • 描述两个坐标系之间的平移(translation)和旋转(rotation)关系
  • 表示为:frame_B 相对于 frame_A 的位置和姿态

3. 变换树(Transform Tree)

  • 所有坐标系通过父子关系连接成一棵树
  • 必须有一个根坐标系(通常是mapodom

ROS 2 TF2 架构

┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ TF2 广播者 │ │ TF2 缓冲区 │ │ TF2 监听者 │ │ (Broadcaster) │────▶│ (Buffer) │◀────│ (Listener) │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ │ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ 发布变换信息 │ │ 查询坐标变换 │ │ /tf 话题 │ │ lookupTransform │ └─────────────────┘ └─────────────────┘ 

核心组件

组件功能对应类/节点
Broadcaster广播坐标变换TransformBroadcaster
Static Broadcaster广播静态变换(固定关系)StaticTransformBroadcaster
Listener监听并查询变换Buffer + TransformListener
Buffer存储变换历史tf2_ros::Buffer

代码示例

1. 发布动态变换(Dynamic Transform)

import rclpy from rclpy.node import Node from geometry_msgs.msg import TransformStamped import tf2_ros import math classDynamicFramePublisher(Node):def__init__(self):super().__init__('dynamic_frame_publisher')# 创建TF广播者 self.br = tf2_ros.TransformBroadcaster(self)# 定时发布 self.timer = self.create_timer(0.1, self.publish_transform) self.t =0.0defpublish_transform(self): t = TransformStamped() t.header.stamp = self.get_clock().now().to_msg() t.header.frame_id ='base_link'# 父坐标系 t.child_frame_id ='rotating_laser'# 子坐标系# 旋转运动 self.t +=0.1 t.transform.translation.x =1.0 t.transform.translation.y =0.0 t.transform.translation.z =0.5# 四元数表示旋转 t.transform.rotation.x =0.0 t.transform.rotation.y =0.0 t.transform.rotation.z = math.sin(self.t /2) t.transform.rotation.w = math.cos(self.t /2) self.br.sendTransform(t)defmain(): rclpy.init() node = DynamicFramePublisher() rclpy.spin(node) rclpy.shutdown()

2. 发布静态变换(Static Transform)

from tf2_ros.static_transform_broadcaster import StaticTransformBroadcaster classStaticFramePublisher(Node):def__init__(self):super().__init__('static_frame_publisher') self.static_br = StaticTransformBroadcaster(self)# 只需要发布一次 static_transform = TransformStamped() static_transform.header.stamp = self.get_clock().now().to_msg() static_transform.header.frame_id ='base_link' static_transform.child_frame_id ='camera_link' static_transform.transform.translation.x =0.5 static_transform.transform.translation.y =0.0 static_transform.translation.z =0.3# 相机朝向(旋转90度) static_transform.transform.rotation.x =0.0 static_transform.transform.rotation.y =0.0 static_transform.transform.rotation.z =0.707 static_transform.transform.rotation.w =0.707 self.static_br.sendTransform(static_transform)

3. 监听变换(Transform Listener)

import tf2_ros from tf2_ros import LookupException, ConnectivityException, ExtrapolationException classFrameListener(Node):def__init__(self):super().__init__('frame_listener')# 创建Buffer和Listener self.tf_buffer = tf2_ros.Buffer() self.tf_listener = tf2_ros.TransformListener(self.tf_buffer, self) self.timer = self.create_timer(1.0, self.lookup_transform)deflookup_transform(self):try:# 查询从 'base_link' 到 'laser' 的变换 transform = self.tf_buffer.lookup_transform('base_link',# 目标坐标系'laser',# 源坐标系 rclpy.time.Time()# 最新时间) self.get_logger().info(f"Translation: [{transform.transform.translation.x:.2f}, "f"{transform.transform.translation.y:.2f}, "f"{transform.transform.translation.z:.2f}]")except(LookupException, ConnectivityException, ExtrapolationException)as e: self.get_logger().warn(f'Could not transform: {str(e)}')

常用工具

命令行工具

# 查看当前TF树 ros2 run tf2_tools view_frames # 查询特定变换 ros2 run tf2_ros tf2_echo base_link laser # 发布静态变换 ros2 run tf2_ros static_transform_publisher 001000 base_link camera 

RViz2 可视化

在RViz2中添加 TF 显示插件,可以实时可视化坐标系:

  • 红色 = X轴
  • 绿色 = Y轴
  • 蓝色 = Z轴

ROS 1 vs ROS 2 TF 对比

特性ROS 1 TFROS 2 TF2
默认库tftf2
时间处理较简单支持时间旅行(查询历史变换)
数据类型专用消息与ROS 2消息系统更好集成
静态变换混合处理独立话题 /tf_static
性能一般更高效,支持零拷贝
Python支持较弱原生支持,API更友好

最佳实践

  1. 区分静态/动态变换:固定关系用StaticTransformBroadcaster,减少网络负载
  2. 保持时间同步:确保所有节点使用相同的时间源(ROS时间 vs 系统时间)
  3. 异常处理:查询变换时总是捕获可能的异常
  4. 命名规范:使用REP 105标准坐标系命名(mapodombase_link
  5. 避免环形依赖:TF树必须是严格的树形结构,不能闭环

典型应用场景

  • 传感器数据融合:将激光雷达、相机数据转换到统一坐标系
  • 导航规划:将目标点从地图坐标系转换到机器人坐标系
  • 机械臂控制:计算末端执行器相对于基座的位姿
  • 多机器人协作:统一不同机器人的坐标参考系

Read more

前端环境配置(nvm、nodejs、npm)

前端环境配置(nvm、nodejs、npm)

一、安装nvm 1. 下载vnm url: https://nvm.uihtm.com/doc/download-nvm.html 2. 解压文件后双击exe文件进行安装 3. 选择nvm的安装地址,我是安装在D:\App\nvm 4. 选择nodejs的安装地址,我是安装在C:\Program Files\nodejs 5. 点击next 一直点击 完成安装; 6. 找到nvm的settings.txt文件打开后: 给该文件添加这两行命令: node_mirror: https://npmmirror.com/mirrors/node/ npm_mirror: https://npmmirror.com/mirrors/npm/ 二、环境变量配置 1.

【DeepSeek R1部署至RK3588】RKLLM转换→板端部署→局域网web浏览

【DeepSeek R1部署至RK3588】RKLLM转换→板端部署→局域网web浏览

本文为DeepSeek R1 7B 以qwen为底座的LLM在瑞芯微RK3588 SoC上的完整部署流程,记录从开发板驱动适配烧录开始,到最终的开发板终端访问模型和局域网web访问模型的完整流程,有不足之处希望大家共同讨论。 文章目录 * 一、项目背景介绍 * 二、所需工具介绍 * 1.硬件工具 * 1.X86 PC虚拟机Ubuntu20.04 * 2. 准备NPU驱动为0.9.8的RK3588开发板 * 2.软件工具 * 三、获取.safetensors模型权重 * 四、safetensors转RKLLM * 1.转换环境搭建 * 2.模型转换 * 五、RKLLM模型板端部署及推理 * 六、集成开源gradio工具实现web访问 一、项目背景介绍 先来介绍下项目背景吧,目前有一个空闲的firefly出厂的搭载瑞芯微RK3588 SoC的arm64开发板,样式如图所示: 博主之前主要进行CV领域的模型的RK开发板部署,对于LLM和VLM的接触并不算多,但现在大模型是趋势所向,并且瑞芯微及时的完成了针对各开源

想做多语言项目?试试Hunyuan-MT-7B-WEBUI快速部署方案

想做多语言项目?试试Hunyuan-MT-7B-WEBUI快速部署方案 你有没有遇到过这样的情况:手头有个跨境项目,要同时处理日语产品说明、西班牙语用户反馈、维吾尔语政策文件,甚至还有藏文古籍数字化需求——可翻来翻去,不是翻译质量差强人意,就是部署起来像在解一道高数题?在线工具不敢传敏感数据,本地跑模型又卡在CUDA版本、依赖冲突、显存爆炸上……最后只能靠人工硬啃,进度一拖再拖。 Hunyuan-MT-7B-WEBUI 就是为这种真实困境而生的。它不讲大道理,不堆参数,不做“实验室里的冠军”,而是把腾讯混元团队打磨出的最强开源翻译模型,连同网页界面、一键脚本、预装环境,全打包进一个镜像里。你不需要懂Transformer结构,不用查PyTorch兼容表,甚至不用打开终端敲命令——点一下,等两分钟,就能在浏览器里开始翻译38种语言。 这不是又一个“需要调参、需要写代码、需要配环境”的AI工具。这是你今天下午就能用上的多语言工作台。 1. 为什么这款翻译镜像值得你立刻试试? 1.1 它真能覆盖你没想过的语言 很多翻译模型标榜“支持多语言”,但实际打开列表一看:英、法、

前端实现Word文档在线编辑与导出:基于mammoth.js与Blob对象的完整解决方案

如何在浏览器中直接编辑Word文档并导出?本文将深入探索一种基于mammoth.js和Blob对象的完整技术方案。 在当今的Web应用开发中,实现文档的在线编辑与导出已成为常见需求。无论是企业内部系统、教育平台还是项目管理工具,都迫切需要让用户能够在浏览器中直接编辑Word文档,而无需安装桌面软件。本文将详细介绍如何利用mammoth.js和Blob对象实现这一功能,并对比其他可行方案。 一、为什么选择mammoth.js与Blob方案? 在Web前端实现Word文档处理,主要有三种主流方案:浏览器原生Blob导出、mammoth.js专业转换和基于模板的docxtemplater方案。它们各有优劣,适用于不同场景。 mammoth.js的核心优势在于它能将.docx文档转换为语义化的HTML,而非简单复制视觉样式。这意味着它生成的HTML结构清晰、易于维护和样式定制。配合Blob对象,我们可以轻松将编辑后的内容重新导出为Word文档。 与直接使用Microsoft Office Online或Google Docs嵌入相比,mammoth.js方案不依赖外部服务,能更好地