tf变换(1)

本文涉及的产品
资源编排,不限时长
简介: TF库的目的是实现系统中任一个点在所有坐标系之间的坐标变换,也就是说,只要给定一个坐标系下的一个点的坐标,就能获得这个点在其他坐标系的坐标. 使用tf功能包,a. 监听tf变换: 接收并缓存系统中发布的所有参考系变换,并从中查询所需要的参考系变换。

TF库的目的是实现系统中任一个点在所有坐标系之间的坐标变换,也就是说,只要给定一个坐标系下的一个点的坐标,就能获得这个点在其他坐标系的坐标.

 使用tf功能包,a. 监听tf变换: 接收并缓存系统中发布的所有参考系变换,并从中查询所需要的参考系变换。

                         b.广播 tf变换: 向系统中广播参考系之间的坐标变换关系。系统中更可能会存在多个不同部分的tf变换广播,每个广播都可以直接将参考系变换关系直接插入tf树中,不需要再进行同步。

 

首先介绍关于TF的API的一些数据结构:

基本的数据类型有(Quaternion, Vector, Point, Pose, Transform)

  

这其中Quaternion 是表示四元数,vector3是一个3*1 的向量,point是一个表示一个点坐标,Pose是位姿(位姿是包括坐标以及方向) Transform是一个转换的模版

tf::Stamped <T>

是一种包含了除了Transform的其他几种基本的数据结构的一种数据结构:

template <typename T>    //模版结构可以是tf::Pose tf:Point 这些基本的结构
class Stamped : public T{
 public:
  ros::Time stamp_;    //记录时间
  std::string frame_id_;   //ID

  Stamped() :frame_id_ ("NO_ID_STAMPED_DEFAULT_CONSTRUCTION"){}; //Default constructor used only for preallocation

  Stamped(const T& input, const ros::Time& timestamp, const std::string & frame_id);
  
  void setData(const T& input);
};

tf::StampedTransform

TF::stampedtransform是TF的一种特殊情况:它需要frame_id和stamp以及child_frame_id。

/** \brief The Stamped Transform datatype used by tf */
class StampedTransform : public tf::Transform
{
public:
  ros::Time stamp_; ///< The timestamp associated with this transform 时间戳                                                                                                                                                                                                                                                       
  std::string frame_id_; ///< The frame_id of the coordinate frame  in which this transform is defined  定义转换坐标框架的frameID                                                                                                                                                                                                                    
  std::string child_frame_id_; ///< The frame_id of the coordinate frame this transform defines 的坐标系变换定义的id                                                                                                                                                                                                                            
  StampedTransform(const tf::Transform& input, const ros::Time& timestamp, const std::string & frame_id, const std::string & child_frame_id):
    tf::Transform (input), stamp_ ( timestamp ), frame_id_ (frame_id), child_frame_id_(child_frame_id){ };

  /** \brief Default constructor only to be used for preallocation */
  StampedTransform() { };

  /** \brief Set the inherited Traonsform data */
  void setData(const tf::Transform& input){*static_cast<tf::Transform*>(this) = input;};

};

 举个例子

在机器人的定位领域有蒙特卡罗定位(AMCL)的算法,这个算法是根据给定的地图,结合粒子滤波获取最佳定位点Mp,这个定位点是相对于地图map上的坐标,也就是base_link(也就是机器人的基坐标)相对map上的坐标。我们知道 odom 的原点是机器人启动时刻的位置,它在map上的位置或转换矩阵是未知的。但是AMCL可以根据最佳粒子的位置推算出 odom->map(就是说通过最佳粒子推算出机器人在地图的中的位置)的tf转换信息并发布到 tf主题上。因为base_link->odom的tf转换信息是每时每刻都在发布的,所以它是已知的

,所以这里有个这样的tf关系

map->base_link(就是地图中机器人的位置  是根据最佳粒子推算的)

base_link->odom(这是现实中机器人的位姿可以说是里程计的信息)

可以理解:机器人的里程计的信息 = 当前地图中的机器人的的位置    减去  地图中机器人的起点位置。

 转为公式可以写成 :map->odom = map->base_link   -  base_link->odom

或者写为:

 base_link->odom = map->base_link - map->odom  (这样更容易理解)

提示:首先我们可以先了解关于PRY这三个概念关于pitch yaw roll的博客 http://blog.csdn.net/yuzhongchun/article/details/22749521

pitch是围绕X轴旋转,也叫做俯仰角,

yaw是围绕Y轴旋转,也叫偏航角,

roll是围绕Z轴旋转,也叫翻滚角

