博客转载自:https://www.ncnynl.com/archives/201702/1311.html

ROS与C++入门教程-tf-编写tf listener(监听)

说明:

  • 介绍如何使用tf访问坐标系转换

创建tf的监听

$ roscd learning_tf
$ touch src/turtle_tf_listener.cpp
$ vim src/turtle_tf_listener.cpp
  • 代码如下:
#include <ros/ros.h>
#include <tf/transform_listener.h>
#include <geometry_msgs/Twist.h>
#include <turtlesim/Spawn.h> int main(int argc, char** argv){
ros::init(argc, argv, "my_tf_listener"); ros::NodeHandle node; 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); tf::TransformListener listener; ros::Rate rate(10.0);
while (node.ok()){
tf::StampedTransform transform;
try{
listener.lookupTransform("/turtle2", "/turtle1",
ros::Time(0), transform);
}
catch (tf::TransformException &ex) {
ROS_ERROR("%s",ex.what());
ros::Duration(1.0).sleep();
continue;
} 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));
turtle_vel.publish(vel_msg); rate.sleep();
}
return 0;
};
  • 如果在运行时遇到错误"Lookup would require extrapolation into the past",您可以尝试此替代代码来调用侦听器:
try {
listener.waitForTransform(destination_frame, original_frame, ros::Time(0), ros::Duration(10.0) );
listener.lookupTransform(destination_frame, original_frame, ros::Time(0), transform);
} catch (tf::TransformException ex) {
ROS_ERROR("%s",ex.what());
}

代码解释:

  • 代码: #include <tf/transform_listener.h>
  • 作用:
    • tf包提供了TransformListener的实现,以帮助使接收变换的任务更容易。
    • 要使用TransformListener,我们需要包括tf/transform_listener.h头文件。
  • 代码:tf::TransformListener listener;

  • 作用:

    • 这里,我们创建一个TransformListener对象。
    • 一旦监听器被创建,它开始接收tf转换,并缓冲它们长达10秒。
    • TransformListener对象应该被限定为持久化,否则它的缓存将无法填充,并且几乎每个查询都将失败。
    • 一个常见的方法是使TransformListener对象成为一个类的成员变量。
  • 代码:

try{
listener.lookupTransform("/turtle2", "/turtle1",
ros::Time(0), transform);
}
  • 作用:这里,真正的工作完成了,我们查询监听器进行特定的转换。

  • 让我们来看看四个参数:

  • 1.我们想从/turtle2坐标系开始

  • 2.变换到/turtle1坐标系

  • 3.变换的时间,提供ros::Time(0)即会给出最近的可用的变换。

  • 4.结果存放的变换对象。

  • 这个代码放在try-catch结构,可以获取抛出的异常

  • 代码:

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) +
  • 作用:

    • 这里,变换用于计算龟的新的线性和角速度,基于它与龟的距离和角度。
    • 新的速度发布在话题"turtle2/cmd_vel"中,turtlesim将使用它来更新turtle2的运动。

运行监听

  • 打开CMakeLists.txt文件,并在底部添加以下行:
add_executable(turtle_tf_listener src/turtle_tf_listener.cpp)
target_link_libraries(turtle_tf_listener ${catkin_LIBRARIES})
  • 编译:
$ cd ~/catkin_ws
$ catkin_make
  • 如果一切顺利,你应该在devel/lib/learning_tf文件夹中有一个名为turtle_tf_listener的二进制文件。
  • 之前已经创建start_demo.launch,在 块,合并代码:
 <launch>
...
<node pkg="learning_tf" type="turtle_tf_listener"
name="listener" />
</launch>
  • 启动:
 $ roslaunch learning_tf start_demo.launch
  • 你应该看到turtlesim有两只海龟。

检查结果:

  • 要查看是否有效,只需使用箭头键(确保您的终端窗口处于活动状态,而不是模拟器窗口)绕过第一只乌龟,您会在第一只乌龟之后看到第二只乌龟!
  • 当turtlesim启动时,你可能会看到:
[ERROR] 1253915565.300572000: Frame id /turtle2 does not exist! When trying to transform between /turtle1 and /turtle2.
[ERROR] 1253915565.401172000: Frame id /turtle2 does not exist! When trying to transform between /turtle1 and /turtle2.
  • 这是因为我们的监听器试图在接收关于龟2的消息之前计算变换,因为它需要一点时间在turtlesim中生成并开始广播一个tf坐标系。

