在命令行工具中也有一个与transformcaster相类似的工具叫做static_transform_publisher,它能够接受命令行参数来接受位置信息、旋转信息、父框架、子框架以及周期信息,通常在launch文件中来指定。static_transform_publisher主要是变换两个固定坐标系之间的转换,eg:base_link和base_laser是底座与激光雷达之间的变换。

eg:

<node pkg="tf" type="static_transform_publisher" name="broadcaster" args="1 0 0 0 0 0 1 parent child 100">

下面来实现tf的订阅者

新建一个源文件turtle_tf_listener.cpp

在这个订阅者的任务里面主要是调用一个服务再生一个turtle,然后再发布cmd_vel这个主题在turtle2上面用于控制turtle2的轨迹,同时turtle2的轨迹是由transform_listener中得到的transform是由turtle1到turtle2的变换。

#include<ros/ros.h>

#include<tf/transform_listener.h>

#include<geometry_msg/Twist.h>

#include<turtlesim/Spawn.h>

int main(int argc,char **argv)

{

  ros::init(argc,argv,"turtle_tf_listener");//节点名字turtle_tf_listener

  ros::NodeHandle node;

//下面写服务,等待spawn服务,如果服务没有到达就一直等待

  ros::service::waitForService("spawn");

  //创建一个服务的客户端,其类型为turtlesim::Spawn,服务类型为spawn

  ros::ServiceClient add_turtle=node.service<turtlesim::Spawn>("spawn");

  //创建一个turtlesim::Spawn变量

  turtlesim::Spawn srv;

  //调用该服务

  add_turtle.call(srv);

  //下面来写一个publisher,其类型为geometry_msgs::Twist,发布到turtle2/cmd_vel上,消息队列为10

  ros::Pubisher turtle_vel=node.advertise<geometry_msgs::Twist>("turtle2/cmd_vel",10);

  //下面创建一个transform_listener对象

  tf::transformListener listener;

  //指定一个频率

  ros::Rate rate(10.0);

  //判断节点是否被关闭

  while(ros::ok())

{

  //创建一个stampedtransform对象来储存变换的信息

  tf::StampedTransform transform;

  try //在try里面使用lookuptransform

  {

  //其参数使targetframe,sourceframe,time,以及transform它用来储存变换的信息。父框架是turtle2,子框架是turtle1,时间为ros::Time(0)是指把最新的有效信息发布出去,在之前的broadcater中用的是time.now()是把现在的信息发送出去。

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

  }

  catch(tf::TransformException &ex)

  {

    ROS_ERROR("%s",ex.what());//把异常显示在终端上

  ros::Duration(1.0).sleep();//显示的时间为1s。

  continue;

  }

  //从transform中得到一个Twist的消息,然后发布给turtle2,下面实例化一个geometry_msgs

  geometry_msgs::Twist vel_msg;

  //角速度z的值,先指定一个系数4.0,然后其计算方法为atan2。

 vel_msg.angular.z = 4.0* atan2(transform.getOrigin().y(),  transform.getOrigin().x());    

//线速度只指定x,系数设为0.5.其计算方法是使用平方函数。

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 1;

}

回顾一下上面程序包含了哪些内容:

首先,初始化节点,然后调用Spawn服务再生一只乌龟,接着再定义一个publisher发布消息在turtle2/cmd_vel上面,发布的消息为geometry_msg:Twist类型的vel_msg,其内容为transform储存的turtle2到turtle1的变换。

下面到CMakeList.txt里面添加内容

add_executable(turtle_tf_listener src/turtle_tf_listener.cpp)

target_link_libraries(turtle_tf_listener ${catkin_LIBRARIES})

下面再来写一个launch文件。

demo.launch

<launch>

<node  pkg="turtlesim" type="turtlesim_node" name="sim"/>

<node  pkg="turtlesim" type="turtle_teleop_key" name="teleop" output="screen"/>

<node pkg="learning_tf" type="turtle_tf_broadcaster" args="/turtle1" name="turtle1_tf">

<node pkg="learning_tf" type="turtle_tf_broadcaster" args="/turtle2" name="turtle2_tf">//将/turtle1和/turtle2两个的在世界坐标系中的速度和位置信息发布到tf树上

<node pkg="learning_tf" type="turtle_tf_listener" name="listener">//用来获取/turtle1与/turtle2之间的变换.

</launch>

launch文件的逻辑为首先启动turtlesim_node,然后再启动turtle_teleop_key通过按键来控制它的运动,然后再learning_tf中再生一只乌龟,有两只乌龟,在tf_listener中会发布turtle2/cmd_vel这个主题来控制turtle2的运动,在turtle_tf_broadcaster中同时启动两个节点,一个节点订阅的是turtle1的pose,另一个节点订阅的是turtle2的pose,然后在tf树中广播turtle1和turtle2的位置;然后listener订阅在世界坐标系中的turtle1个turtle2的相对位置,储存在transform中,通过transform中存储的位置信息转化为控制信息。

args是指从命令行输入的参数!!

下面去编译,别忘了增加tf的依赖项。!!!!!!!!

运行roslaunch learning_tf demo.launch

运行仿真工具rosrun rviz rviz

运行之后把tf添加进去。记得把Fixed frame选择为world。

第七课 ROS的空间描述和变换的更多相关文章

  1. 第六课 ROS的空间描述和变换

    1.空间描述与变换 有两个坐标系A和B,B坐标系中有一个点P,如何把B坐标系中的P映射到A坐标系呢,这就涉及到空间描述与变换, 先看一下旋转矩阵: 上面中间的行向量中的元素表示在B坐标系当中的元素用A ...

  2. 第八课 ROS的空间描述和变换

    1.tf的实际应用 1)在机器人的配置中 从上面可以看出激光雷达中心距离机器人底座的中心有20cm,激光雷达的中心距机器人底座中心有10cm,如果激光雷达在障碍物前面0.3米,那么机器人底座离障碍物多 ...

  3. NeHe OpenGL教程 第七课:光照和键盘

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  4. [译]Quartz.NET 框架 教程(中文版)2.2.x 之第七课 触发监听器和作业任务监听器

    第七课:触发监听器和作业任务监听器 监听器是在调度器中基于事件机制执行操作的对象.你大概可以猜到,触发监听器接收响应跟触发器有关的事件,作业任务监听器接收响应跟作业任务有关的事件. 跟触发器有关的事件 ...

  5. Kali Linux Web 渗透测试视频教程— 第七课 OpenVas

    Kali Linux Web 渗透测试视频教程— 第七课 OpenVas 文/玄魂 视频教程地址:http://edu.51cto.com/course/course_id-1887.html 目录 ...

  6. NeHe OpenGL教程 第五课:3D空间

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  7. 【C语言探索之旅】 第二部分第七课:文件读写

    内容简介 1.课程大纲 2.第二部分第七课: 文件读写 3.第二部分第八课预告: 动态分配 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏 ...

  8. 【C语言探索之旅】 第一部分第七课:循环语句

    内容简介 1.课程大纲 2.第一部分第七课: 循环语句 3.第一部分第八课预告: 第一个C语言小游戏 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编 ...

  9. 【Cocos游戏实战】功夫小子第七课之游戏主功能场景逻辑功能和暂停功能场景的分析和实现

    CSDN的markdown编辑器是吃屎了么! !.什么玩意.!写了一半写不了东西还全没了,搞个毛线! 本节课的视频教程地址是:第七课在此 假设本教程有帮助到您,希望您能点击进去观看一下,并且如今注冊成 ...

