1. 程式人生 > >tf樹 tf變換(1)

tf樹 tf變換(1)

tf變換(1)

 

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/

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/