ROS tf-深入Time和TF


博客轉載自:https://www.ncnynl.com/archives/201702/1313.html

ROS與C++入門教程-tf-深入Time和TF

說明:

  • 介紹使用waitForTransform函數去等待TF樹中的變換生效

TF和Time

  • 在前面的教程中,我們了解了tf如何跟蹤坐標系樹。
  • 此樹隨時間變化,tf存儲每個變換的時間快照(默認情況下最多為10秒)。
  • 直到現在,我們使用lookupTransform()函數來獲取該tf樹中最新的可用變換,而不知道什么時候記錄變換。
  • 本教程將教您如何在特定時間獲取轉換。
  • 在上個教程的文件上修改:
$ roscd learning_tf
$ vim src/turtle_tf_listener.cpp
  • 找到代碼:
try{
    listener.lookupTransform("/turtle2", "/carrot1",  
        ros::Time(0), transform);
  • 修改為:
try{
   listener.lookupTransform("/turtle2", "/turtle1",  
        ros::Time(0), transform);
  • 更改/turtle2跟隨/turtle1,不是/carrot1,我們指定了時間為0,即獲得最新有效的變換。
  • 改變獲取當前時間的變換,即改為now(), 修改代碼:
  try{
    listener.lookupTransform("/turtle2", "/turtle1",  
                             ros::Time::now(), transform);
  • 編譯運行:
  $ catkin_make
  $ roslaunch learning_tf start_demo.launch
  • lookupTransform()函數提示失敗:
[ERROR] [1287871653.885277559]: You requested a transform that is 0.018 miliseconds in the past, but the most recent transform in the tf buffer is 7.681 miliseconds old.                                                 
 When trying to transform between /turtle1 and /turtle2.  
  • 這是為什么? 每個監聽器有一個緩沖區,它存儲來自不同tf廣播者的所有坐標變換。 當廣播者發出變換時,變換進入緩沖區之前需要一些時間(通常是幾個毫秒)。 因此,當您在時間“now”請求坐標系變換時,您應該等待幾毫秒以獲得該信息。

等待變換

  • tf提供了一個很好的工具,它將等待,直到變換可用。
  • 修改代碼為:
 try{
    ros::Time now = ros::Time::now();
    listener.waitForTransform("/turtle2", "/turtle1",
                              now, ros::Duration(3.0));
    listener.lookupTransform("/turtle2", "/turtle1",
                             now, transform);
  • waitForTransform() 四個參數:

    • 1.需要等待變換從坐標系turtle2
    • 2.到坐標系turtle1
    • 3.在now時間
    • 4.超時時間,不要等待超過此最大持續時間
  • 注意:使用ros::Time::now()是為了這個例子。通常這將是希望被轉換的數據的時間戳。

  • 所以waitForTransform()實際上會阻塞直到兩個海龜之間的變換可用(這通常需要幾毫秒)

  • 或者如果變換不可用,直到達到超時。

  • 編譯運行:

  $ catkin_make
  $ roslaunch learning_tf start_demo.launch
  • 但等待,您可能仍會看到錯誤一次(錯誤msg可能會有所不同):
[ERROR] [1287872014.408401177]: You requested a transform that is 3.009 seconds in the past, but the tf buffer only has a history of 2.688 seconds.                                                                   
 When trying to transform between /turtle1 and /turtle2.

  

這是因為turtle2需要非零時間來生成並開始發布tf幀。 因此,第一次請求現在時間的/turtle2坐標系可能不存在,當請求轉換時,轉換可能不存在,並且第一次失敗。 在第一次變換之后,所有的變換都存在,
並且烏龜的行為如預期的那樣。

檢查結果

  • 現在,你應該能夠使用箭頭鍵(確保你的終端窗口是活躍的,而不是你的模擬器窗口),你會看到第二只烏龜跟隨第一只烏龜!
  • 所以,你注意到烏龜的行為沒有明顯的區別。 這是因為實際的時間差只有幾個毫秒。 但是為什么我們從Time(0)到now()進行這種改變? 只是教你關於tf緩沖區和與它相關的時間延遲。對於真實的tf用例,使用Time(0)通常是完全正常的。

ROS與C++入門教程-tf-Time travel(時間穿梭

說明:

  • 介紹tf的高級時間穿梭功能

Time travel

  • 利用上一個教程的文件。
  • 打開src/turtle_tf_listener.cpp,找到25-30,如下:
  try{
    ros::Time now = ros::Time::now();
    listener.waitForTransform("/turtle2", "/turtle1",
                              now, ros::Duration(1.0));
    listener.lookupTransform("/turtle2", "/turtle1",
                             now, transform);
  • 現在,不是讓turtle2去到turtle1當前時間的地方,而讓turtle2去turtle1是5秒前的地方:
try{
    ros::Time past = ros::Time::now() - ros::Duration(5.0);
    listener.waitForTransform("/turtle2", "/turtle1",
                              past, ros::Duration(1.0));
    listener.lookupTransform("/turtle2", "/turtle1",
                             past, transform);
  • 編譯運行:
$ make  or  catkin_make
$ roslaunch learning_tf start_demo.launch
  • 你會期望看到什么? 在第一個5秒鍾,第二只烏龜不知道去哪里,因為我們還沒有第一只烏龜5秒的歷史。

  • 但是這5秒后呢?效果圖:

  • 類似截圖,你的海龜是不可控制? 那么發生了什么?

  • 我們問TF:相對於/turtle2 5秒前,/turtle1 5秒前的姿勢是什么?

  • 這意味着我們控制/turtle2基於5秒前的位置以及/turtle1在5秒前的位置。

  • 那應該問:相對於/turtle2目前的位置,/turtle1 5秒前的姿勢是什么?

高級API

  • 回答上面問題,依賴高級API,示例代碼:
  try{
    ros::Time now = ros::Time::now();
    ros::Time past = now - ros::Duration(5.0);
    listener.waitForTransform("/turtle2", now,
                              "/turtle1", past,
                              "/world", ros::Duration(1.0));
    listener.lookupTransform("/turtle2", now,
                             "/turtle1", past,
                             "/world", transform);
  • 這個lookupTransform()API,有六個參數:

      1. 變換從坐標系turtle2
      1. 在now時間
      1. 到turtle1坐標系
      1. 在past時間
      1. 指定不隨時間改變的坐標系,這里是world
      1. 變換結果保存的變量
  • waitForTransform()跟lookupTransform()一樣有6個相應參數。

  • 效果圖示:

  • 這個圖顯示了tf在后台做什么。

  • 在past時間,它計算從turtle1到world坐標系的變換。

  • 在world坐標系,tf時間從past到now。

  • 在now時間,tf計算從world到turtle2坐標系的變換。

檢查結果:

  • 編譯運行:
$ catkin_make
$ roslaunch learning_tf start_demo.launch
  • 效果:turtle2是指向turtle1 5秒前的地方!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM