ROS订阅tf并转换坐标

tf2/tf1坐标计算,坐标变换,坐标取逆,坐标订阅,坐标发布 tf2坐标计算,坐标变换,坐标取逆,坐标订阅,坐标发布等 阅读详情
  • 不要在函数中,特别是回调函数中声明TransformListener对象
  • TransformListener对象应该被限定为持久化,否则它的缓存将无法填充,并且几乎每个查询都将失败。出现Lookup would require extrapolation at time 1657511018.391161648, but only time 1657511018.856185462 is in the buffer之类的问题
  • 一个常见的方法是使TransformListener对象成为一个类的成员变量
#include <ros/ros.h>
#include <tf/transform_listener.h>
#include <tf/transform_datatypes.h>
#include <geometry_msgs/Quaternion.h>
#include <nav_msgs/OccupancyGrid.h>
#include <sensor_msgs/LaserScan.h>

class Callback
{
public:
  tf::TransformListener listener_;
  tf::StampedTransform transform_;
  ros::Subscriber sub_;
  double last_x_;
  double last_y_;
  double last_angle_;

  Callback(ros::NodeHandle n)
  {
    last_x_ = 0;
    last_y_ = 0;
    last_angle_ = 0;
    sub_ = n.subscribe<sensor_msgs::LaserScan>("/scan", 1, &Callback::CB, this);
  }
  void CB(const sensor_msgs::LaserScanConstPtr &scan);
};

void Callback::CB(const sensor_msgs::LaserScanConstPtr &scan)
{

  try
  {
    // base_link to map
    listener_.waitForTransform("/map",
                               "/base_link",
                               ros::Time(0), ros::Duration(0.2));
    listener_.lookupTransform("map",
                              "base_link",
                              ros::Time(0), transform_);
  }
  catch (tf::TransformException &ex)
  {
    ROS_ERROR("%s", ex.what());
    return;
  }
  double dx = transform_.getOrigin().x() - last_x_;
  double dy = transform_.getOrigin().y() - last_y_;
  double distance = sqrt(dx * dx + dy * dy);
  tf::Quaternion quat;
  double qx = transform_.getRotation().x(), qy = transform_.getRotation().y(),
         qz = transform_.getRotation().z(), qw = transform_.getRotation().w();
  geometry_msgs::Quaternion qua;
  qua.x = qx;
  qua.y = qy;
  qua.z = qz;
  qua.w = qw;
  tf::quaternionMsgToTF(qua, quat);
  double roll, pitch, yaw;
  tf::Matrix3x3(quat).getRPY(roll, pitch, yaw);
  if (yaw >= 6.27)
    yaw = 0;
  double a = (yaw - last_angle_) * 180 / 3.14159;
  if (a < 0)
    a = -a;
  if (a >= 30 || distance >= 1.1)
  {
    ROS_INFO("%lf, %lf", distance, a);
    last_x_ = transform_.getOrigin().x();
    last_y_ = transform_.getOrigin().y();
    last_angle_ = yaw;
  }
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "lwd_tf");
  ros::NodeHandle n;
  Callback cb(n);
  ros::spin();
  return 0;
}

  • 下面的就不要看了,历史的眼泪
#include <pcl/point_cloud.h>
#include <pcl_conversions/pcl_conversions.h>
#include <ros/ros.h>
#include <sensor_msgs/PointCloud2.h>
#include <tf/transform_listener.h>

void CB(const sensor_msgs::PointCloud2ConstPtr& pc, ros::Publisher& pub) {
  float x = 2.8, y = z = 1.1;
  tf::TransformListener listener;
  tf::StampedTransform transform;
  try {
  	// camera to base_link
    listener.waitForTransform("/base_link",
                              "/realsense_camera_depth_optical_frame",
                              ros::Time(0), ros::Duration(0.2));
    listener.lookupTransform("base_link",
                             "realsense_camera_depth_optical_frame",
                             ros::Time(0), transform);
  } catch (tf::TransformException& ex) {
    ROS_ERROR("%s", ex.what());
    return;
  }
  
    float R[4][4];
    float qx = transform.getRotation().x(), qy = transform.getRotation().y(),
          qz = transform.getRotation().z(), qw = transform.getRotation().w();
    float scale = 1 / sqrt(qx * qx + qy * qy + qz * qz + qw * qw);
    qx *= scale, qy *= scale, qz *= scale, qw *= scale;
    R[0][0] = 1 - 2 * qy * qy - 2 * qz * qz;
    R[0][1] = 2 * qx * qy - 2 * qz * qw;
    R[0][2] = 2 * qx * qz + 2 * qy * qw;
    R[0][3] = 0;
    R[1][0] = 2 * qx * qy + 2 * qz * qw;
    R[1][1] = 1 - 2 * qx * qx - 2 * qz * qz;
    R[1][2] = 2.0f * qy * qz - 2.0f * qx * qw;
    R[1][3] = 0;
    R[2][0] = 2.0f * qx * qz - 2.0f * qy * qw;
    R[2][1] = 2.0f * qy * qz + 2.0f * qx * qw;
    R[2][2] = 1.0f - 2.0f * qx * qx - 2.0f * qy * qy;
    R[2][3] = R[3][0] = R[3][1] = R[3][2] = 0;
    R[3][3] = 1;
    float xx = x * R[0][0] + y * R[0][1] + z * R[0][2] + R[0][3] +
               transform.getOrigin().x();
    float yy = x * R[1][0] + y * R[1][1] + z * R[1][2] + R[1][3] +
               transform.getOrigin().y();
    float zz = x * R[2][0] + y * R[2][1] + z * R[2][2] + R[2][3] +
               transform.getOrigin().z();
}

