TF学习笔记4(添加坐标系)

在之前的教程中,我们重建了turtle demo,通过添加tf广播器和tf侦听器。

本教程将教您如何向tf树添加额外的坐标系。

这与创建广播者非常相似,并将展示tf的一些强大功能。

1 为什么要添加坐标系

对于许多任务,在局部坐标系更容易找到问题。

例如,更容易分析激光扫描仪中心坐标系中的激光扫描仪。

tf允许您为系统中的每个传感器,链接等定义本地坐标系。

tf能够注意到所有引入的额外坐标变换。

2 在哪里添加坐标系

tf建立了一个树状结构的坐标系 ; 但它不允许坐标系结构中出现闭环。

这意味着一个坐标系只有一个父坐标系,以及可以有多个子坐标系。

目前我们的tf树包含三个框架:world,turtle1和turtle2。这两只乌龟是世界坐标系的子坐标系。

如果我们想要将新坐标系添加到tf,则三个现有坐标系中的一个需要是父坐标系,并且新坐标系将成为子坐标系。

tree.png

3 如何添加坐标系

在我们的乌龟demo中,我们将向第一只乌龟添加一个新坐标系。这个坐标系将成为第二只乌龟的“carrot”。

我们先创建源文件。转到我们为之前的教程创建的包:

 $ roscd learning_tf

3.1 程序

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

#include <ros/ros.h>
#include <tf/transform_broadcaster.h>

int main(int argc, char** argv){
  ros::init(argc, argv, "my_tf_broadcaster");
  ros::NodeHandle node;

  tf::TransformBroadcaster br;
  tf::Transform transform;

  ros::Rate rate(10.0);
  while (node.ok()){
    transform.setOrigin( tf::Vector3(0.0, 2.0, 0.0) );
    transform.setRotation( tf::Quaternion(0, 0, 0, 1) );
    br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "turtle1", "carrot1"));
    rate.sleep();
  }
  return 0;
};

该代码与tf广播者教程中的示例非常相似。

3.2 程序解释

我们来看看这段代码中的关键字:

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

在这里,我们创建一个新的转换,从父turtle1到新的孩子carrot1。

所述carrot1坐标系相比较左侧turtle1坐标系有2米的偏移。

4 运行坐标系广播者

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

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

在catkin工作区的顶层文件夹中构建包:

 $ catkin_make

如果一切顺利,你的bin文件夹中应该有一个名为frame_tf_broadcaster的二进制文件。

如果是这样,我们就可以编辑start_demo.launch启动文件了。只需在启动块内合并下面的节点块::

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

首先,确保从上一个教程中停止了启动文件(使用Ctrl-c)。现在您已准备好开始海龟广播着Demo:

 $ roslaunch learning_tf start_demo.launch

5 检查结果

因此,如果您驾驶第一只乌龟,即使我们添加了一个新坐标系,您会注意到这个乌龟的行为与前一个教程相比没有变化。

这是因为添加额外的坐标系不会影响其他坐标系,我们的Listener仍在使用先前定义的坐标系。

所以,让我们改变监听器的行为。

打开SRC / turtle_tf_listener.cpp文件,简单更换“/ turtle1”与“/ carrot1”在26-27行:

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

现在好的部分:只需重建并重新启动乌龟演示,你就会看到第二只乌龟跟着carrot而不是第一只乌龟!

请记住,carrot位于turtle1左侧2米处。carrot没有可视化表示,但你应该看到第二只乌龟移动到那一点。

 $ catkin_make
 $ roslaunch learning_tf start_demo.launch

6 广播移动的帧

我们在本教程中发布的额外坐标系是一个固定坐标系,相对于父坐标系不会随时间变化。

但是,如果要发布移动坐标系,可以更改广播者以随时间更改。

让我们修改/ carrot1坐标系以随着时间的推移相对于/ turtle1进行更改。

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

现在是好的部分:只需重建并重新启动乌龟演示,你就会看到第二只乌龟跟着一只移动的carrot。

 $ catkin_make
 $ roslaunch learning_tf start_demo.launch

您现在已准备好转到关于tf和time的下一个教程(Python) (C ++)

猜你喜欢

转载自blog.csdn.net/qq_27806947/article/details/84725521