标签:wiki listen include jad main from 矩阵 作用 jade
tf是ros中一个很重要的模块,避免了我们在使用过程中不同坐标系下数据转换之间的困扰。目前使用主要是以下几种场景需要用到tf,
下面是我在学习中的一些整理和理解。
tf的使用主要分为两个部分,广播和监听。广播的作用是向系统中广播参考系之间的坐标变换关系,监听则是接收并缓存系统中发布的所有参考系变换。上面说的比较抽象,下面附上深蓝学院一个例子,以帮助更好理解。
广播部分的用法,比较固定。就是声明一个broadcaster,然后用其sendTransform方法发布一个tf::StampedTransform。这里面的核心在于tf::StampedTransform的构建。
tf::StampedTransform(const tf::Transform &input, const ros::Time ×tamp, const std::string &frame_id, const std::string &child_frame_id )
tf::StampedTransfor继承自tf::Transform,其第一个参数就是tf::Transform,第二个参数是timestamp,其中比较重要的是第三个和第四个参数,同时要注意一下第三个和第四个参数的名字,分别对应tf tree的父节点和子节点,例如例子中间的frame_id是base_link, child_frame_id是base_laser。在确定完第三、四个参数后,就需要来思考第一个参数的矩阵是如何构建的。深蓝学院的例子中,可以给我们参考,其实指的是child_frame_id在frame_id下的坐标,在例子中,右手坐标系下,laser在车辆坐标系下的坐标就是(0.1, 0.0, 0.2)。
转换矩阵的构建方法请参考
// name: tf_broadcaster.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;
ros::Rate r(100);
tf::TransformBroadcaster broadcaster;
while(n.ok()){
broadcaster.sendTransform(
tf::StampedTransform(
tf::Transform(tf::Quaternion(0, 0, 0, 1), tf::Vector3(0.1, 0.0, 0.2)), ros::Time::now(), "base_link", "base_laser"));
r.sleep();
}
}
listener部分也是比较死板的。还是首先需要一个监听器的对象,后面的做法有两种,一个是像例子中,使用listener.transformPoint("base_link", laser_point, base_point)。
void tf::TransformListener::transformDATATYPE (const std::string &target_frame, const geometry_msgs::DATATYPEStamped &stamped_in, geometry_msgs::DATATYPEStamped &stamped_out) const
这类方法是有3个输入参数,其中第一个是目标的坐标系,比如例子中,就是要在车的坐标系下进行观察。这个地方可以是任意你想切换到的坐标系,但是必须要是在tf tree中存在的。后面的两个是需要进行构建的,不同的transformDATATYPE是不一样的,需要查阅资料。在第二个参数中,会带上第二个参数所在的坐标系,由此就有了原坐标系,再由第一个参数,便可以再tf tree中查询到tf,在进行转换后会将结果储存在第三个参数中。
另外是一种保存转移矩阵,
void tf::TransformListener::lookupTransform (const std::string &target_frame, const std::string &source_frame, const ros::Time &time, StampedTransform &transform) const
这个部分的转移矩阵是结果,要注意其含义,是将在source_frame坐标系下的数据转换为在target_frame坐标系下的数据。比如source_frame是激光雷达的坐标系,而father_id_是车辆坐标起。
// name: tf_listener.cpp
#include <ros/ros.h>
#include <geometry_msgs/PointStamped.h>
#include <tf/transform_listener.h>
void transformPoint(const tf::TransformListener& listener){
geometry_msgs::PointStamped laser_point;
laser_point.header.frame_id = "base_laser";
laser_point.header.stamp = ros::Time();
laser_point.point.x = 1.0;
laser_point.point.y = 0.2;
laser_point.point.z = 0.0;
try{
geometry_msgs::PointStamped base_point;
listener.transformPoint("base_link", laser_point, base_point);
ROS_INFO("base_laser: (%.2f, %.2f. %.2f) -----> base_link: (%.2f, %.2f, %.2f) at time %.2f",
laser_point.point.x, laser_point.point.y, laser_point.point.z,
base_point.point.x, base_point.point.y, base_point.point.z, base_point.header.stamp.toSec());
}
catch(tf::TransformException& ex){
ROS_ERROR("Received an exception trying to transform a point from \"base_laser\" to \"base_link\": %s", ex.what());
}
}
int main(int argc, char** argv){
ros::init(argc, argv, "robot_tf_listener");
ros::NodeHandle n;
tf::TransformListener listener(ros::Duration(10));
ros::Timer timer = n.createTimer(ros::Duration(1.0), boost::bind(&transformPoint, boost::ref(listener)));
ros::spin();
}
标签:wiki listen include jad main from 矩阵 作用 jade
原文地址:https://www.cnblogs.com/ztyu/p/12424042.html