int main(int argc, char** argv) {
  ros::init(argc, argv, "listener");
  ros::NodeHandle n;
  ros::Publisher pcl_pub =
      n.advertise<sensor_msgs::PointCloud2>("pcl_output", 1);
  ros::Subscriber sub = n.subscribe<sensor_msgs::PointCloud2>(
      "/depth/color/points", 1, boost::bind(&CB, _1, pcl_pub));
  ros::spin();
  return 0;
}
Docker网络教程(四)macvlan 网络教程 在这种网络下,Docker 宿主机在它的IP之上,允许接受多个 MAC 地址的请求,然后再将这些请求路由至对应的容器里。流通,Docker 会用它的 MAC 地址,把流量路由进你的容器里。对于网络上的网络设备来说,你的容器似乎是物理上连接到网络上的。),Docker使用其MAC地址将流量路由到你的容器。对于网络上的网络设备来说,你的容器似乎是物理上连接到网络上的。你需要 3.9 或者更高版本的 Linux 内核,4.0 以及以上的版本是更好的。如果你的设备叫别的名字,用对应的名字代替。 阅读详情

相关推荐

AISHELL-2 中文语音数据库

AISHELL-1 is by far the largest open-source speech corpus available for Mandarin speech recognition research. It was released with a baseline system containing solid training and testing pipelines for Mandarin ASR. In AISHELL-2, 1000 hours of cle

AI_SHELL的博客 7887

关于ros --tf2的使用

在tf2系统中,将包分为tf2和tf2_ros。tf2用来进行坐标旋转,以及tf、msg两种四元素数据结构的变换;tf2_ros负责与ROS数据通信打交道,负责发布tf或订阅tf,即发布者和订阅者是在tf2_ros命名空间下的。1、tf2 (姿态变换和tf格式转换) 1.1 四元数的组成 一个四元素有4个成员(x,y,z,w)。不绕xyz轴旋转的常用单位四元数为(0,0,0,1)。注意: w 是最后一个,但是一些库像 Eigen 把 w 放在第一的位置。 四元数的大小应为1。 如果数值错误导致四元数的大小不

weixin_48631463的博客 3550

ENU坐标系实战:5分钟搞定无人机导航中的站心坐标转换

本文针对无人机导航中GPS坐标与视觉感知不匹配的定位漂移问题,提供了基于ENU坐标系的实战解决方案。通过Python代码演示了如何快速、精准地实现地心地固坐标与站心坐标之间的转换,并详细解释了转换原理、精度对比及工程优化技巧,帮助开发者从根本上解决局部相对定位不准的难题。

mqtt6iot的博客 552

ROS机器人操作系统开发视频教程进阶-ros节点发布订阅(五)

ROS机器人操作系统开发视频教程进阶(记录感悟和过程)五、ros节点发布和订阅 五、ros节点发布和订阅 1、ROS节点编程 使用robware开发环境,创建节点框架 打开开发环境robot_1 然后,右键src-新建ROS包-命名为test-右键新建的test-新建C++ROS节点-节点名称为test -自动生成文件代码框架 订阅test_sub.cpp文件代码及解释如下: clude "ros/ros.h" #include "std_msgs/String.h" void chatterCallba

qq_45954434的博客 804

Notion访问卡顿?一键优化DNS与Hosts提升加载速度

本文针对Notion访问卡顿问题,提供了两种核心优化方案:修改Hosts文件与配置DNS。详细解析了卡顿根源在于网络链路,并手把手指导用户在Windows、Mac、iOS及Android设备上实施优化,旨在通过替换为更优线路,显著提升Notion的页面加载与同步速度。

