博客參考:https://www.ncnynl.com/archives/201702/1312.html
ROS與C++入門教程-tf-增加坐標系
說明:
- 介紹如何為TF增加額外固定的坐標系
為何增加坐標系
- 對於許多任務,更容易在本地坐標內思考。
- 例如,更容易推斷在激光掃描器中心的坐標系中的激光掃描。
- tf允許您為系統中的每個傳感器,鏈接等定義一個本地坐標系。
- 並且,tf將處理所引入的所有額外坐標系的變換。
那里增加坐標系
- tf建立坐標系的樹結構; 它不允許在坐標系結構中存在閉環。
- 這意味着一個坐標系只有一個父系,但它可以有多個子系。
- 目前我們的tf樹包含三個坐標系:world,turtle1和turtle2。 兩只烏龜是世界的子系。
- 如果我們要向tf添加一個新坐標系,三個現有坐標系中的一個需要是父系,新坐標系將成為子系。
- 圖示:
如何添加坐標系
- 在我們的烏龜例子中,我們將添加一個新的坐標系carrot1到turtle1。
- 新建文件frame_tf_broadcaster.cpp:
$ roscd learning_tf $ touch src/frame_tf_broadcaster.cpp $ vim src/frame_tf_broadcaster.cpp
- 代碼如下:
#include <ros/ros.h> #include <tf/transform_broadcaster.h> int main(int argc, char** argv){ ros::init(argc, argv, "my_tf_broadcaster"); ros::NodeHandle node; tf::TransformBroadcaster br; tf::Transform transform; ros::Rate rate(10.0); while (node.ok()){ transform.setOrigin( tf::Vector3(0.0, 2.0, 0.0) ); transform.setRotation( tf::Quaternion(0, 0, 0, 1) ); br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "turtle1", "carrot1")); rate.sleep(); } return 0; };
- 代碼類似廣播變換
代碼解釋:
- 代碼:
transform.setOrigin( tf::Vector3(0.0, 2.0, 0.0) ); transform.setRotation( tf::Quaternion(0, 0, 0, 1) ); br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "turtle1", "carrot1")
- 解釋:我們創建transform,從父系turtle1到子系carrot1,carrot1離左邊的turtle12米遠
編譯運行
- 打開CMakeLists.txt
$ rosed learning_tf CMakeLists.txt
- 在底部增加代碼:
add_executable(frame_tf_broadcaster src/frame_tf_broadcaster.cpp) target_link_libraries(frame_tf_broadcaster ${catkin_LIBRARIES})
- 編譯:
$ cd ~/catkin_ws $ catkin_make
-
編譯順利,在bin目錄會生成frame_tf_broadcaster文件
-
編輯start_demo.launch
$ rosed learning_tf start_demo.launch
- 增加新代碼:
<launch> ... <node pkg="learning_tf" type="frame_tf_broadcaster" name="broadcaster_frame" /> </launch>
- 運行:
$ roslaunch learning_tf start_demo.launch
檢查結果:
- 接着上個教程的,如果你驅動turtle1,你注意到,即使我們添加了一個新的坐標系,行為沒有改變。 這是因為添加額外的坐標系不會影響其他坐標系,我們的監聽器仍然使用先前定義的坐標系。 所以,讓我們改變監聽器的行為。
- 編輯src/turtle_tf_listener.cpp,在26-27行用/carrot1替換/turtle1,如:
listener.lookupTransform("/turtle2", "/carrot1", ros::Time(0), transform);
- 編譯運行:
$ catkin_make $ roslaunch learning_tf start_demo.launch
- 應該可以看到,turtle2跟隨carrot1變化,而不是turtle1
廣播移動的坐標系
- 我們在本教程中發布的額外坐標系是一個固定的坐標系,不隨時間改變相對於父系。 但是,如果要發布移動坐標系,您可以更改廣播器以隨時間更改。 讓我們修改/carrot1坐標系以相對於/turtle1隨時間改變。
- 修改編輯src/turtle_tf_listener.cpp
$ vim src/frame_tf_broadcaster.cpp
- 代碼如下:
transform.setOrigin( tf::Vector3(2.0*sin(ros::Time::now().toSec()), 2.0*cos(ros::Time::now().toSec()), 0.0) ); transform.setRotation( tf::Quaternion(0, 0, 0, 1) );
- 編譯運行:
$ catkin_make $ roslaunch learning_tf start_demo.launch