天天看點

ROS 學習系列 -- RViz中移動機器人來學習 URDF,TF,base_link, map,odom和odom 主題的關系1. ROS中base_link, odom, fixed_frame, target_frame和虛拟大地圖map的關系fixed_frameRViz中認定的大世界就是fixed_frame target_frame

前面已經介紹了如何使用URDF建造機器人小車并顯示在Rviz的仿真環境裡面,但是小車是靜止的。下面介紹如何讓它在Rviz裡面動起來,并理清URDF,TF 和 odom 的關系。

1. ROS中base_link, odom, fixed_frame, target_frame和虛拟大地圖map的關系

一般在urdf檔案中都要定義base_link,它代表了機器人的主幹,其它所有的frame都是相對于base_link定義并粘在一起的。它們一起相對于大地圖map移動,讓機器人移動就是向tf釋出 geometry_msgs::TransformStamped 消息通知ros  base_linke相對于map的tf轉換關系。先看一下這幾個概念在ros中的定義:

map

map是虛拟世界中的固定frame, 它的Z軸指向正上方,也就是天空。一個時間點上移動機器人的姿态相對于map不應該出現明顯的漂移。如果一個map是不連續穩定的那就意味着機器人的位置在任何一個時間點上都會是變化的。

一般雷射地位儀等裝置會連續的計算map的位置因而造成它的不穩定性,這也使它不能成為一個好的參照體frame.

odom

odom是一個很好的固定世界參照frame.機器人的姿态相對odom而言是随時間是經常可變,是以在長遠中它不是一個好的全局參照系。但在某一時間點而言它相對機器人的位置是不變的。

典型的 odom frame 是通過運動源來計算出來的, 例如輪子運動,視覺偏移等.

odom frame 的準确性使它在局部參照系中是很有用的。但是不适合作全局參照frame.

base_link

base_link參照系緊緊粘在移動機器人基座上的任何一個位置和角度。

各個Frames的關系

frame之間是按樹狀結構組織的。是以每個frame隻有一個父節點和任意多個子節點。 上述幾個frame的關系:

map --> odom --> base_link

Frame Authorities

odom到base_link的坐标轉換是從運動源計算出來廣播的。

map到base_link的坐标轉換是被定位子產品計算出來的. 但定位子產品并不釋出map到base_link的轉換. 相反它先接受從odom到base_link的轉換, 再計算并廣播map到odom的位置轉換關系。

fixed_frame

RViz中認定的大世界就是fixed_frame

target_frame

Rviz中視覺跟蹤的frame是 target_frame

2. RViz如何動态确定各個frame之間的坐标轉換

先看一下啟動RViz的launch檔案,裡面定要了服務于RViz的參數和node

<launch>
    <arg name="model" />
    <arg name="gui" default="False" />
    <param name="robot_description" textfile="$(arg model)" />
    <param name="use_gui" value="$(arg gui)"/>
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
    <node name="rviz" pkg="rviz" type="rviz" args="-d $(find sp1s)/urdf.rviz" required="true" />
</launch>
           

"robot_description" 參數定義了urdf檔案的路徑,它被 robot_state_publisher節點使用。該節點解析urdf檔案後将各個frame的狀态釋出給tf. 是以在rviz裡面就看到各個frame(link)之間的tf轉換顯示OK.否則會顯示warning.

"joint_state_publisher"節點擷取urdf裡面定義的rotate link并釋出坐标轉換給tf.否則會顯示warning. 注意: "joint_state_publisher" 是python寫的,隻支援ascii編碼,不支援Unicode,如果發現RViz報告下面錯誤:

"No transform from [front_left] to [base_link]"

那就是因為urdf檔案是Unicode編碼的。

3. geometry_msgs/TransformStamped 消息的作用和機構

geometry_msgs/TransformStamped  就是通知ROS 兩個frame之間的tf轉換關系。當兩個frame之間關系經常變化,如輪子移動,手臂關節移動等,則需要編寫node來實時釋出。檢視該消息結構:

<span style="font-size:18px;">rosmsg show -r geometry_msgs/TransformStamped
# This expresses a transform from coordinate frame header.frame_id
# to the coordinate frame child_frame_id
#
# This message is mostly used by the 
# <a href="http://www.ros.org/wiki/tf" target="_blank" rel="external nofollow" >tf</a> package. 
# See its documentation for more information.

Header header
string child_frame_id # the frame id of the child frame
Transform <strong><span style="color:#FF0000;">transform</span></strong>

