Gmapping从开始到放弃—写一个TF 监听
這篇文章主要 記錄如何監聽一個TF廣播,通過監聽tf,我們可以避免繁瑣的旋轉矩陣的計算,而直接獲取我們需要的相關信息.當然也是接著上一篇文章創建的開發包繼續走下去
(1)在my_tf文件下的src下新建一個文件命名turtle_tf_listener.cpp.
添加代碼如下
#include <ros/ros.h>
#include <tf/transform_listener.h> //transformListener是接受tf消息的頭文件
#include <geometry_msgs/Twist.h>
#include <turtlesim/Spawn.h>int main(int argc, char** argv){ros::init(argc, argv, "my_tf_listener"); //初始化節點ros::NodeHandle node;//以下的代碼是為了在一個界面里可視化兩個小烏龜,小烏龜在這里是服務信息ros::service::waitForService("spawn");ros::ServiceClient add_turtle =node.serviceClient<turtlesim::Spawn>("spawn");turtlesim::Spawn srv;add_turtle.call(srv);ros::Publisher turtle_vel =node.advertise<geometry_msgs::Twist>("turtle2/cmd_vel", 10); //定義發布的消息的類型tf::TransformListener listener; //定義監聽器ros::Rate rate(10.0);while (node.ok()){tf::StampedTransform transform;//定義存放變換關系的變量try{listener.waitForTransform("/turtle2", "/turtle1", ros::Time(0), ros::Duration(10.0) );//等待listener.lookupTransform("/turtle2", "/turtle1",ros::Time(0), transform);//參數分別是destination_frame, original_frame,time,transform.我們是想把/turtle1的坐標信息轉換位turtle2 。transform 這里是用于存儲最后總的結果}catch (tf::TransformException &ex) { //出現異常的處理ROS_ERROR("%s",ex.what());ros::Duration(1.0).sleep();continue;}
//上面存儲在transform中的turtle1的距離和角度的信息,用于計算turtle2De 線速度和角速度,這個新的計算結果發布在“turtle2/cmd_vel”用來更型turtle2的運動geometry_msgs::Twist vel_msg;vel_msg.angular.z = 4.0 * atan2(transform.getOrigin().y(),transform.getOrigin().x());vel_msg.linear.x = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) +pow(transform.getOrigin().y(), 2)); //前面的數字你可以自己修改查看會有什么的效果,這只是用于限定小烏龜的線速度和角速度的參數,turtle_vel.publish(vel_msg);rate.sleep();}return 0;
};
分析:由于tf的會把監聽的內容存放到一個緩存中,再讀取內容,而這個過程可能會有幾毫秒的延遲,所以,tf的監聽器并不能立即監聽到“現在”的變換,所以如果不使用try,catch函數會導致報錯:
不可以把ros::Time(0)改成ros::time::now(),因為監聽做不到實時,會有幾毫秒的延遲。ros::Time(0)指最近時刻存儲的數據,ros::time::now()則指當下,如果非要使用ros::time::now,則需要結合waitForTransform()使用,具體見:
http://wiki.ros.org/tf/Tutorials/tf%20and%20Time%20%28C++%29
實際中ros::Time(0)大多數情況下可以滿足要求。
“world” passed to lookupTransform argument target_frame does not exist. ”
(2)在CMakeList.txt中添加我們剛剛新建的文件,需要編譯的文件
add_executable(turtle_tf_listener src/turtle_tf_listener.cpp)
target_link_libraries(turtle_tf_listener ${catkin_LIBRARIES})
(3)catkin_make 編譯
(4)為了查看效果在之前的.launch文件中添加下面的一行
<node pkg="my_tf" type="turtle_tf_listener"name="listener" />
(5)運行roslaunch my_tf start_demo.launch
具體的解釋在代碼中也是有給出了,所以我們直接運行結果查看
可以發現我們在按移動turtle1的時候turtle2也會跟在后面走,那是因為turtle2監聽了turtle1轉換到turtle2的TF 消息了,可以查看下一
rosrun tf tf_echo /turtle1 /turtle2
不過好像并看不出來什么,但是我們可以從代碼中可以明白一點什么
總結
以上是生活随笔為你收集整理的Gmapping从开始到放弃—写一个TF 监听的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Gmapping从开始到放弃—写一个TF
- 下一篇: 《概率机器人》速度运动模型gmappin