ROS学习--轻松使用tf

2023-05-16

tf是ROS中建立坐标系,并且使用各个坐标间转换关系的一个很好的工具,对于非导航专业的同学,常常苦恼与各种旋转矩阵的变换,自己经常被搞的头大,最近由于课题实验的需要,尝试使用tf,对此有了一个初步的了解。很多已经接触ROS有一段时间的朋友,可能都没有真正使用过tf,因为从官方给的例程看起来好像非常繁琐,所以也就不想使用,但是最近一段时间的学习发现,其实真正有用程序的就仅仅几句,所以其实非常简单。

一.广播tf

其实就是发布你建立的坐标系。步骤如下:
1.定义一个广播,相当于发布话题时定义一个发布器,还是以官方的小乌龟例程为例:
http://wiki.ros.org/tf/Tutorials/Writing%20a%20tf%20broadcaster%20%28C++%29

static tf::TransformBroadcaster br;

2.定义存放转换信息(平动,转动)的变量

tf::Transform transform;

3.设置坐标原点

transform.setOrigin( tf::Vector3(msg->x, msg->y, 0.0) );

需要注意:
(1)setOrigin()函数的参数类型需要为tf::Vector3类型
(2)假设是要发布一个子坐标系为”turtle1”父坐标系为“world”,那么其中(msg->x,msg->y,0.0)是指“turtle1”的坐标原点在“world”坐标系下的坐标。
4.定义旋转

 tf::Quaternion q;
  q.setRPY(0, 0, msg->theta);
  transform.setRotation(q);

需要注意:
(1)setRPY()函数的参数为”turtle1”在“world”坐标系下的roll(绕X轴),pitch(绕Y轴),yaw(绕Z轴)
(2)为了确保转换正确强烈建议,在转换完后,运行下程序,打开rviz下使用确认下转换是否正确,我在实验中有一次,明明依次填入了三个角度,但是在rviz下发现并不正确,pitch,yaw还存在一个负号的关系(楼主对旋转角的正负号向来头晕,所以都是直接打开rviz,直接试,直观而且准确)。
5.将变换广播出去

br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", turtle_name));

其中,
(1)transform:存储变换关系的变量;
(2)ros::Time::now():广播tf使的时间戳;
(3)“world”:父坐标系的名字;
(4)turtle_name:子坐标系的名字,这里因为子坐标系有两个,所以它定义了字符串用于存放名字,方便切换,通常我们把名字填到引号里就可以了。
总结一下,假设你在机器人上应用,如果你知道机器人的位置x,y,z,与三个旋转角roll,pitch,yaw就可以广播一个tf了,如果在是平面移动机器人,则只需要知道x,y与yaw即可。

二.监听tf

通过监听tf,我们可以避免繁琐的旋转矩阵的计算,而直接获取我们需要的相关信息。
在监听中我最常用两个函数:
(1)lookupTransform();
(2)transformPoint();
(一)lookupTransform();函数的使用
1.函数功能:可以过得两个坐标系之间转换的关系,包括旋转与平移。
2.使用例程:http://wiki.ros.org/tf/Tutorials/Writing%20a%20tf%20listener%20%28C++%29
3.主要步骤:
(1)定义监听器;

tf::TransformListener listener

(2)定义存放变换关系的变量

 tf::StampedTransform transform;

(3)监听两个坐标系之间的变换

   try{
      listener.lookupTransform("/turtle2", "/turtle1",
                               ros::Time(0), transform);
    }
    catch (tf::TransformException &ex) {
      ROS_ERROR("%s",ex.what());
      ros::Duration(1.0).sleep();
      continue;
    }

注意:
A.由于tf的会把监听的内容存放到一个缓存中,然后再读取相关的内容,而这个过程可能会有几毫秒的延迟,也就是,tf的监听器并不能监听到“现在”的变换,所以如果不使用try,catch函数会导致报错:

“world” passed to lookupTransform argument target_frame does not exist. ”

并且会导致程序挂掉,使用try,catch之后就OK了。

