ROS1学习笔记--tf变换

一、tf变换简介
机器人系统通常具有许多随时间变化的3D坐标系,例如世界坐标系(world frame),基准坐标系(base frame),夹具坐标系(gripper frame),头部坐标系(head frame)等。tf包可以随时记录所有这些坐标系,并可以解决如下问题:

  • 5秒前,机器人头部坐标系相对于世界(全局)坐标系的关系是什么样的?
  • 机器人夹取的物体相对于机器人的中心坐标的位置是什么?
  • 机器人中心坐标系相对于全局坐标系的位置在哪里?
TF变换可以广播tf变换(broadcaster)和监听tf变换(lisenter)来实现。
二、tf变换实例
1.实现一个tf广播器
  • 定义一个tf广播器(TransformBroadcaster)
  • 创建坐标变换值
  • 发布坐标变换(sendTransform)
代码实现:src/turtle_tf_broadcaster.cpp.
#include #include #include std::string turrtle_name; void poseCallback(const turtlesim::PoseConstPtr& msg) { //创建一个tf广播器 static tf::TransformBroadcaster br; //创建一个Transform对象,根据当前海龟的位置,设置相对与世界坐标系的坐标变换 tf::Transform transform; transform.setOrigin( tf::Vector3(msg->x, msg->y, 0.0) ); tf::Quaternion q; q.setRPY(0, 0, msg->theta); transform.setRotation(q); //设置旋转//发布坐标变换,(transform,发布时间戳,父坐标系,子坐标系) br.sendTransform(tf::StampedTransform(transform, ros::Time::now(), "world", turtle_name)); }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]; //订阅turtle的位置(pose)信息 ros::NodeHandle node; ros::Subscriber sub = node.subscribe(turtle_name+"/pose", 10, &poseCallback); //循环等待 ros::spin(); return 0; };

参考网站:小海龟例程broadcaster

2.实现一个TF监听器
  • 定义一个tf监听器(TransformListener)
  • 查找坐标变换(waitTransform.lookupTransform)
代码实现:src/turtle_tf_listener.cpp
#include #include #include #include int main(int argc, char** argv) { //初始化节点 ros::init(argc, argv, "my_tf_listener"); //创建句柄,如果一个节点没有启动,节点句柄会自动启动该节点 ros::NodeHandle node; //通过服务调用,产生第二只海龟 ros::service::waitForService("spawn"); ros::ServiceClient add_turtle = node.serviceClient("spawn"); turtlesim::Spawn srv; add_turtle.call(srv); //定义第二只海龟的速度发布器,发布频率为10hz ros::Publisher turtle_vel = node.advertise("turtle2/cmd_vel", 10); //创建一个tf监听器 tf::TransformListener listener; ros::Rate rate(10.0); while (node.ok()){ tf::StampedTransform transform; try{ //查找两个海龟间的坐标变换 listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform); } catch (tf::TransformException &ex) { ROS_ERROR("%s",ex.what()); ros::Duration(1.0).sleep(); continue; }//基于两个海龟之间的坐标变换,计算turtle2的新的线性和角速度 //新速度发布在主题“turtle2 / cmd_vel”中,sim将使用它来更新turtle2的移动。 geometry_msgs::Twist vel_msg; vel_msg.angular.z = 4.0 * atan2(transform.getOrigin().y(), transform.getOrigin().x()); vel_msg.linear.x = 0.5 * sqrt(pow(transform.getOrigin().x(), 2) + pow(transform.getOrigin().y(), 2)); turtle_vel.publish(vel_msg); rate.sleep(); } return 0; };


三、添加一个额外的固定坐标系
参考网站:Tutorials

四、学会使用waitTranform
【ROS1学习笔记--tf变换】参考网站:Tutorials

五、高级时间历史功能
参考网站:Tutorials


还有很多没有详细看,有时间再添加



参考网站:
官方wiki:tf_ROS.wik
海龟跟随小例程:tf_demo
官方Tutorials:http://wiki.ros.org/tf/Tutorials
古月居tf:重读tf






listener参考网站:小海龟例程listener

    推荐阅读