ROS————tf2介绍及教程
tf2 - ROS Wikihttp://wiki.ros.org/tf2tf已经被弃用,取而代之的是tf2。tf2是转换库的第二代,它允许用户随时间跟踪多个坐标帧。tf2在时间缓冲的树结构中维护坐标帧之间的关系,并允许用户在任何所需的时间点在任意两个坐标帧之间转换点、向量等。一、tf2的作用以及为什么要使用tf2如果你不光想要只是阅读文档而是想看看tf2到底能干什么,查看下面的简介演示连接:tf
本文参考资料:
tf2 - ROS Wikihttp://wiki.ros.org/tf2
目录
前言
tf已经被弃用,取而代之的是tf2。tf2是转换库的第二代,它允许用户随时间跟踪多个坐标帧。tf2在时间缓冲的树结构中维护坐标帧之间的关系,并允许用户在任何所需的时间点在任意两个坐标帧之间转换点、向量等。
一、tf2的作用以及为什么要使用tf2
如果你不光想要只是阅读文档而是想看看tf2到底能干什么,查看下面的简介演示连接:
如果尚未创建用于完成教程的工作区,请按照下文创建工作区:
source /opt/ros/noetic/setup.bash
mkdir -p ~/tutorial_ws/src
cd ~/tutorial_ws
catkin_init_workspace src
catkin_make
source devel/setup.bash
1.安装demo
安装依赖和编译demo包:
sudo apt-get install ros-$ROS_DISTRO-turtle-tf2 ros-$ROS_DISTRO-tf2-tools ros-$ROS_DISTRO-tf
2.运行demo
现在,我们已经完成了turtle_ tf2教程包的编译,让我们运行演示。
roslaunch turtle_tf2 turtle_tf2_demo.launch
此时问题来了,按道理打开的Turtlesim界面应该有两只乌龟,但是实际只有一只乌龟,报错如下:
是因为在其目录中找的是python的编译器,但是ROS安装是安装的是python3.8(这里以noetic)所以他的编译器的名称是python3,而不是python所以在运行的时候就会报错。
解决方案:
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1
再次输入:
roslaunch turtle_tf2 turtle_tf2_demo.launch
使用方向键移动,就可以看到一只乌龟追着另一只乌龟了。
3.上面的例子代表着什么
此demo使用tf2库创建三个坐标系:世界坐标系、turtle1坐标系和turtle2坐标系。本教程使用tf2广播程序发布海龟坐标系,使用tf2侦听器计算海龟坐标系中的差异,并移动一只海龟以跟随另一只海龟。
4.tf2工具
现在,让我们看看如何使用tf2创建此demo。我们可以使用tf2工具查看tf2在幕后所做的工作。
4.1使用view_frames
view_frames 创建 tf2 通过ROS广播的所有坐标系的示意图,他们的相互关系。
不要关闭海龟窗口,重新打开一个终端,输入:
rosrun tf2_tools view_frames.py
可以看到以下结果:
这里,tf2侦听器正在侦听通过ROS广播的坐标系,并绘制帧连接方式的树。要查看树,请执行以下操作:
evince frames.pdf
这条指令运行后会直接保存在home路径下。
在这个图上,可以看到tf2广播的三个坐标系:世界坐标系,turtle1坐标系和turtle2坐标系,并且世界坐标系是turtle1和turtle2坐标系的父级。 view_frames还报告一些诊断信息,这些信息有关何时接收到最旧和最新的坐标系转换,以及将tf2帧发布到tf2进行调试的速度。
4.2使用tf_echo
tf_echo报告通过ROS广播的任何两个坐标系之间的转换关系。
用法:
rosrun tf tf_echo [reference_frame] [target_frame]
让我们看一下turtle2坐标系相对于turtle1坐标系的变换:
rosrun tf tf_echo turtle1 turtle2
移动乌龟,可以看到他们的位置变换,静止时为0:
5.rviz和tf2
rviz是一种可视化工具,可用于检查tf2坐标系。 看看通过rviz的turtle坐标系。 让我们使用turtle_tf2配置文件,使用rviz的-d选项启动rviz。
rosrun rviz rviz -d `rospack find turtle_tf2`/rviz/turtle_rviz.rviz
将鼠标选中显示乌龟的终端,按方向键就可以在rviz中看到框架的移动。
回到标题一,继续介绍tf2的作用以及为什么使用tf2:
机器人系统通常具有许多随时间变化的三维坐标系,例如世界坐标系、基础坐标系、夹具坐标系、头部坐标系等。tf2随时间跟踪所有的这些坐标系,并可以解答下列问题:
①在5秒之前,头部坐标系相对于世界坐标系在哪;
②我抓手中的物体相对于我的底座的姿态是什么;
③地图坐标系中的基础坐标系当前位姿是什么。
tf2 可以在分布式系统中运行。 这意味着有关机器人坐标系的所有信息都可用于系统中任何计算机上的所有 ROS 组件。 Tf2 可以与包含所有转换信息的中央服务器一起运行,或者您可以让分布式系统中的每个组件构建自己的转换信息数据库。
二.教程
ROS创建了一组教程,逐步指导您使用 tf2。 有关所有 tf2 和 tf2 相关教程的完整列表,请查看教程页面。任何用户都可以使用 tf2 来完成两个任务,监听转换和广播转换。
教程参考网页:
tf2/Tutorials - ROS Wikihttp://wiki.ros.org/tf2/Tutorials/
三.概述
1.支持的数据类型
tf2 实现模板化数据类型支持。 这允许核心包具有最小的依赖关系,并且有一些包增加了对不同数据类型的转换以及转换这些数据类型的支持。 tf2 转换方法也支持多种不同数据类型之间的转换和转换。
tf2 的核心依赖于标记数据类型,这些数据类型可以方便地与具有 Messages#Header 的 ROS 消息相关联。
1.1数据类型支持包
这些包提供了允许 tf2 本地处理任何外部库的数据类型的方法。 大多数都是特定于 C++ 或 Python 的。
①tf2_bullet tf2 方法在 C++ 中本机处理项目符号数据类型;
②tf2_eigen tf2 方法在 C++ 中本机处理 Eigen 数据类型;
③tf2_geometry_msgs 在 C++ 或 Python 中原生使用 geometry_msgs 数据类型的 tf2 方法;
④tf2_kdl tf2 方法在 c++ 或 python 中本地处理 kdl 数据类型;
⑤tf2_sensor_msgs 在 C++ 或 Python 中原生使用 sensor_msgs 数据类型的 tf2 方法。
2.坐标系约定
使用 tf2 的一个重要部分是使用坐标系的标准约定。 使用坐标系有多种约定来源:
①REP 103 涵盖了单位、方向约定、手性、旋转表示和协方差表示 ;
②REP 105 涵盖了移动基础坐标系的标准名称 ;
③人形机器人的标准坐标系在 REP 120 中 ;
④有关使用的一些数学术语的定义,请参阅tf2/Terminology - ROS Wiki页面。
2.1 命名
ROS 中的坐标系由字符串 frame_id 标识,格式为小写下划线分隔。 该字符串在系统中必须是唯一的。 生成的所有数据都可以简单地识别它的 frame_id 来说明它在世界上的位置。
没有 tf_prefix:在以前的版本中,有一个 tf_prefix 的概念,它将使用 / 分隔符添加到坐标系名称之前。 一个前导斜杠用于表示它已经被添加了前缀。 为了向后兼容,tf2 将删除任何前导 / 字符。
没有重新映射: tf frame_ids 的概念与 ROS 名称的范围不同。 特别是,命名计算图的特定子部分不会改变 tf 树所代表的物理布局。 因此 frame_ids 不遵循命名空间重新映射规则。 通常支持 ROS 参数以允许更改算法中使用的 frame_id。
多个机器人: 对于具有多个机器人的用例,通常建议使用多个主机并在机器人之间转发特定的 tf 信息。 有几种不同的方法可以在主节点之间实现桥接。 有关更多信息,请参阅sig/Multimaster - ROS Wiki。
3. 工具
①tf2 包是核心功能的独立于 ROS 的实现。 如果消息数据类型被复制出来,这可以在 ROS 之外使用;
②tf2_tools 提供了许多在 ROS 中使用 tf2 的工具。
4. 几何学
tf2 提供了基本的几何数据类型,例如 Vector3、Matrix3x3、Quaternion、Transform。 这些数据类型支持彼此之间的线性代数运算。
5. ROS绑定
这些包为使用 tf2 的开发人员提供了主要接口。
①tf2_ros 为 tf2 提供 roscpp 绑定,包括 BufferListener、BufferBroadcaster、BufferServer 和 BufferClient 的类 ;
②tf2_ros 还为 tf2 提供了 rospy 绑定,包括 BufferListener BufferBroadcaster 和 BufferClient 的类。
6. 从tf迁移
有关从 tf 迁移的更多信息,请参阅tf2/Migration - ROS Wiki。
7.添加静态转换支持
静态转换的目标是消除重新传达不变事物的需要。 更新值的功能是在它们受到不确定性影响的情况下实现的,并且以后可能会使用改进的值重新估计。 但重要的是,这些更新后的值在任何时候都应该是正确的。
转换的添加和删除是有问题的,特别是因为假设始终为真。 如果您有一个由静态变换表示的可拆卸臂,并且您经历了 1) 安装、2) 移除、3) 安装 4) 用臂移除的过程。
如果您在 t=1 和 3 处添加静态变换并在 t=2 和 4 处删除变换。任何从抓手到身体的变换查询都应使用 1.5 的时间戳。 但是,如果该查询是在 t=1 和 t=2 之间进行的,它将通过,但由于静态转换被删除,时间戳为 t=1.5 的先前工作查询将在 t=2 处中断。 另一个问题成立。 在 t=2.5 时,变换不应该查找,但是如果在时间 t=3.5 查询,如果使用静态变换,则在时间戳 2.5 处的查找将通过。
如果您通过更改连通性来破坏树,也会产生这些不正确的结果。 如果您有一个来来往往的框架,您应该真正使用标准框架并以适当的低速率发布它,该速率适合捕获更改机器人拓扑的预期频率。
静态转换与常规转换的最大不同之处在于它们不保留时间历史。这主要节省了存储和查找时间,尽管发布开销也更好。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)