ROS tf监听编写的更多相关文章

  1. ROS tf

    一.节点中使用(cpp,python) 1. ros wiki 提供的tutorials 2. https://blog.csdn.net/start_from_scratch/article/det ...

  2. ros之tf坐标系广播与监听的编程实现

    创建功能包-learning_tf $ cd ~/catkin_ws/src $ catkin_create_pkg learning_tf roscpp rospy tf turtlesim 如何创 ...

  3. 使用HTML+CSS,jQuery编写的简易计算器后续(添加了键盘监听)

    之前发布了一款简易的计算器,今天做了一下修改,添加了键盘监听事件,不用再用鼠标点点点啦 JS代码: var yunSuan = 0;// 运算符号,0-无运算;1-加法;2-减法;3-乘法;4-除法 ...

  4. java Gui编程 事件监听机制

    1.     GUI编程引言 以前的学习当中,我们都使用的是命令交互方式: 例如:在DOS命令行中通过javac java命令启动程序. 软件的交互的方式:   1. 命令交互方式    图书管理系统 ...

  5. JAVA GUI 事件监听事件 详解 和 案例.

    GUI(图形用户界面) Graphical User Interface(图形用户接口) 用图形的 方式, 来显示 计算机操作的 界面, 这样更方便 更直观. CLI Command Line Use ...

  6. 学习ASP.NET Core, 怎能不了解请求处理管道[3]: 自定义一个服务器感受一下管道是如何监听、接收和响应请求的

    我们在<服务器在管道中的"龙头"地位>中对ASP.NET Core默认提供的具有跨平台能力的KestrelServer进行了介绍,为了让读者朋友们对管道中的服务器具有更 ...

  7. iOS监听tableView组头切换事件

    - (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSIntege ...

  8. Dcloud HTML5 监听蓝牙设备 调用 原生安卓实现

    最近一直搞Dcloud ,这是HTML5版本的开发,打包时候,可以打包成 apk 和ipa 分别运行在安卓和ios 机器上面, 但是这里面的资料很少,遇到问题,之后只能自己钻研总结, 现在有这么一个需 ...

  9. Self Host模式下的ASP. NET Web API是如何进行请求的监听与处理的?

    构成ASP.NET Web API核心框架的消息处理管道既不关心请求消息来源于何处,也不需要考虑响应消息归于何方.当我们采用Web Host模式将一个ASP.NET应用作为目标Web API的宿主时, ...

随机推荐

  1. composer.json详解

    composer.json 架构:https://docs.phpcomposer.com/04-schema.html#homepage composer.json 完全解析:https://lea ...

  2. Pollard-rho的质因数分解

    思路:见参考文章(原理我是写不粗来了) 代码: 用到了快速幂,米勒罗宾素性检验. #include <iostream> #include <time.h> #include ...

  3. 使用SecureCRT操作linux系统时候的简单设置

    因为第一次访问一台虚拟机的时候会出现这样的情况;   底色为白色和乱码的情况 需要在选项----->会话选项中进行一些设置 用来解决乱码问题的这个设置为:

  4. Python应用之-file 方法

    #!/usr/bin/env python # *_* coding=utf-8 *_* """ desc: 文件方法 ######################### ...

  5. c#2.0锐利体验《泛型编程》读书笔记

    1.c#泛型及机制 Class Stack<T> { } T 其实为type的缩小,不过也可为其他字符代替T ,被称为“泛型类型”  T为晚绑定的,在编译的时候还不能确定T的确切类型. 2 ...

  6. xshell连接不上阿里云服务器Could not connect to 'ip' (port 22): Connection failed.解决过程

    记一次xshell阿里云服务器突然连接不上的解决办法: 1, 确认阿里云服务器安全组出入都有22,百度出来都说的这个和ip拦截设置,以防万一都设置了:但楼主设置后,还是连不上服务器: 只好下一步 2, ...

  7. window对象(全局对象)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. junit3和junit4的区别总结

    先来看一个例子: 先用junit3来写测试用例,如下: junit3测试结果: 从上面可看出: 1.junit3必须要继承TestCase类 2.每次执行一个测试用例前,junit3执行一遍setup ...

  9. let

    let a=2+2 #+ - * / % ** 都支持 支持类C的计算方式 let i++ let i-- let i+=10 let i-=10 let i*=10 let i/=10 let i% ...

  10. 回文数 js 解法

    判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输入: -121 输出: false 解释: 从左向 ...