本篇教程演示如何建立新坐標(biāo)系,建立新坐標(biāo)系與創(chuàng)建tf廣播類似蒲列,同時能加強(qiáng)tf功能娄柳。
1.為什么添加坐標(biāo)系
很多實(shí)例中,分系統(tǒng)的本地坐標(biāo)系理解起來比較簡單粮坞,比如激光雷達(dá)的坐標(biāo)系在雷達(dá)的幾何中心蚊荣,tf允許在任何傳感中定義一個坐標(biāo)系,tf的作用也在于整理好坐標(biāo)系之間的轉(zhuǎn)換關(guān)系莫杈。
2.坐標(biāo)系在哪兒添加
tf建立了一個樹狀結(jié)構(gòu)的坐標(biāo)系組互例,坐標(biāo)系組中不允許閉環(huán)存在。這意味著一個坐標(biāo)系只有一個父坐標(biāo)系筝闹,但可以有多個子坐標(biāo)系媳叨。前面示例中使用的系統(tǒng)擁有三個坐標(biāo)系:世界坐標(biāo)系,海龜1关顷,海龜2.兩個海龜坐標(biāo)系是世界坐標(biāo)系的子坐標(biāo)系糊秆。當(dāng)我們要添加一個新的坐標(biāo)系到tf中時,三個已知的坐標(biāo)中的一個坐標(biāo)系需要是其父坐標(biāo)系议双,新的坐標(biāo)系將成為子坐標(biāo)系痘番。
3.如何添加坐標(biāo)系
在海龜示例中,我們在第一個海龜中添加一個坐標(biāo)系平痰,這個坐標(biāo)系是第二個海龜?shù)摹昂}卜”汞舱,如下所示進(jìn)入當(dāng)前工作包,添加代碼宗雇。
$ roscd learning_tf
$ vim nodes/fixed_tf_broadcaster.py
import rospy
import tf
if __name__ == '__main__':
rospy.init_node('my_tf_broadcaster')
br = tf.TransformBroadcaster()
rate = rospy.Rate(10.0)
while not rospy.is_shutdown():
br.sendTransform((0.0, 2.0, 0.0),
(0.0, 0.0, 0.0, 1.0),
rospy.Time.now(),
"carrot1",
"turtle1")
rate.sleep()
4.運(yùn)行坐標(biāo)系發(fā)布程序
在start_demo.launch文件中添加下面的內(nèi)容昂芜。
$vim launch/start_demo.launch
<launch> ...
<node pkg="learning_tf" type="fixed_tf_broadcaster.py" name="broadcaster_fixed" />
</launch>
5.檢查結(jié)果
當(dāng)運(yùn)行上面的launch文件時,會發(fā)現(xiàn)結(jié)果與之前一致赔蒲,海龜2還是跟隨海龜1而不是新建的“carrot”坐標(biāo)系泌神。這是因?yàn)橹暗膌istner文件中海龜2的坐標(biāo)系是參照海龜1的坐標(biāo)系計算速度的。如果將參考坐標(biāo)系改為“carrot”坐標(biāo)系計算速度信息嘹履,即可使得海龜2跟隨“carrot”坐標(biāo)系腻扇。
$ vim nodes/turtle_tf_listener.py
將lookupTransform后面的/turtle1替換為/carrot1
'''
(trans,rot) = listener.lookupTransform("/turtle2", "/carrot1", rospy.Time(0))
'''
roslaunch learning_tf start_demo.launch、
6.運(yùn)動坐標(biāo)系的廣播
我們在教程中新建的坐標(biāo)系相對于父坐標(biāo)系的位置是固定的砾嫉,因此是固定坐標(biāo)系幼苛。然而,當(dāng)需要發(fā)布一個移動坐標(biāo)系時焕刮,就需要隨時改變廣播舶沿,下面的實(shí)例中嘗試將carrot1坐標(biāo)系設(shè)置為移動坐標(biāo)系墙杯,隨著時間改變相對于海龜坐標(biāo)系1的位置。
#!/usr/bin/env python
import roslib
roslib.load_manifest('learning_tf')
import rospy
import tf
import math
if __name__ == '__main__':
rospy.init_node('my_tf_broadcaster')
br = tf.TransformBroadcaster()
rate = rospy.Rate(10.0)
while not rospy.is_shutdown():
t = rospy.Time.now().to_sec() * math.pi
br.sendTransform((2.0 * math.sin(t), 2.0 * math.cos(t), 0.0),
(0.0, 0.0, 0.0, 1.0),
rospy.Time.now(),
"carrot1",
"turtle1")
rate.sleep()