TF能够根据时间缓冲并维护多个参考系之间的坐标变换,可以在任意时间,将点、向量、等数据的坐标,完成坐标变换。
TF的使用方法(两个概念了解一下):
监听tf变换
接收并缓存系统中发布的所有参考系变换,并从中查询所需要的参考系变换。
广播tf变换
向系统中广播参考系之间的坐标变换关系。系统中更能可能会存在多个不同部分的tf变换广播,每个广播都可以直接将参考系变换关系直接插入tf树中,不需要在进行同步。
A.TF包内的指令工具:
- 指令 tf_monitor 打印tf树中所有的所有参考系信息
- 指令tf_echo 查看指定参考系之间的变换关系
- 指令 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})