B.lookupTransform()函数参数说明
a.官网的例程说的是实现从“/turtle2”到“/turtle1”的转换,但实际中使用时,我发现转换得出的坐标是在“/turtle2”坐标系下的
b.不可以把ros::Time(0)改成ros::time::now(),因为监听做不到实时,会有几毫秒的延迟。ros::Time(0)指最近时刻存储的数据,ros::time::now()则指当下,如果非要使用ros::time::now,则需要结合waitForTransform()使用,具体见:
http://wiki.ros.org/tf/Tutorials/tf%20and%20Time%20%28C++%29
实际中ros::Time(0)大多数情况下可以满足要求。
c.最后转换关系存入transform中

(4)使用变换
通常我们使用的是点的信息

transform.getOrigin().x()
transform.getOrigin().y(),  

可以得到在turtle1坐标系的原点,在turtle2坐标系下的位置。

transform.getRotation().getW();
transform.getRotation().getX();
transform.getRotation().getY();
transform.getRotation().getZ();

可以得到旋转的四元数,如何直接得到偏航角因为没有用到这个功能所以也就没有去找相关的函数。

(二)transformPoint()函数使用
在实际应用中我们肯定会需要把在一个坐标系下的点转换到另一个坐标系下,这就需要transformPoint()函数。
1.函数功能:将一个坐标系下的点的坐标转换到另一个坐标系下。
2.函数参数:如

listener_.transformPoint("PTAM_world",m_normal_pose,pose_PTAM_world);

(1)其中m_normal_pose数据类型为 geometry_msgs::PointStamped,
其中需要定义m_normal_pose.header.frame_id即该点所属的坐标系
(2)而“PTAM_world”则指,我要将m_normal_pose转换到“PTAM_world”坐标系下。
pose_PTAM_world是转换的结果,数据类型同样为geometry_msgs::PointStamped。
3.使用例程:

geometry_msgs::PointStamped turtle1;
turtle1.header.stamp=ros::Time();
turtle1.header.frame_id="turtle1";
turtle1.point.x=1;
turtle1.point.y=2;
turtle1.point.z=3;
geometry_msgs::PointStamped turtle1_world;
        try{
listener_.transformPoint("PTAM_world",turtle1,turtle1_world);
         }
             catch (tf::TransformException &ex) {
          ROS_ERROR("%s",ex.what());
          ros::Duration(1.0).sleep();
    }

说明:同样因为延时,turtle1.header.stamp不能为ros::Time::now();否则会出类似错误

[ERROR] [1456669076.279804500]: Lookup would require extrapolation into the future. Requested time 1456669076.279616253 but the latest data is at time 1456669076.159341977, when looking up transform from frame …

