日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Gmapping从开始到放弃—写一个TF 监听

發(fā)布時(shí)間:2023/11/27 生活经验 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Gmapping从开始到放弃—写一个TF 监听 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這篇文章主要 記錄如何監(jiān)聽一個(gè)TF廣播,通過監(jiān)聽tf,我們可以避免繁瑣的旋轉(zhuǎn)矩陣的計(jì)算,而直接獲取我們需要的相關(guān)信息.當(dāng)然也是接著上一篇文章創(chuàng)建的開發(fā)包繼續(xù)走下去
(1)在my_tf文件下的src下新建一個(gè)文件命名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");  //初始化節(jié)點(diǎn)ros::NodeHandle node;//以下的代碼是為了在一個(gè)界面里可視化兩個(gè)小烏龜,小烏龜在這里是服務(wù)信息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);  //定義發(fā)布的消息的類型tf::TransformListener listener; //定義監(jiān)聽器ros::Rate rate(10.0);while (node.ok()){tf::StampedTransform transform;//定義存放變換關(guān)系的變量try{listener.waitForTransform("/turtle2", "/turtle1", ros::Time(0), ros::Duration(10.0) );//等待listener.lookupTransform("/turtle2", "/turtle1",ros::Time(0), transform);//參數(shù)分別是destination_frame, original_frame,time,transform.我們是想把/turtle1的坐標(biāo)信息轉(zhuǎn)換位turtle2 。transform 這里是用于存儲最后總的結(jié)果}catch (tf::TransformException &ex) {   //出現(xiàn)異常的處理ROS_ERROR("%s",ex.what());ros::Duration(1.0).sleep();continue;}
//上面存儲在transform中的turtle1的距離和角度的信息,用于計(jì)算turtle2De 線速度和角速度,這個(gè)新的計(jì)算結(jié)果發(fā)布在“turtle2/cmd_vel”用來更型turtle2的運(yùn)動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)); //前面的數(shù)字你可以自己修改查看會有什么的效果,這只是用于限定小烏龜?shù)木€速度和角速度的參數(shù),turtle_vel.publish(vel_msg);rate.sleep();}return 0;
};

分析:由于tf的會把監(jiān)聽的內(nèi)容存放到一個(gè)緩存中,再讀取內(nèi)容,而這個(gè)過程可能會有幾毫秒的延遲,所以,tf的監(jiān)聽器并不能立即監(jiān)聽到“現(xiàn)在”的變換,所以如果不使用try,catch函數(shù)會導(dǎo)致報(bào)錯(cuò):
不可以把ros::Time(0)改成ros::time::now(),因?yàn)楸O(jiān)聽做不到實(shí)時(shí),會有幾毫秒的延遲。ros::Time(0)指最近時(shí)刻存儲的數(shù)據(jù),ros::time::now()則指當(dāng)下,如果非要使用ros::time::now,則需要結(jié)合waitForTransform()使用,具體見:
http://wiki.ros.org/tf/Tutorials/tf%20and%20Time%20%28C++%29
實(shí)際中ros::Time(0)大多數(shù)情況下可以滿足要求。

“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)運(yùn)行roslaunch my_tf start_demo.launch

具體的解釋在代碼中也是有給出了,所以我們直接運(yùn)行結(jié)果查看

可以發(fā)現(xiàn)我們在按移動turtle1的時(shí)候turtle2也會跟在后面走,那是因?yàn)閠urtle2監(jiān)聽了turtle1轉(zhuǎn)換到turtle2的TF 消息了,可以查看下一
rosrun tf tf_echo /turtle1 /turtle2

不過好像并看不出來什么,但是我們可以從代碼中可以明白一點(diǎn)什么

總結(jié)

以上是生活随笔為你收集整理的Gmapping从开始到放弃—写一个TF 监听的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。