2019年10月6日
ROS 学习笔记(4)TF
-
Transform Configuration(变换配置)
两个坐标系:一个对应于机体中心点的坐标系(base_link),一个对应于扫描仪中心的坐标系(base_laser)。
tf假设所有的转换都是从parent到child的,我们选择“base_link”坐标系作为parent,其他的传感器等,都是作为“器件”被添加进robot的,转换关系的表达式应该是(x:0.1m,y0.0m,z:0.2m)。 - Writing Code(代码编写)
$ cd %TOP_DIR_YOUR_CATKIN_WS%/src $ catkin_create_pkg robot_setup_tf roscpp tf geometry_msgs $ vi robot_setup_tf/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(); } }
- Using a Transform(调用变换)
#include <ros/ros.h> #include <geometry_msgs/PointStamped.h> #include <tf/transform_listener.h> void transformPoint(const tf::TransformListener& listener){ //we'll create a point in the base_laser frame that we'd like to transform to the base_link frame geometry_msgs::PointStamped laser_point; laser_point.header.frame_id = "base_laser"; //we'll just use the most recent transform available for our simple example laser_point.header.stamp = ros::Time(); //just an arbitrary point in space 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)); //we'll transform a point once every second ros::Timer timer = n.createTimer(ros::Duration(1.0), boost::bind(&transformPoint, boost::ref(listener))); ros::spin(); }
- Building the Code代码构建
CMakeList.txt添加以下内容:add_executable(tf_broadcaster src/tf_broadcaster.cpp) add_executable(tf_listener src/tf_listener.cpp) target_link_libraries(tf_broadcaster ${catkin_LIBRARIES}) target_link_libraries(tf_listener ${catkin_LIBRARIES})
$ cd %TOP_DIR_YOUR_CATKIN_WS% $ catkin_make
- Running the Code(代码运行)
好的,万事俱备只欠东风!让我恩试着实际运行下吧。这部分,你需要开三个终端窗口
第一个窗口,运行core
roscore
第二个,运行 tf_broadcaster
rosrun robot_setup_tf tf_broadcaster
好的。现在,我们会在第三个窗口运行tf_listener,将从传感器坐标系获取的虚拟点,变换到机体坐标系。
rosrun robot_setup_tf tf_listener
抄自:http://wiki.ros.org/cn/navigation/Tutorials/RobotSetup/TF