ROS学习之TF变换

TF能够根据时间缓冲并维护多个参考系之间的坐标变换,可以在任意时间,将点、向量、等数据的坐标,完成坐标变换。

TF的使用方法(两个概念了解一下):
监听tf变换
接收并缓存系统中发布的所有参考系变换,并从中查询所需要的参考系变换。
广播tf变换
向系统中广播参考系之间的坐标变换关系。系统中更能可能会存在多个不同部分的tf变换广播,每个广播都可以直接将参考系变换关系直接插入tf树中,不需要在进行同步。

A.TF包内的指令工具:

  1. 指令 tf_monitor 打印tf树中所有的所有参考系信息
  2. 指令tf_echo 查看指定参考系之间的变换关系
  3. 指令 static_transform_publisher 发布两个参考系之间的静态坐标系变换

static_transform_publisher x y z yaw pitch roll frame_id
child_frame_id period_in_ms
static_transform_publisher x y z qx qz qw fram_id child_frame_id period_in_ms

yaw代表这绕z轴旋转的角度,pitch代表绕Y轴的角度,roll代表绕X轴的角度。

实例:在这里插入图片描述

<noed 
	pkg="tf" type="static_transform_publisher" name="base_link_to_laser"
	args="-0.023 0 0.15 3.141593 0 0 /base_link /laser 100"
/>

解释一下该launch文件内容
pkg=“tf” 来自tf功能包
type=“static_transform_publisher” 该功能包下的static_transform_publisher结点
name=“base_link_to_laser"给该结点取名叫base_link_to_laser
arges=”-0.023 0 0.15 3.141593 0 0 /base_link /laser 100"
x y z表示子节点相对于主节点的位置
"3.141593 0 0"表示子节点绕z轴旋转180°,即将laser掉了一个头
/base_link 父坐标
/laser 子坐标
100 每100ms广播一次tf变换

B.TF功能包API
广播变换

tf::TransformBroadcaster(); //创建tf广播变换
//发送变换
void sendTransform(const StampedTransform& transform);
void sendTransform(const geometry_msgs::TransformStamped& transform);
在使用这两个函数在前,在创建功能包时:catkin_create_pkg learning_tf tf roscpp rospy turtlesim 得加入tf依赖这一项

测试接收到的TF变换

tf::TransformListener::canTransform(…)
tf::TransformListener::waitForTransform(…)

接收并转换TF数据

tf::TransformListener::lookupTransForm(…)变换2个坐标
tf::TransformListener::transformDATATYPE(…)转换数据

#include <ros/ros.h>
#include <tf/transform_broadcaster.h>	//TransformBroadcaster包含在该头文件中
#include <turtlesim/Pose.h>
    
std::string turtle_name;
    
    
    
void poseCallback(const turtlesim::PoseConstPtr& msg){

	 //创建tf广播变换
	 static tf::TransformBroadcaster br;			
	 
	 //创建一个变换,将2D位姿转变为3D位姿
     tf::Transform transform;							
     transform.setOrigin( tf::Vector3(0.1, 0, 0.2) );//相对父坐标的。。x y z
     tf::Quaternion q;
     q.setRPY(0, 0, 3.1416);//相对父坐标旋转了180°
     transform.setRotation(q);		
     
     //真正有用的在这
     br.sendTransform(tf::StampedTransform(transform, ros::Time::now(),"/base_link", "/laser"));
     //第一个参数 赋予transform时间戳  第二个坐标是父坐标系,第三个是子坐标系
   }
   
   int main(int argc, char** argv){
     ros::init(argc, argv, "my_tf_broadcaster");
     if (argc != 2){ROS_ERROR("need turtle name as argument"); return -1;};
     turtle_name = argv[1];
   
     ros::NodeHandle node;
     ros::Subscriber sub = node.subscribe(turtle_name+"/pose", 10, &poseCallback);
   
     ros::spin();
     return 0;
   };

最后在Cmakelist中添加:

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ROS中实现tf变换需要以下两个步骤: 1. 发布tf变换信息:需要创建一个tf广播器,通过该广播器发布机器人各个坐标系之间的tf变换信息。在ROS中,可以使用`tf::TransformBroadcaster`类来实现tf变换信息的发布,具体步骤如下: - 创建一个`tf::TransformBroadcaster`对象。 - 构造一个`tf::Transform`对象,表示需要发布的tf变换信息。 - 调用`sendTransform()`函数发布tf变换信息。 2. 订阅tf变换信息:需要创建一个tf监听器,通过该监听器订阅机器人各个坐标系之间的tf变换信息。在ROS中,可以使用`tf::TransformListener`类来实现tf变换信息的订阅,具体步骤如下: - 创建一个`tf::TransformListener`对象。 - 调用`lookupTransform()`函数获取需要订阅的tf变换信息。 下面是一个简单的例子,演示如何通过tf广播器发布机器人的tf变换信息: ```cpp #include <ros/ros.h> #include <tf/transform_broadcaster.h> int main(int argc, char** argv){ ros::init(argc, argv, "robot_tf_publisher"); ros::NodeHandle n; tf::TransformBroadcaster broadcaster; ros::Rate loop_rate(10.0); while (n.ok()){ tf::Transform transform; transform.setOrigin( tf::Vector3(0.0, 2.0, 0.0) ); tf::Quaternion q; q.setRPY(0, 0, 1.57); transform.setRotation(q); broadcaster.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "base_link", "laser")); loop_rate.sleep(); } return 0; }; ``` 上述代码中,创建了一个tf广播器`broadcaster`,并在每个循环周期中发布机器人的tf变换信息,其中`setOrigin()`函数和`setRotation()`函数用于设置机器人的坐标系之间的变换关系。在本例中,机器人的激光雷达坐标系"laser"相对于机器人底盘坐标系"base_link"沿着z轴平移了2米,并绕z轴旋转了90度(即1.57弧度)。 如果需要订阅机器人的tf变换信息,可以通过如下代码实现: ```cpp #include <ros/ros.h> #include <tf/transform_listener.h> int main(int argc, char** argv){ ros::init(argc, argv, "robot_tf_listener"); ros::NodeHandle n; tf::TransformListener listener; ros::Rate loop_rate(10.0); while (n.ok()){ tf::StampedTransform transform; try{ listener.lookupTransform("base_link", "laser", ros::Time(0), transform); } catch (tf::TransformException &ex) { ROS_ERROR("%s",ex.what()); ros::Duration(1.0).sleep(); continue; } ROS_INFO("Translation: [%f, %f, %f]", transform.getOrigin().x(), transform.getOrigin().y(), transform.getOrigin().z()); ROS_INFO("Rotation: [%f, %f, %f, %f]", transform.getRotation().x(), transform.getRotation().y(), transform.getRotation().z(), transform.getRotation().w()); loop_rate.sleep(); } return 0; }; ``` 上述代码中,创建了一个tf监听器`listener`,并在每个循环周期中获取机器人的tf变换信息,其中`lookupTransform()`函数用于获取机器人底盘坐标系"base_link"到激光雷达坐标系"laser"之间的tf变换信息,`getOrigin()`函数和`getRotation()`函数用于获取tf变换信息中的平移和旋转部分。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值