总结,只有开始使用tf了才能逐渐感受到它的方便,另外再建议tf一定要与rviz结合使用,真的直观又方便。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS学习--轻松使用tf 的相关文章

  • ros 样例代码和教程

    中国大学MOOC 机器人操作系统入门 课程代码示例 代码 https github com DroidAITech ROS Academy for Beginners 书 https legacy gitbook com book sych
  • 使用WTGAHRS2(JY-GPSIMU)在ROS中读取数据并发布话题

    目录 IMU简介 驱动程序 IMU串口通信协议 程序 效果 IMU简介 十轴惯性导航传感器WTGAHRS2传感器集成高精度的陀螺仪 加速度计 地磁场传感器 GPS 模块 采用高性能的微处理器和先进的动力学解算与卡尔曼动态滤波算法 能够快速求
  • ROS与navigation教程——ACML参数配置

  • SLAM-hector_slam 简介与使用

    hector slam功能包使用高斯牛顿方法 不需要里程计数据 只根据激光信息便可构建地图 所以他的总体框架如下 hector slam功能包 hector slam的核心节点是hector mapping 它订阅 scan 话题以获取SL
  • ros 中ERROR: cannot download default sources list from: https://raw.githubusercontent.com/ros/rosdist

    ros 中ERROR cannot download default sources list from https raw githubusercontent com ros rosdistro master rosdep sources
  • ROS诸多调试工具总结1

    ROS有许多调试工具来为ROS调试你的工具 1 rosnode 参数 用法 作用 list rosnode list 查看当前运行了哪些节点 info rosnode info node name 查看该节点发布 接受哪些话题以及服务 ki
  • V-REP安装

    小知识 是当前目录 是父级目录 是根目录 1 下载V REP 官网地址 http www v rep eu downloads html 我用ubuntu16 04下载V REP PRO EDU V3 5 0 Linux tar 2 解压安
  • 关于相机与激光雷达数据采集与标定

    最近在做一个关于车路协同的项目 需要做一个路侧系统 传感器有摄像头和激光雷达 相机和激光雷达联合标定费了老半天劲 在此记录一下 雷达时间戳不对 导致摄像头和雷达的数据无法对齐 解决办法 修改雷达驱动发布点云消息时的时间戳 相机内参标定可以使
  • rosrun 和 roslaunch 的时候 TAB 的自动补全出现问题

    rosrun 和 roslaunch 的时候 TAB 的自动补全出现问题 rospack Warning error while crawling home sun boost filesystem status Permission de
  • Ubuntu16.04安装ROS Kinetic详细步骤

    文章目录 ROS安装 配置Ubuntu软件仓库 设置sources list 设置密钥 更新Debian软件包索引 安装ROS 初始化 rosdep 环境配置 构建工厂依赖 测试安装 开发环境 ROS安装 ROS Kinetic只支持Wil
  • Ubuntu下vscode配置ROS环境

    摘要 最近准备放弃用clion开发ROS使用更主流的vscode 整理一下在ubuntu18 04下的VSCode安装和ROS环境配置流程 安装 方法一 软件商店安装 个人还是推荐使用ubuntu软件下载vscode 简单不容易出错 方法二
  • Hypervisor介绍及在智能驾驶的应用

    转自Hypervisor 智能座舱和智能驾驶融合的关键技术 腾讯新闻
  • ROS 笔记(01)— Ubuntu 20.04 ROS 环境搭建

    ROS 官网 https www ros org ROS 中文官网 http wiki ros org cn 1 系统和 ROS 版本 不同的 ROS 版本所需的 ubuntu 版本不同 每一版 ROS 都有其对应版本的 Ubuntu 切记
  • 最快实现一个自己的扫地机

    作者 良知犹存 转载授权以及围观 欢迎关注微信公众号 羽林君 或者添加作者个人微信 become me 扫地机介绍 扫地机器人行业本质是技术驱动型行业 产品围绕导航系统的升级成为行业发展的主旋律 按功能划分 扫地机器人分为四大系统 即导航系
  • 服务数据的定义和使用

    1 自定义数据服务 在包下创建srv文件夹 在文件夹下创建Person srv 在Person srv下输入以下内容 代表数据类型 string name uint8 age uint8 sex uint8 unknown 0 uint8
  • 在 CLion 中设置 ROS 包

    我正在使用 CLion C IDE 来编辑 ROS 包 我可以通过打开CMakeLists txt文件 但是 我收到一个错误 FATAL ERROR find package catkin 失败 在工作区和 CMAKE PREFIX PAT
  • Kinect / Primesense (Xtion) ROS Ubuntu 通过虚拟机 (VMware)

    由于我花了相当长的时间才弄清楚如何让 Xtion Primesense 在 VMware 上工作 所以我想在这里与大家分享 使用 Kinect 时 即使 VMware 已成功连接该设备 我也无法让 ROS 查看该设备 roslaunch o
  • ROS中spin和rate.sleep的区别

    我是 ROS 新手 正在尝试了解这个强大的工具 我很困惑spin and rate sleep功能 谁能帮助我了解这两个功能之间的区别以及何时使用每个功能 ros spin and ros spinOnce 负责处理通信事件 例如到达的消息
  • 如何使用一个凉亭同时创建两个地图?

    如下图所示 现在我的gazebo正在运行2个slam gmapping包 首先是 turtlebot slam gmapping 发布到 map 主题 第二个是 slam gmapping 发布到与第一个相同的 map 主题 我想创建一个新
  • 安装 ROS 时 Cmake 未检测到 boost-python

    我一直在尝试在我的 Mac 上安装 ROS 并根据不同版本的 boost 使用不同的库解决了错误 然而 似乎有一个库甚至没有检测到 boost python 这是我得到的错误 CMake Error at usr local share c

随机推荐