随机推荐

  1. JAMstack 技术要点

    1.  简要说明 Modern web development architecture based on client-side JavaScript, reusable APIs,and preb ...

  2. fn project k8s 集成

    具体部署还是比较简单的,以下为官方参考,只是有一个service type 为 loadBlancer 实际使用需要修改为NodePort  Prerequisite 1: working Kuber ...

  3. jQuery火箭图标返回顶部代码

    在网上找来段使用jQuery火箭图标返回顶部代码,感觉比较酷,比较炫,大概样式如下, 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1. ...

  4. Dedesql数据库类详解(二次开发必备教程)(转)

    http://www.dedecms.com/help/development/2009/1028/1076.html 织梦DedeCMS的二次开发不仅仅是会写写织梦的标签,会制作织梦的模板.很多时候 ...

  5. POJ1742:Coins

    浅谈\(DP\):https://www.cnblogs.com/AKMer/p/10437525.html 题目传送门:http://poj.org/problem?id=1742 多重背包,每个物 ...

  6. Jvm垃圾回收器详细

    1, 串行回收器 1.1, 新生代串行回收器 (1)特点:  –它仅仅使用单线程进行垃圾回收  –它是独占式的垃圾回收  –进行垃圾回收时, Java应用程序中的线程都需要暂停(Stop-The-Wo ...

  7. java代码用户界面网格布局GridLayout.划分为格子区域

    总结:网格布局.很简单,首先要new一个   this.setlayout(new GriedLayout(3,5));里面是行数和列数 package clientFrame; //网格布局练习 i ...

  8. PHP 字符串 加*

    PHP字符串加* 思路: 获取第一个字符或文字 获取最后一个字符或文字 一头一尾,中间加* 尝试用substr方法,发现对中文的支持有问题. 后来发现mb_substr很好的解决了这个问题. < ...

  9. Docker - 使用 swarm 部署 services

    前言 经过之前一段时间学习与思考,我们已经大概明确了一些感念: Docker image/container,  service and node 简单来说,swarm允许我们以节点(node)的方式 ...

  10. 分析java类的静态成员变量初始化先于非静态成员变量

    依上图中当class字节码文件被jvm虚拟机加载到内存中依次经过 连接 验证:对字节码进行验证 准备:给静态变量分配内存并赋予变量类型各自的默认值(注:基本类型为0或false,对象为null,sta ...