</span>
           

Transform 其中transform就是我們關心的 tf 轉換關系,child_frame_id是"base_link", header.frame_id 則是'odom'. 檢視geometry_msgs/transform:

rosmsg show -r geometry_msgs/Transform
# This represents the transform between two coordinate frames in free space.

Vector3 <strong><span style="color:#FF0000;">translation</span></strong>
Quaternion rotation

rosmsg show -r Vector3
[geometry_msgs/Vector3]:
# This represents a vector in free space. 

float64 x
float64 y
float64 z 
           

這裡的x, y, z 就定義了兩個frame的tf轉換關系。

4. RViz中如何定義 base_link 和 odom 之間的 tf 坐标轉換

要移動機器人,就需要向tf釋出geometry_msgs/TransformStamped 消息通知ros  base_linke相對于map的tf轉換關系,也就是說告訴ROS運動的base_link相對于不動的odom位置偏移。這裡的odom frame并不能定義在urdf檔案裡面,它是一個虛拟的。我們隻需要RViz知道fixed_frame就是odom就可以了。是以在urdf.rviz檔案中這樣定義虛拟odom:

<span style="font-size:18px;">Global Options:
    Background Color: 48; 48; 48
    Fixed Frame: <strong><span style="color:#FF0000;">/odom</span></strong>
    Target Frame: <Fixed Frame>
    Frame Rate: 30</span>
           

如果現在啟動 RViz來觀察機器人:

<span style="font-size:18px;">roslaunch sp1s display.launch model:=urdf/sp1s.urdf </span>
           

肯定會得到錯誤警告,而且RViz中無法顯示完整的機器人:

"No transform from [odom] to [base_link]"

這個錯誤很容易了解,沒有任何地方定義odom和base_link之間的tf關系,他們之間是連續變化的,我們當然不能在任何地方寫固定偏移量定義tf transform.

但是我們可以寫一個node來不斷的發送geometry_msgs/TransformStamped消息。被發送對象就是tf。 ROS官方有個執行個體完整代碼如何釋出odom到base_link的變換,代碼執行個體直接拷貝并在本地編譯。這個例子不斷向odom主題發送消息更改odom與base_link之間的位移,位移的軌迹就是一個圓周。這個node名字叫 odom_publisher. 它其實做了兩件事情:

1. 向 tf 發送geometry_msgs/TransformStamped 消息, 就是讓機器人運動起來。

2. 向odom主題發送nav_msgs/Odometry導航消息,報告角速度,線速度和巡航角度。這部分代碼相對本文來講不是必須的。

同"joint_state_publisher" node一樣,“ odom_publisher”需要在RViz啟動之前啟動,添加它的啟動項。修改後的dispaly.launch檔案:

<launch>
	<arg name="model" />
	<arg name="gui" default="False" />
	<param name="robot_description" textfile="$(arg model)" />
	<param name="use_gui" value="$(arg gui)"/>
        <strong><span style="color:#FF0000;"><node name="odom_publisher" pkg="sp1s" type="odom_publisher" /></span></strong>
        <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
	<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
	<node name="rviz" pkg="rviz" type="rviz"  args="-d  $(find sp1s)/urdf.rviz" required="true"/>
</launch></span>
           

再次打開RViz:

roslaunch sp1s display.launch model:=urdf/sp1s.urdf 
           

這次就看到機器人在地圖空間中做規則的圓周運動了! 因為RViz收到了odom_publisher向tf發送的坐标轉換内容。

4. RViz中觀察移動軌迹

“ odom_publisher”中還向 odom主題釋出了nav_msgs/Odometry導航消息,這樣就可以在RViz中顯示運動軌迹了。在RViz中點選 'add',選中Odometry,配置該dispaly的topic為 "odom" 就可以看到不斷變化的運動軌迹了。這是因為nav_msgs/Odometry中包含了線速度,角速度和巡航角度,是以RViz可以顯示出來。

ROS 學習系列 -- RViz中移動機器人來學習 URDF,TF,base_link, map,odom和odom 主題的關系1. ROS中base_link, odom, fixed_frame, target_frame和虛拟大地圖map的關系fixed_frameRViz中認定的大世界就是fixed_frame target_frame

5.odom frame和 odom  topic

這兩個完全是不同的東西,很容易混淆。一個是地圖上的一個參照系,一個是topic用來接收導航輸入的。名字一樣,純屬巧合!

版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。