四 tf / Tutorials / Adding a frame (C++)

原文地址:http://wiki.ros.org/tf/Tutorials/Adding a frame (C%2B%2B)

在前面的教程中,我们通过添加tf广播器和tf监听器来重新创建turtle demo。本教程将教您如何向tf树中添加额外的坐标系。这与创建tf广播非常相似,并且将展示tf的一些能力。

1 Why adding frames

对于许多任务来说,在本地坐标系内进行思考更容易,例如,在激光扫描器的中心处的坐标系中推断激光扫描更容易。tf允许您为系统中的每个传感器、链接等定义本地坐标系。而且,tf将负责所有引入的额外坐标系的transforms。

2 Where to add frames

tf建立坐标系的树结构;它不允许坐标系结构中的闭环。这意味着一个坐标系只有一个父节点,但是它可以有多个子节点。目前,我们的tf树包含三个坐标系:world、turtle1和turtle2。这两只turtle是world的子坐标系。如果我们想向tf添加新坐标系,三个现有坐标系中的一个需要是父坐标系,并且新坐标系将成为子坐标系。
在这里插入图片描述

3 How to add a frame

在我们的turtle 示例中,我们将为turtle1添加一个新坐标系。这个坐标系将是turtle2的“胡萝卜”。
让我们首先创建源文件。转到我们为前面的教程创建的包:

 $ roscd learning_tf

3.1 The Code

启动您喜欢的编辑器,并将以下代码粘贴到一个名为src/frame_tf_broadcaster.cpp的新文件中。



   1 #include <ros/ros.h>
   2 #include <tf/transform_broadcaster.h>
   3 
   4 int main(int argc, char** argv){
   5   ros::init(argc, argv, "my_tf_broadcaster");
   6   ros::NodeHandle node;
   7 
   8   tf::TransformBroadcaster br;
   9   tf::Transform transform;
  10 
  11   ros::Rate rate(10.0);
  12   while (node.ok()){
  13     transform.setOrigin( tf::Vector3(0.0, 2.0, 0.0) );
  14     transform.setRotation( tf::Quaternion(0, 0, 0, 1) );
  15     br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "turtle1", "carrot1"));
  16     rate.sleep();
  17   }
  18   return 0;
  19 };

代码非常类似于tf broadcaster tutorial 中的示例。

3.2 The Code Explained

让我们看看这段代码中的关键行:

  13     transform.setOrigin( tf::Vector3(0.0, 2.0, 0.0) );
  14     transform.setRotation( tf::Quaternion(0, 0, 0, 1) );
  15     br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "turtle1", "carrot1"));

在这里,我们创建一个新的transform,从父turtle1到新的子carrot1。carrot1坐标系与turtle1坐标系向左偏移2米。

4 Running the frame broadcaster

现在我们已经创建了代码,让我们首先编译它。打开CMakeLists.txt文件,并在底部添加以下行:

add_executable(frame_tf_broadcaster src/frame_tf_broadcaster.cpp)
target_link_libraries(frame_tf_broadcaster ${catkin_LIBRARIES})

在catkin的工作空间的顶部文件夹中编译包:

扫描二维码关注公众号,回复: 5817491 查看本文章
 $ catkin_make

如果一切顺利,则bin文件夹中应该有一个名为frame_tf_broadcaster的二进制文件。如果是这样,我们就可以编辑start_demo.launch启动文件了。只需将下面的node block合并到launch block内::

  <launch>
    ...
    <node pkg="learning_tf" type="frame_tf_broadcaster"
          name="broadcaster_frame" />
  </launch>

首先,确保您停止了前一个教程中的启动文件(使用Ctrl-c)。现在你已经准备好开始播放turtle broadcaster的demo了:

$ roslaunch learning_tf start_demo.launch

5 Checking the results

因此,如果您驱动turtle1四处游荡,您会发现即使我们添加了一个新坐标系,该行为与前一个教程没有改变。这是因为添加额外的坐标系不会影响其他坐标系,并且我们的listener仍然使用之前定义的坐标系。所以,让我们改变listener的行为。
打开 src/turtle_tf_listener.cpp 文件,第26-27行中用“/carrot1”简单替换“/turtle1”:

   1   listener.lookupTransform("/turtle2", "/carrot1",
   2                            ros::Time(0), transform);

现在好的部分是:重新编译并重新启动turtle demo,您将看到turtle2跟随carrot而不是turtle1!记住,carrot离turtle1左边2米。carrot没有视觉上的表示,但是您应该看到turtle2移动到该点。

 $ catkin_make
 $ roslaunch learning_tf start_demo.launch

6 Broadcasting a moving frame

在本教程中我们发布的额外坐标系是一个固定的坐标系,它不会随着时间而相对于父坐标系发生变化。然而,如果你想发布一个移动坐标系,你可以改变broadcaster让它随时间改变。让我们修改/carrot1坐标系以相对于/turtle1随时间更改。

   1     transform.setOrigin( tf::Vector3(2.0*sin(ros::Time::now().toSec()), 2.0*cos(ros::Time::now().toSec()), 0.0) );
   2     transform.setRotation( tf::Quaternion(0, 0, 0, 1) );

现在好的部分是:只需重新编译并重新启动turtle demo,您将看到turtle2跟随一个移动的carrot。

 $ catkin_make
 $ roslaunch learning_tf start_demo.launch

现在,您可以进入下一个关于tf和time的教程了。

猜你喜欢

转载自blog.csdn.net/llz56/article/details/85242456