ROS TF变换
靜態(tài)坐標(biāo)轉(zhuǎn)換:機(jī)器人本體中心到雷達(dá)中心的轉(zhuǎn)換。因?yàn)榧す饫走_(dá)可能沒(méi)安裝到機(jī)器人的中心。
動(dòng)態(tài)坐標(biāo)轉(zhuǎn)換:機(jī)器人中心和里程計(jì)坐標(biāo)的變換。機(jī)器人從起點(diǎn)出發(fā)后,里程計(jì)坐標(biāo)相對(duì)于本體就會(huì)產(chǎn)生一個(gè)偏移,這個(gè)偏移隨著機(jī)器人的運(yùn)動(dòng)不斷改變。
odme:里程計(jì)坐標(biāo)系。
base_link :機(jī)器人的基體坐標(biāo)系,與機(jī)器人的中心點(diǎn)重合。
base_link坐標(biāo)系原點(diǎn)一般為機(jī)器人的旋轉(zhuǎn)中心,base_footprint坐標(biāo)系原點(diǎn)為base_link原點(diǎn)在地面的投影。
base_laser :傳感器坐標(biāo)系,例如激光雷達(dá)傳感器。
map:地圖坐標(biāo)系,固定坐標(biāo)系(fixed frame),與機(jī)器人所在的世界坐標(biāo)系一致。
TF是可以讓用戶隨時(shí)間跟蹤多個(gè)坐標(biāo)系的功能包。使用樹(shù)形數(shù)據(jù)結(jié)構(gòu),根據(jù)時(shí)間緩沖,維護(hù)多個(gè)坐標(biāo)系之間的坐標(biāo)變換關(guān)系。
TF功能包提供了存儲(chǔ)、計(jì)算不同數(shù)據(jù)在不同參考系之間變換的功能,只需要告訴tf樹(shù)這些參考系之間的變換公式即可。
所有訂閱TF消息的節(jié)點(diǎn)都會(huì)緩沖一份所有坐標(biāo)系的變換關(guān)系數(shù)據(jù)。
有一篇文章介紹了移動(dòng)機(jī)器人的控制結(jié)構(gòu),并且介紹了里程計(jì):
base_controller節(jié)點(diǎn)將訂閱的cmd_vel信息通過(guò)串口或其它通信接口發(fā)送給下位機(jī)(嵌入式控制板)。
下位機(jī)中根據(jù)機(jī)器人運(yùn)動(dòng)學(xué)公式進(jìn)行解算,將機(jī)器人速度轉(zhuǎn)換為每個(gè)輪子的速度。
然后通過(guò)CAN總線(或其它總線接口)將每個(gè)輪子的轉(zhuǎn)速發(fā)送給電機(jī)驅(qū)動(dòng)板控制電機(jī)轉(zhuǎn)動(dòng)。
電機(jī)驅(qū)動(dòng)板對(duì)電機(jī)轉(zhuǎn)速進(jìn)行閉環(huán)控制(PID控制),并統(tǒng)計(jì)單位時(shí)間內(nèi)接收到的編碼器脈沖數(shù),計(jì)算出輪子轉(zhuǎn)速。
base_controller節(jié)點(diǎn)將接收到的cmd_vel速度信息轉(zhuǎn)換為自定義的結(jié)構(gòu)體或union類型的數(shù)據(jù)(自定義的數(shù)據(jù)類型中可以包含校驗(yàn)碼等其它信息),并通過(guò)串口發(fā)送控制速度信息(speed_buf)或讀取機(jī)器人傳回的速度信息 (speed_buf_rev)。
base_controller節(jié)點(diǎn)正確讀取到底層(比如嵌入式控制板)傳回的速度后進(jìn)行積分,計(jì)算出機(jī)器人的估計(jì)位置和姿態(tài),并將里程計(jì)信息和tf變換發(fā)布出去。
單獨(dú)使用里程計(jì)來(lái)估計(jì)小車位置姿態(tài)的效果不是特別好,因?yàn)檩喿哟蚧D莻€(gè)文章的作者提到,使用多傳感器重合的方法,可以使位姿信息更加精準(zhǔn)。具體方法是:使用IMU或其它傳感器來(lái)同時(shí)進(jìn)行測(cè)量,使用擴(kuò)展卡爾曼濾波對(duì)imu和里程計(jì)的數(shù)據(jù)進(jìn)行融合。
靜態(tài)坐標(biāo)轉(zhuǎn)換
新建一個(gè)launch文件。
launch文件內(nèi)容:調(diào)用tf功能包下的static_transform_publisher節(jié)點(diǎn),幾個(gè)參數(shù)分別是x,y,z三個(gè)方向的距離變換,航向,俯仰,橫滾三個(gè)角度的變換。
x軸方向偏移0.1米,z軸方向偏移0.2米,/tf1/tf2表示參數(shù)描述的是tf2相對(duì)tf1的變換關(guān)系。20表示發(fā)布間隔20毫秒。
<launch><node pkg="tf" type="static_transform_publisher" name="static_transform"args="0.1 0.0 0.2 0.0 0.0 0.0 /tf1 /tf2 20"></node> </launch>終端輸入:
@robot:~$ roscore @ubuntu:~$ roslaunch test1 tf_transform.launch @ubuntu:~$ rosrun rqt_tf_tree rqt_tf_tree打開(kāi)RVIZ進(jìn)行相應(yīng)設(shè)置,可看到tf2相對(duì)tf1在x軸和z軸的偏移。
動(dòng)態(tài)坐標(biāo)轉(zhuǎn)換
新建tf_transform.py文件。
#!/usr/bin/env python import rospy import tf import math def tf_transform():rospy.init_node('tf_transform', anonymous=False)tf_broadcaster = tf.TransformBroadcaster()rate = rospy.Rate(10) # 10hzangle = 0.0rospy.loginfo('Start TF Transform')while not rospy.is_shutdown():x = math.cos(angle)*0.3y = math.sin(angle)*0.3z = 0.2quat = tf.transformations.quaternion_from_euler(0,0,angle)current_time = rospy.Time.now()tf_broadcaster.sendTransform((x,y,z),quat,current_time,'tf3','tf1')tf_broadcaster.sendTransform((x,y,z),(0,0,0,1),current_time,'tf4','tf1')angle += 0.01rate.sleep() if __name__ == '__main__':tf_transform() @ubuntu:~/catkin_ws$ cd src/test1/src/ @ubuntu:~/catkin_ws/src/test1/src$ chmod +x tf_transform.py @ubuntu:~/catkin_ws/src/test1/src$ rosrun test1 tf_transform.py [INFO] [1645266508.071635]: Start TF Transform這個(gè)節(jié)點(diǎn)會(huì)持續(xù)發(fā)布兩個(gè)坐標(biāo)tf3和tf4,繞著tf1以0.3為半徑做圓周運(yùn)動(dòng)。tf4相對(duì)于tf1只做位置變換不做角度變換。tf3在位置變換的同時(shí)做角度變換。
總結(jié)
- 上一篇: ROS配置分布式通信
- 下一篇: kafka 创建topic_Kafka试