一.  tf::StampedTransform <-------------> Eigen::Matrix4f

tf::StampedTransform是ros里代表TF变换的数据类型,一般在机器人上读取雷达坐标系到机器人坐标系的信息就是通过读取tf信息.

tf::StampedTransform transform; //雷达到机器人的静态变换 tf

然后就是另一种位姿(也就是变换矩阵)的表示方式, Eigen::Matrix4f是4*4的变换矩阵,包括平移和旋转.

 Eigen::Matrix4f tf_btol;

以下是这两种数据格式之间的转换:

由transform获取位移矩阵:Eigen::Translation3f  (3 * 3)

Eigen::Translation3f tl_btol(transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ());

旋转通过以下形式从TF获得:

Eigen::AngleAxisf rot_x_btol(roll, Eigen::Vector3f::UnitX());   //轴角表达形式

Eigen::AngleAxisf rot_y_btol(pitch, Eigen::Vector3f::UnitY());

Eigen::AngleAxisf rot_z_btol(yaw, Eigen::Vector3f::UnitZ());

tf_btol = (tl_btol * rot_z_btol * rot_y_btol * rot_x_btol).matrix(); //雷达到机器人的静态变换矩阵   平移*旋转

这样就从TF变换转换到了变换矩阵.

下面是完整的程序:

tf::TransformBroadcaster tf_broadcaster;
tf::TransformListener tf_listener;
tf::StampedTransform transform;  //雷达到机器人的静态变换 tftry{ros::Time now = ros::Time::now();ROS_INFO("now:%f listen from static_tf and set tf_btol");tf_listener.waitForTransform(param_base_frame, param_laser_frame, ros::Time(0), ros::Duration(param_tf_timeout * 10), ros::Duration(param_tf_timeout / 3));tf_listener.lookupTransform(param_base_frame, param_laser_frame, ros::Time(0), transform);ROS_INFO("success listen from tf");}catch (const tf::TransformException &ex){ROS_ERROR("Error waiting for tf in init: %s", ex.what());return;}Eigen::Translation3f tl_btol(transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ());double roll, pitch, yaw;tf::Matrix3x3(transform.getRotation()).getEulerYPR(yaw, pitch, roll);Eigen::AngleAxisf rot_x_btol(roll, Eigen::Vector3f::UnitX());Eigen::AngleAxisf rot_y_btol(pitch, Eigen::Vector3f::UnitY());Eigen::AngleAxisf rot_z_btol(yaw, Eigen::Vector3f::UnitZ());tf_btol = (tl_btol * rot_z_btol * rot_y_btol * rot_x_btol).matrix();  //雷达到机器人的静态变换矩阵tf_ltob = tf_btol.inverse();  //机器人到雷达的静态变换矩阵

二. Eigen::Matrix4f<-------------> pose

一般我们通过点云匹配或者里程计产生的都是运动表达形式 都是变换矩阵(Eigen::Matrix4f )形式,但是我们在实际使用中更多是直观的使用 平移 x, y, z和旋转 roll, pitch, yaw  这些直接数据.所以要将得到的变换矩阵转换成 自定义的pose格式,也就是将 x ,y ,z roll, pitch, yaw 信息提取出来.

一般在程序中我们自己定义一个相对直观的位姿表示结构体:

struct pose

{

double x, y, z;

double pitch, roll, yaw;

...... //一些其他成员函数

}

pose localizer_pose;  //定义一个 pose结构体实例Eigen::Matrix4f t_localizer(Eigen::Matrix4f::Identity());     //ndt定位产生的变换矩阵      4*4tf::Matrix3x3 mat_l,;   // 旋转变换矩阵,作为转换的中间量,  来求rpy转换角度mat_l.setValue(static_cast<double>(t_localizer(0, 0)), static_cast<double>(t_localizer(0, 1)),static_cast<double>(t_localizer(0, 2)),static_cast<double>(t_localizer(1, 0)),static_cast<double>(t_localizer(1, 1)), static_cast<double>(t_localizer(1, 2)),static_cast<double>(t_localizer(2, 0)), static_cast<double>(t_localizer(2, 1)),static_cast<double>(t_localizer(2, 2)));// Update localizer_pose. // 更新局部下的坐标localizer_pose.x = t_localizer(0, 3);localizer_pose.y = t_localizer(1, 3);localizer_pose.z = t_localizer(2, 3);mat_l.getRPY(localizer_pose.roll, localizer_pose.pitch, localizer_pose.yaw, 1);

以上就将Eigen::Matrix4f 的变换矩阵 转换成了 pose,我们可以从pose直接获取平移 x, y, z和旋转 roll, pitch, yaw 

三. 将位姿通过 tf::TransformBroadcaster 发送出去

我们一般直接获取到的转换形式是上文的 变换矩阵形式(Eigen::Matrix4f),首先我们要将变换矩阵根据上文转换成 Pose格式,然后再将Pose通过一下步骤转换为 tf::StampedTransform:

