ROS 学习笔记(4)TF

  1. Transform Configuration(变换配置)

    http://wiki.ros.org/navigation/Tutorials/RobotSetup/TF?action=AttachFile&do=get&target=simple_robot.png

    两个坐标系:一个对应于机体中心点的坐标系(base_link),一个对应于扫描仪中心的坐标系(base_laser)。

    http://wiki.ros.org/navigation/Tutorials/RobotSetup/TF?action=AttachFile&do=get&target=tf_robot.png
    tf假设所有的转换都是从parent到child的,我们选择“base_link”坐标系作为parent,其他的传感器等,都是作为“器件”被添加进robot的,转换关系的表达式应该是(x:0.1m,y0.0m,z:0.2m)。

  2. 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();
        }
    }

     

  3. 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();
    }

     

  4. 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
  5.  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