ROS学习之tf基本用法

主要细节参见wiki,这里我写一下它的broadcaster和listener做个记录:

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 node;
    
    ros::Rate rate(100);
 
    tf::TransformBroadcaster broadcaster;
    while(node.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"
            )
        );
        rate.sleep();
    }
}

在broadcaster中我们主要描述的是两个坐标frame之间的位置关系,这里是base_link与base_laser之间的位置关系,表base_laser在base_link的x=0.1,y=0.0,z=0.2的位置,旋转方面quaternion置0,没有变化。


tf_listener.cpp:

#include<ros/ros.h>
#include<tf/transform_listener.h>
#include<geometry_msgs/PointStamped.h>
 
void transformPoint(const tf::TransformListener& listener){
        //这里先随意设置一个点,当做是laser坐标的点,然后我们将其转换成base_link坐标上的位置
        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{
                //创建一个点,用来存放当前base_laser的点在base_link坐标系中的位置
                geometry_msgs::PointStamped base_point;
                //下面这句话,它会自动为我们进行相应的转换,并将结果放入base_point,由于laser_point的frame_id为base_laser,这里我们先写将转换到的坐标系base_link.                
                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 node;
 
    tf::TransformListener listener(ros::Duration(10));
    //定时每隔1秒查询进行一次:
    ros::Timer timer = node.createTimer( ros::Duration(1.0), boost::bind( &transformPoint, boost::ref(listener) ) );
    ros::spin();
}

在CMakeLists文件中加入:

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
  actionlib_msgs 
  ##添加tf包
  tf                    
  actionlib
)
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})

依次运行,会发现出现结果:

[ INFO] [1472897890.623220105]: base_laser: (1.00, 0.20. 0.00) -----> base_link: (1.10, 0.20, 0.20) at time 1472897890.61
[ INFO] [1472897891.623229008]: base_laser: (1.00, 0.20. 0.00) -----> base_link: (1.10, 0.20, 0.20) at time 1472897891.61
[ INFO] [1472897892.624179159]: base_laser: (1.00, 0.20. 0.00) -----> base_link: (1.10, 0.20, 0.20) at time 1472897892.61
[ INFO] [1472897893.622589774]: base_laser: (1.00, 0.20. 0.00) -----> base_link: (1.10, 0.20, 0.20) at time 1472897893.61
[ INFO] [1472897894.624529454]: base_laser: (1.00, 0.20. 0.00) -----> base_link: (1.10, 0.20, 0.20) at time 1472897894.61

显示出了两坐标关系~~

--------------------- 
作者:sunfengcai 
来源:CSDN 
原文:https://blog.csdn.net/SUNFC_nbu/article/details/52424589 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ROS中,使用TF库来处理坐标系变换。首先,在你的ROS包中创建一个订阅器(Subscriber)来订阅TF话题,并在回调函数中将TF消息转换为Pose消息。 以下是一个示例代码: ```cpp #include <ros/ros.h> #include <tf/transform_listener.h> #include <geometry_msgs/PoseStamped.h> void tfCallback(const tf::tfMessage::ConstPtr& tfMsg) { // 创建一个TransformListener对象 tf::TransformListener listener; // 获取两个坐标系之间的变换 tf::StampedTransform transform; try{ listener.lookupTransform("map", "base_link", ros::Time(0), transform); } catch (tf::TransformException ex){ ROS_ERROR("%s",ex.what()); return; } // 将变换转换为Pose消息 geometry_msgs::PoseStamped poseMsg; poseMsg.header.stamp = ros::Time::now(); poseMsg.header.frame_id = "map"; poseMsg.pose.position.x = transform.getOrigin().x(); poseMsg.pose.position.y = transform.getOrigin().y(); poseMsg.pose.position.z = transform.getOrigin().z(); poseMsg.pose.orientation.x = transform.getRotation().x(); poseMsg.pose.orientation.y = transform.getRotation().y(); poseMsg.pose.orientation.z = transform.getRotation().z(); poseMsg.pose.orientation.w = transform.getRotation().w(); // 发布Pose消息 // ... } int main(int argc, char** argv) { ros::init(argc, argv, "tf_to_pose"); ros::NodeHandle nh; // 创建一个订阅器来订阅TF话题 ros::Subscriber sub = nh.subscribe("/tf", 10, tfCallback); // 创建一个发布器来发布Pose消息 // ... ros::spin(); return 0; } ``` 在回调函数中,我们首先创建了一个TransformListener对象,然后调用`lookupTransform()`方法获取两个坐标系之间的变换。注意,`lookupTransform()`方法的第一个参数是目标坐标系,第二个参数是源坐标系。在这个例子中,我们将获取从`base_link`坐标系到`map`坐标系的变换。 一旦我们获取了变换,我们就可以将其转换为Pose消息,并发布出去。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值