fff88的博客 1195

极智量化平台实战:5分钟教你用Python实现双均线交易策略(附完整代码)

本文详细介绍了如何在极智量化平台上使用Python实现双均线交易策略,包括数据获取、信号生成、回测分析和策略优化。通过完整的代码示例和实战演示,帮助开发者快速掌握量化交易系统的基本原理和应用方法,实现自动化交易。

weixin_29269441的博客 487

ROS TF相关笔记

1

dzysdhr1234的博客 702

从网格划分到结果解读:一次完整的子弹侵彻LS-DYNA仿真避坑指南

本文详细解析了子弹侵彻LS-DYNA仿真中的关键技术与避坑指南,涵盖网格优化、对称边界条件设置、沙漏控制参数调整及结果可信度验证。通过HyperMesh网格划分和LS-DYNA高级参数配置,帮助工程师提升仿真精度与效率,确保计算结果物理可信。

weixin_29816689的博客 406

ros tf 发布和订阅demo(附c++代码)

发布demo代码如下: 订阅demo代码如下:

weixin_45024226的博客 2775

AST实战:解密Akamai混淆JS代码的完整流程

本文详细解析了如何使用AST技术解密Akamai混淆的JS代码,包括定位关键代码、AST解混淆实战步骤及常见问题解决方案。通过实际案例演示了从混淆代码到清晰逻辑的完整处理流程,并提供了工具推荐和法律合规建议,帮助开发者有效应对反爬虫技术。

weixin_33725722的博客 313

2026年【江苏“信息与未来”编程思维】真题及题解(T6:桌面游戏)

2026年【江苏“信息与未来”编程思维】真题及题解(T6:桌面游戏)

王老师青少年编程 533

P8 ROS节点编程发布订阅TF

查找wiki demo样例:wiki主页的Core Libraries。 直接在launch中启用坐标系发布节点,在command tool栏 通过编程实现坐标系发布节点,在参考api栏

☜@_@达奚黑雁的博客 249

SDR 和 DDR 的区别

SDR 和 DDR 的差别,最明显提现在传输速率和频率上。DDR SDRAM与SDRAM的基本结构是相似的,最根本的区别在于DDR 支持在一个时钟周期内传输两次数据,,SDR 只能传输一次数据。

串起点滴 1958

ROS中的静态坐标转换(解析+示例)

什么是TF2? tf2是一个用来描述物体空间位置的工具。我们知道,用一个三维向量和一个四元数就可以描述一个物体相对于一个参考系的位置与姿态,tf2的工作属于“小而美”,它只专注于在ROS2中提供这样一个功能,就是描述一组物体之间的相对位置关系。 为何要使用TF2? TF2可以用于描述机器人各关节的相对位置,大大方便了运动学求解。不仅如此,在多机器人的场景中,tf2还可以用于描述机器人之间的相对位置,从而执行跟随、避障等操作。此外,tf2也可以用于描述目标物体与机器人的相对位置。总而言之,我们只需提供坐

超级霸霸强的博客 6863

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

ROS中TF(坐标系转换)原理与使用

TF(TransForm),就是坐标转换,包括了位置和姿态两个方面的变换。注意区分坐标转换和坐标系转换。坐标转换是一个坐标在不同坐标系下的表示,而坐标系转换不同坐标系的相对位姿关系。ROS中机器人模型包含大量的部件,每一个部件统称之为link(比如手部、头部、某个关节、某个连杆),每一个link上面对应着一个frame(坐标系), 用frame表示该部件的坐标系,frame和link是绑定在一起的。可以被当做是一种标准规范,这套标准定义了坐标转换的数据格式和数据结构.tf本质是树状的数据结构,即。

m0_53316604的博客 3016

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

【ROS程序】 --- 2-2. TF--实时坐标转换

“无人问津的日子里”I、准备工作II、demo02中发布程序的思路III、demo02中订阅程序的思路III、实现以及效果查看IV 全部源码02pub_pose.cpp02sub_pose.cpp 本节来看看动态坐标转换,就小乌龟而言,我们在上一专栏的学习中,很容易得到小乌龟当前位置信息。 此时坐标系为(0,0 ),将乌龟坐标系下的点(1,1)转化到世界坐标系下。 I、准备工作 延用工作空间test2_ws; 功能包demo2_trans_pose存放代码; 发布代码放在02pub_pose.cpp中; 订

Eric_Sober的博客 769

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

ROS TF2 :通过tf2_ros::MessageFilter 将世界坐标系下的点转为期望坐标系下的点