1.    ROS_DEBUG("New pose: %6.3f %6.3f %6.3f",  
2.             hyps[max_weight_hyp].pf_pose_mean.v[0],  
3.             hyps[max_weight_hyp].pf_pose_mean.v[1],  
4.             hyps[max_weight_hyp].pf_pose_mean.v[2]);  
5.     // hyps[max_weight_hyp].pf_pose_mean.v[0], [1], [2] 就代表了Mp  也就是机器人的位姿那么位姿的格式是(x,y,theta)最后一个是yaw偏航角,
6.    // subtracting base to odom from map to base and send map to odom instead  
7.    tf::Stamped<tf::Pose> odom_to_map;  
8.    try  
9.    {  
10.      tf::Transform tmp_tf(tf::createQuaternionFromYaw(hyps[max_weight_hyp].pf_pose_mean.v[2]),   tf::Vector3(hyps[max_weight_hyp].pf_pose_mean.v[0],  
11.                                       hyps[max_weight_hyp].pf_pose_mean.v[1],  
12.                                       0.0));  
13.    // tmp_tf = 从map原点看base_link的位置  为yaw生成四元数,最后的0.0是(x,y,z)的Z的值为0  因为这是在二维平面中。
14.      tf::Stamped<tf::Pose> tmp_tf_stamped (tmp_tf.inverse(),  
15.                                            laser_scan->header.stamp,  
16.                                            base_frame_id_);  
17.    //tmp_tf.inverse()  = 以为Mp为坐标的原点,地图map原点相对于Mp的位置,就是在base_link坐标系下map 原点的位置
18.      this->tf_->transformPose(odom_frame_id_,  
19.                               tmp_tf_stamped,  
20.                               odom_to_map); 
21.     //进行 base_link坐标系下的点转换到odom坐标系,也就是把map原点转换到odom坐标系下,等于从odom原点看map原点的位置。放到latest_tf_变量里面
22.    }  
23.    catch(tf::TransformException)  
24.    {  
25.      ROS_DEBUG("Failed to subtract base to odom transform");  
26.      return;  
27.    }  

 

TF命令行工具

(1) tf_monitor工具的功能是打印tf树中的所有参考系信息,通过输入参数来查看指定参考系之间的信息  用法: rosrun tf tf_monitor

  tf_monitor <source_frame> <target_target>  监视一个特定的转换 For example, to monitor the transform from /base_footprint to /odom:

  (2) tf_echo工具的功能是查看指定参考系之间的变换关系。命令的格式: tf_echo <source_frame> <target_frame>

 (3)static_transform_publisher工具的功能是发布两个参考系之间的静态坐标变换,两个参考系一般不发生相对位置变化

(4)view_frames 是可视化的调试工具,可以生成pdf文件,来显示整棵tf树的信息。用法:rosrun tf view_frames 

 

具体可以查看http://wiki.ros.org/tf/

博客园的编辑界面真实难以编辑啊  受不鸟了  所以还是不写了  转向CSDN了

 

相关实践学习
使用ROS创建VPC和VSwitch
本场景主要介绍如何利用阿里云资源编排服务,定义资源编排模板,实现自动化创建阿里云专有网络和交换机。
阿里云资源编排ROS使用教程
资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。编排模板同时也是一种标准化的资源和应用交付方式,并且可以随时编辑修改,使基础设施即代码(Infrastructure as Code)成为可能。 产品详情:https://www.aliyun.com/product/ros/
相关文章
|
7月前
|
编解码 监控 算法
3D-Genome | Hi-C互作矩阵归一化指南
3D-Genome | Hi-C互作矩阵归一化指南
178 2
|
4月前
|
存储 机器学习/深度学习 算法框架/工具
张量(Tensor)、标量(scalar)、向量(vector)、矩阵(matrix)
张量(Tensor)、标量(scalar)、向量(vector)、矩阵(matrix)
72 1
|
6月前
|
存储 机器学习/深度学习 PyTorch
Pytorch-张量形状操作
PyTorch中,张量形状操作至关重要,如reshape用于改变维度而不变元素,transpose/permute用于维度交换,view改形状需内存连续,squeeze移除单维度,unsqueeze添加维度。这些函数帮助数据适应神经网络层间的转换。例如,reshape能调整数据适配层的输入,transpose用于矩阵转置或多维排列,而squeeze和unsqueeze则用于处理单维度。理解并熟练运用这些工具是深度学习中必要的技能。
|
计算机视觉
OpenCV-矩阵变形reshape
OpenCV-矩阵变形reshape
173 0
|
计算机视觉
OpenCV-矩阵归一化cv::normalize
OpenCV-矩阵归一化cv::normalize
112 0
|
PyTorch 算法框架/工具
torch,如何将两个二维张量,按照第一维度,合并
在这个例子中,torch.cat() 函数的第一个参数是一个列表,包含要拼接的张量 x 和 y,第二个参数是拼接的维度,即第一维度。拼接后的张量 z 的形状为 (6, 4),因为两个原始张量的第一维度都是 3,拼接后就变成了 6。
749 0
|
存储 PyTorch 算法框架/工具
pytorch 如何按行计算tensor张量的二范数
在 PyTorch 中,可以使用 torch.norm(input, dim=1) 函数来按行计算张量的二范数。具体来说,input 是一个张量,dim=1 表示按照行的方向计算二范数。
674 0
|
数据采集 机器学习/深度学习
tebsorflow2.0 tf.keras序列问题
本节是主要介绍的是序列问题的处理,采用的数据集为电影评论数据集,我们通过keras.datasets.imdb直接导入,之后我们建立模型,对其进行分类,并处理过拟合问题。
135 0
tebsorflow2.0 tf.keras序列问题
|
机器学习/深度学习 PyTorch 算法框架/工具
np.ndarray与torch.Tensor之间的转化 (图像的区别)
np.ndarray与torch.Tensor之间的转化 (图像的区别)
成功解决基于model利用plot_importance()函数出现仅输出一个、两个或者三个等特征(极少的特征)
成功解决基于model利用plot_importance()函数出现仅输出一个、两个或者三个等特征(极少的特征)
成功解决基于model利用plot_importance()函数出现仅输出一个、两个或者三个等特征(极少的特征)