pose current_pose;  //得到的Posetf::StampedTransform transform_broadcastertransform_broadcaster.setOrigin( tf::Vector3(current_pose.x, current_pose.y, current_pose.z) );    //设置平移tf::Quaternion q;
q.setRPY(current_pose.roll, current_pose.pitch, current_pose.yaw);  //欧拉角 -->>四元数transform_broadcaster.setRotation(q);    //TF 的transform 必须从四元数获取旋转信息//四元数 -->> 欧拉角
tf::Quaternion quat;
tf::quaternionMsgToTF(odom.pose.pose.orientation, quat);
double roll, pitch, yaw;   //定义存储r\p\y的容器
tf::Matrix3x3(quat).getRPY(roll, pitch, yaw);//进行转换

几种位姿转换表示方式----tf::StampedTransform Eigen::Matrix4f Pose, 及其相互转换相关推荐

  1. 【Eigen和tf中位姿表达方式转换】【tf::StampedTransform】【Eigen::Matrix4f】

    [tf的使用][Eigen和tf中位姿表达方式转换][tf::StampedTransform][Eigen::Matrix4f] 0 前言 1 tf::StampedTransform<--& ...

  2. 数据预处理(17)_坐标转换,tf::StampedTransform =」 Eigen::Matrix4f

    在开发的过程中,通常会遇到坐标转换的问题,比如从传感器坐标系src,到车体坐标系ref.通常可以分为3步: 第一步:监听TF bool getTF(const ros::Time&query_ ...

  3. TF之RNN:TF的RNN中的常用的两种定义scope的方式get_variable和Variable

    TF之RNN:TF的RNN中的常用的两种定义scope的方式get_variable和Variable 目录 输出结果 代码设计 输出结果 代码设计 # tensorflow中的两种定义scope(命 ...

  4. ROS中的tf与Eigen的转换

    写ROS程序时会经常遇到tf与Eigen库的转换,即算法中大多会使用Eigen来进行运算和表示机器人的位姿,但是最终需要tf将pose发布出去,所以需要将Eigen表示的pose转换为tf以及相应的m ...

  5. java.io几种读写文件的方式

    一.Java把这些不同来源和目标的数据都统一抽象为数据流. Java语言的输入输出功能是十分强大而灵活的. 在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作 ...

  6. 在计算机系统中有两种不同的图像编码方式,第二章计算机系统与计算原理.ppt...

    第二章计算机系统与计算原理 大学计算机基础 * 信息表示与处理 ----西文字符 ASCII 码是美国信息交换标准代码(American Standard Code for Information I ...

  7. 一种网络进程间通信的方式—— 管道

    一种网络进程间通信的方式-- 管道 摘要: 文章主要介绍了计算机网络进程间通信的必要性以及进程间通信所采用的几种方式,重点说明了管道通信的原理及命名管道的实现方法. 关键词:管道 命名管道 进程 一. ...

  8. iOS五种本地缓存数据方式

    iOS五种本地缓存数据方式 iOS本地缓存数据方式有五种:前言 1.直接写文件方式:可以存储的对象有NSString.NSArray.NSDictionary.NSData.NSNumber,数据全部 ...

  9. jackson 复杂对象集合 的几种简单转换

    jackson 复杂对象集合 的几种简单转换 [java] view plaincopy package com; import java.io.BufferedReader; import java ...

最新文章

  1. 懒 人 世 界 的 生 存 法 则
  2. 中文-自然语言处理-开源工具-流行度调查+句法依存树可视化调研
  3. 为mysql数据库建立索引
  4. html左侧隐藏菜单栏,如何制作一个炫酷的隐藏侧边栏菜单
  5. [C++] vector 初始化
  6. 如何使用extern在源文件之间共享变量?
  7. 使用Visual Studio 2012 开发 Html5 应用
  8. 三大抽样分布、正态总体下的抽样分布
  9. C++配置OpenCv:一劳永逸
  10. 未来计算机源消能耗,磁微处理器挑战计算机最低能耗极限
  11. 如何提高迅雷下载速度
  12. android休闲游戏,休闲放松是王道 六款安卓休闲游戏推荐
  13. Alice and the List of Presents CodeForces - 1236B 数学推导
  14. CS61C Spring 2021——Project 3: CS61CPU要求及实现思路
  15. 影像变革之年 CP+2019展会五大看点
  16. php 拼团_详解在微信公众平台里实现微信拼团功能的步骤
  17. 什么力量推动了互联网的进化
  18. 牛客网sql练习笔记(二)
  19. HEX文件格式解析(转)
  20. 使用普通账户安装 Redis 服务

热门文章

  1. 证券量化交易平台-接入业务:SpringBoot 集成Apama
  2. 解读什么是千人千面算法、猜你喜欢、个性化推荐算法,
  3. HTML--a标签的herf属性
  4. C++ 学习(15)文件操作、文件文件读与写操作、二进制文件读与写操作
  5. 二叉树 性质和相关公式
  6. 使用邻接列表简单实现PageRank算法(C++)
  7. DNA甲基化与癌症、泛癌早筛 | DNA methylation and pan-cancer
  8. 生成PL设备树及动态加载PL程序和设备树
  9. <iomanip>库输入输出控制函数
  10. webrtc的pacing分析