使用tf内置节点进行坐标变换时,为何要同时实现坐标信息的发布方与坐标信息的订阅方?

答案是不行的,那为什么提出要用一个文件实现坐标变换呢?因为我们实现坐标变换时,只需要获知坐标系相对位置关系坐标点在源坐标系中的坐标即可实现坐标变换。因此我们想在一个CPP文件中声明坐标系的关系和坐标点在源坐标系中的坐标,然后再使用tfs_ros::buffer中的transform函数一气呵成计算出坐标点基于目标坐标系的坐标。理论上来说还挺行得通,但是真的如此吗?

错误代码示例:

#include "ros/ros.h"  
#include "geometry_msgs/TransformStamped.h"  
#include "geometry_msgs/PointStamped.h"  
#include "tf2_geometry_msgs/tf2_geometry_msgs.h"  
#include "tf2/LinearMath/Quaternion.h"  
#include "tf2_ros/buffer.h"  
  
int main(int argc,char* argv[])  
{  
    setlocale(LC_ALL,"");  
    ros::init(argc,argv,"static_tf2");  
    geometry_msgs::TransformStamped transform;  
    transform.child_frame_id = "son1";  
    transform.header.frame_id = "son2";  
    transform.header.stamp = ros::Time::now();  
    transform.transform.translation.x = 10;  
    transform.transform.translation.y = 10;  
    // 二维平面无Z轴偏移  
    transform.transform.translation.z = 0;  
    // 在XOY平面上的旋转均是围绕垂直于XOY平面的轴进行的  
    tf2::Quaternion qtn(0,0,90);  
    transform.transform.rotation.w = qtn.getW();  
    transform.transform.rotation.x = qtn.getX();  
    transform.transform.rotation.y = qtn.getY();  
    transform.transform.rotation.z = qtn.getZ();  
    geometry_msgs::PointStamped PointOnSon1;  
    PointOnSon1.header.frame_id = "son1";  
    PointOnSon1.header.stamp = ros::Time();  
    PointOnSon1.point.x = 10;  
    PointOnSon1.point.y = 10;  
    PointOnSon1.point.z = 10;  
    // 错误使用buffer  
    geometry_msgs::PointStamped PointOnSon2;  
    tf2_ros::Buffer buffer;  
    PointOnSon2 = buffer.transform(PointOnSon1,"son2");  
    ROS_INFO("PointOnSon2:%d,%d,%d\n\t",PointOnSon2.point.x,PointOnSon2.point.y,PointOnSon2.point.z);  
}

这段代码看起来挺顺眼的没有语法错误,那怎么错了呢?出错位置如下所示:

// 错误使用buffer  
geometry_msgs::PointStamped PointOnSon2;  
tf2_ros::Buffer buffer;  
PointOnSon2 = buffer.transform(PointOnSon1,"son2"); 

我们的本意是“使用存在buffer中坐标系相对位置关系将坐标点在son1坐标系下的坐标转换至基于son2坐标系的坐标”,但我们忽略了一点“坐标系相对位置关系存入buffer了吗?”

还记得我们在使用话题通信传递坐标关系时,发布端/订阅端的发布/订阅实现分别如下:

发布端发布坐标关系:

geometry_msgs::TransformStamped transform;  
transform.child_frame_id = "son1";  
transform.header.frame_id = "son2";  
transform.header.stamp = ros::Time::now();  
transform.transform.translation.x = 10;  
transform.transform.translation.y = 10;  
// 二维平面无Z轴偏移  
transform.transform.translation.z = 0;  
// 在XOY平面上的旋转均是围绕垂直于XOY平面的轴进行的  
tf2::Quaternion qtn(0,0,90);  
transform.transform.rotation.w = qtn.getW();  
transform.transform.rotation.x = qtn.getX();  
transform.transform.rotation.y = qtn.getY();  
transform.transform.rotation.z = qtn.getZ();  
tf2_ros::StaticTransformBroadcaster pub;  
pub.sendTransform(transform); 

订阅端订阅坐标关系并存入属于对象自己的buffer当中去:

tf2_ros::Buffer buffer;  
tf2_ros::TransformListener listen(buffer);  
PointOnSon2 = buffer.transform(PointOnSon1,"son2");  
ROS_INFO("PointOnSon2:%d,%d,%d\n\t",PointOnSon2.point.x,PointOnSon2.point.y,PointOnSon2.point.z);  

在订阅端中我们通过传入buffer对象,构建了属于listener对象的缓冲区,该缓冲区用于保存通过tf2_static话题传来的坐标系相对位置关系。最上面那个代码错误的原因就是“我们根本没有任何途径将坐标系相对位置关系传入buffer当中去,还谈何使用buffer中的位置关系呀”!现在,我们可以知道为何不可以使用一个CPP文件去进行坐标变换了吧。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

肥肥胖胖是太阳

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

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

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

打赏作者

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

抵扣说明:

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

余额充值