轉:http://blog.csdn.net/akunainiannian/article/details/45103519 分類: 前面已經(jīng)介紹了如何使用URDF建造機器人小車并顯示在Rviz的仿真環(huán)境里面,但是小車是靜止的。下面介紹如何讓它在Rviz里面動起來,,并理清URDF,TF 和 odom 的關系,。 1. ROS中base_link, odom, fixed_frame, target_frame和虛擬大地圖map的關系一般在urdf文件中都要定義base_link,它代表了機器人的主干,,其它所有的frame都是相對于base_link定義并粘在一起的,。它們一起相對于大地圖map移動,讓機器人移動就是向tf發(fā)布 geometry_msgs::TransformStamped 消息通知ros base_linke相對于map的tf轉換關系,。先看一下這幾個概念在ros中的定義: map map是虛擬世界中的固定frame, 它的Z軸指向正上方,,也就是天空。一個時間點上移動機器人的姿態(tài)相對于map不應該出現(xiàn)明顯的漂移,。如果一個map是不連續(xù)穩(wěn)定的那就意味著機器人的位置在任何一個時間點上都會是變化的,。 一般激光地位儀等設備會連續(xù)的計算map的位置因而造成它的不穩(wěn)定性,這也使它不能成為一個好的參照體frame. odom odom是一個很好的固定世界參照frame.機器人的姿態(tài)相對odom而言是隨時間是經(jīng)??勺?,所以在長遠中它不是一個好的全局參照系。但在某一時間點而言它相對機器人的位置是不變的,。 典型的 odom frame 是通過運動源來計算出來的, 例如輪子運動,,視覺偏移等. odom frame 的準確性使它在局部參照系中是很有用的。但是不適合作全局參照frame. base_linkbase_link參照系緊緊粘在移動機器人基座上的任何一個位置和角度,。 各個Frames的關系frame之間是按樹狀結構組織的,。所以每個frame只有一個父節(jié)點和任意多個子節(jié)點。 上述幾個frame的關系: map --> odom --> base_link Frame Authoritiesodom到base_link的坐標轉換是從運動源計算出來廣播的,。 map到base_link的坐標轉換是被定位模塊計算出來的. 但定位模塊并不發(fā)布map到base_link的轉換. 相反它先接受從odom到base_link的轉換, 再計算并廣播map到odom的位置轉換關系,。 fixed_frameRViz中認定的大世界就是fixed_frametarget_frameRviz中視覺跟蹤的frame是 target_frame 2. RViz如何動態(tài)確定各個frame之間的坐標轉換先看一下啟動RViz的launch文件,里面定要了服務于RViz的參數(shù)和node "joint_state_publisher"節(jié)點獲取urdf里面定義的rotate link并發(fā)布坐標轉換給tf.否則會顯示warning. 注意:"joint_state_publisher" 是Python寫的,只支持ascii編碼,,不支持Unicode,,如果發(fā)現(xiàn)RViz報告下面錯誤: "No transform from [front_left] to [base_link]" 那就是因為urdf文件是Unicode編碼的。 3. geometry_msgs/TransformStamped 消息的作用和機構geometry_msgs/TransformStamped 就是通知ROS 兩個frame之間的tf轉換關系,。當兩個frame之間關系經(jīng)常變化,,如輪子移動,手臂關節(jié)移動等,,則需要編寫node來實時發(fā)布,。查看該消息結構:Transform其中transform就是我們關心的 tf 轉換關系,child_frame_id是"base_link", header.frame_id 則是'odom'. 查看geometry_msgs/transform: 這里的x, y, z 就定義了兩個frame的tf轉換關系,。 4. RViz中如何定義 base_link 和 odom 之間的 tf 坐標轉換要移動機器人,,就需要向tf發(fā)布geometry_msgs/TransformStamped 消息通知ros base_linke相對于map的tf轉換關系,也就是說告訴ROS運動的base_link相對于不動的odom位置偏移,。這里的odom frame并不能定義在urdf文件里面,,它是一個虛擬的,。我們只需要RViz知道fixed_frame就是odom就可以了。所以在urdf.rviz文件中這樣定義虛擬odom:如果現(xiàn)在啟動 RViz來觀察機器人: 肯定會得到錯誤警告,,而且RViz中無法顯示完整的機器人:"No transform from [odom] to [base_link]" 這個錯誤很容易理解,,沒有任何地方定義odom和base_link之間的tf關系,他們之間是連續(xù)變化的,,我們當然不能在任何地方寫固定偏移量定義tf transform. 但是我們可以寫一個node來不斷的發(fā)送geometry_msgs/TransformStamped消息,。被發(fā)送對象就是tf。 ROS官方有個實例完整代碼如何發(fā)布odom到base_link的變換,,代碼實例直接拷貝并在本地編譯,。這個例子不斷向odom主題發(fā)送消息更改odom與base_link之間的位移,位移的軌跡就是一個圓周,。這個node名字叫 odom_publisher. 它其實做了兩件事情: 1. 向 tf 發(fā)送geometry_msgs/TransformStamped 消息, 就是讓機器人運動起來,。 2. 向odom主題發(fā)送nav_msgs/Odometry導航消息,報告角速度,,線速度和巡航角度,。這部分代碼相對本文來講不是必須的。
再次打開RViz: 這次就看到機器人在地圖空間中做規(guī)則的圓周運動了! 因為RViz收到了odom_publisher向tf發(fā)送的坐標轉換內(nèi)容,。 4. RViz中觀察移動軌跡“ odom_publisher”中還向 odom主題發(fā)布了nav_msgs/Odometry導航消息,這樣就可以在RViz中顯示運動軌跡了,。在RViz中點擊 'add',,選中Odometry,配置該dispaly的topic為 "odom" 就可以看到不斷變化的運動軌跡了。這是因為nav_msgs/Odometry中包含了線速度,,角速度和巡航角度,,所以RViz可以顯示出來。 5.odom frame和 odom topic這兩個完全是不同的東西,,很容易混淆,。一個是地圖上的一個參照系,一個是topic用來接收導航輸入的,。名字一樣,,純屬巧合! |
|