ROS TF2 :通过tf2_ros::MessageFilter 将世界坐标系下的点转为期望坐标系下的点1、情景2、实现代码3、代码解释4、 疑问 本片博客描述:如何使用 tf2_ros::MessageFilter 处理 Stamped(时间戳) 数据类型 在 TF2 的 体系下 如何使用传感器的数据 在 实际 情况下 传感器的数据包括: 相机、激光雷达 1、情景 假设一只新的乌龟 命名为 乌龟3 , 它没有好的里程计(也就是说不指定它的具体坐标),但是现在有一个上方的相机 跟踪 它的位置并且发布

月照银海似蛟龙的博客 1080

ROS tf2 坐标变换学习(一)

b站参考这里 b站视频在线参考文档当前TF转换文档页面 ros官方说明参考这里 开始前注意以下代码处于ros工作区的位置,ros下的调用方式参考视频,以下为视频中基于ros tf2的使用记录 1.ROS tf2 功能总结描述 2.参数与类型 geometry_msgs/TransformStamped.msg geometry_msgs/PointStamped Message 一.静态坐标变换 两个坐标的位置是固定的,如下图的雷达和雷达下方的小车 步骤流程如下 python参考静态坐标变换老师

weixin_43134049的博客 5087

ROS中的坐标与坐标系转换

ROS中的TF 官网建议新工作直接使用tf2,因为它有一个更清洁的界面,和更好的使用体验。(自ROS Hydro以来,tf第一代已被“弃用”,转而支持tf2) TF介绍 TF(TransForm),就是坐标转换,包括了位置和姿态两个方面的变换。注意区分坐标转换和坐标系转换。 坐标转换是一个坐标在不同坐标系下的表示,而坐标系转换不同坐标系的相对位姿关系。 ROS中机器人模型包含大量的部件,每一个部件统称之为link(比如手部、头部、某个关节、某个连杆),每一个link上面对应着一个frame(坐标系), 用f

张飞飞的博客 6057

ros -- 动态坐标变换

ROS的学习

zycpersevere的博客 504

ROS学习第二十节——TF动态坐标变换

所谓动态坐标变换,是指两个坐标系之间的相对位置是变化的。需求描述:启动 turtlesim_node,该节点中窗体有一个世界坐标系(左下角为坐标系原点),乌龟是另一个坐标系,键盘控制乌龟运动,将两个坐标系的相对位置动态发布。实现分析:乌龟本身不但可以看作坐标系,也是世界坐标系中的一个坐标点订阅 turtle1/pose,可以获取乌龟在世界坐标系的 x坐标、y坐标、偏移量以及线速度和角速度将 pose 信息转换成 坐标系相对信息并发布。

qq_45685327的博客 454

ROS 动态坐标变换

通过编码实现ROS动态坐标变换

weixin_45205599的博客 539

读取/IMU topic并以TF转发

读取/IMU topic并以TF转发 #include <ros/ros.h> #include <sensor_msgs/Imu.h> #include <tf/transform_broadcaster.h> /* 参考ROS wiki * http://wiki.ros.org/tf/Tutorials/Writing%20a%20tf%20broadcaster%20%28C%2B%2B%29 * */ void ImuCallback(const sens

weixin_41698305的博客 1205

【ROS1】17-多坐标变换

本文介绍了多坐标变换的应用,通过案例演示了父子坐标系转换的实现过程。以world、son1和son2坐标系为例,详细说明了实现步骤:1)使用static_transform_publisher发布坐标系相对关系;2)通过tf2_ros实现坐标系转换;3)完成坐标点在不同坐标系间的转换计算。最后给出C++订阅方实现代码,展示了如何获取坐标系相对关系并转换坐标点。

ChaoChao66666的博客 1003

TF2动态转换-dynamic

但不同的坐标系可能不像是之前静态的pub,发布方的坐标是动态变化的,所以我们不能时时改写发布方的文档来适应它,这不合理也不精准。

Mr_rustylake的博客 269

ROS下点云消息接收、TF关系获取和点云坐标系的转换,保姆级教程

点云数据读取 读取点云数据有三种方法: 1.读取本地的pcd文件(没用过); 给个pcd文件读取并发布的例子,需要的操作里面都有 //总得导入ros吧 #include <ros/ros.h> //导入消息格式 #include <sensor_msgs/PointCloud2.h> //导入pcl #include <pcl_conversions/pcl_conversions.h> #include <pcl/point_cloud.h> #i

qq_41505897的博客 7729
上一篇: 深度图坐标转化彩色图坐标
下一篇: 深度学习之权重初始化
刀么克瑟拉莫
博客等级 码龄14年 68粉丝 268原创
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刀么克瑟拉莫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值