ROS1学习笔记--tf变换
一、tf变换简介
机器人系统通常具有许多随时间变化的3D坐标系,例如世界坐标系(world frame),基准坐标系(base frame),夹具坐标系(gripper frame),头部坐标系(head frame)等。tf包可以随时记录所有这些坐标系,并可以解决如下问题:
- 5秒前,机器人头部坐标系相对于世界(全局)坐标系的关系是什么样的?
- 机器人夹取的物体相对于机器人的中心坐标的位置是什么?
- 机器人中心坐标系相对于全局坐标系的位置在哪里?
二、tf变换实例
1.实现一个tf广播器
- 定义一个tf广播器(TransformBroadcaster)
- 创建坐标变换值
- 发布坐标变换(sendTransform)
#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)
#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
推荐阅读
- EffectiveObjective-C2.0|EffectiveObjective-C2.0 笔记 - 第二部分
- 由浅入深理解AOP
- 继续努力,自主学习家庭Day135(20181015)
- python学习之|python学习之 实现QQ自动发送消息
- Android中的AES加密-下
- 一起来学习C语言的字符串转换函数
- 定制一套英文学习方案
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- 《深度倾听》第5天──「RIA学习力」便签输出第16期
- 如何更好的去学习