• 第八课 ROS的空间描述和变换


    1、tf的实际应用

    1)在机器人的配置中

    从上面可以看出激光雷达中心距离机器人底座的中心有20cm,激光雷达的中心距机器人底座中心有10cm,如果激光雷达在障碍物前面0.3米,那么机器人底座离障碍物多远呢?

    1、新建一个包,如下

    catkin_create_pkg robot_setup_tf roscpp tf geometry_msgs

    2、catkin_make一下

    3、新建两个源文件tf_publisher.cpp,tf_listener.cpp

    下面按照base_link和base_laser的位置来编写publisher

    #include<ros/ros.h>

    #include<tf/transform_broadcaster.h>

    int main(int argc,char **argv)

    {

      ros::init(argc,argv,"tf_publisher");

      ros::NodeHandle n;

      //发布频率

      ros::Rate r(100);

      //创建一个transform_broadcaster

      tf::TransformBroadcaster broadcaster;

      //创建一个transform对象

      tf::Transform transform;

      //下面设置其位置以及旋转信息

      transform.setOrigin(tf::Vector3(0.1,0.0,0.2));

      //再创建一个四元组

      tf::Quaternion q;

      q.setRPY(0.0,0.0,0.0);//没有旋转

      transform.setRotation(q);//以上已经把位置描述设定好了

      while(ros::ok())

      {

        broadcaster.sendTransform(tf::StampedTransform(transform,ros::Time::now(),"base_link","base_laser"));//父框架叫base_link,子框架叫base_laser

        r.sleep();

      }

      return 0;

    }

    下面再tf_listener.cpp当中来编写

    在其中使用了一个新的类型叫做geometry_msgs/PointStamped

    在命令行当中查看该类型rosmsg show geometry_msgs/PointStamped

    #include<ros/ros.h>

    #include<geometry_msgs/PointStamped.h>

    #include<tf/transform_listener.h>

    void transformPoint(const tf::TransformListener &listener)

    {

      //实例化一个消息

      geometry_msgs::PointStamped laser_point;

      //指定header的frame_id,表示最新的可用的变换

      laser_point.header.framer_id="base_laser";

      laser_point.header.stamp = ros::Time();

      laser_point.point.x= rand()%5;;//赋予一个随机值

      laser_point.point.y= rand()%5;;//赋予一个随机值

      laser_point.point.z= rand()%5;;//赋予一个随机值

      try

      {

        geometry_msgs::PointStamped base_point;//实例化一个geometry_msgs::PointStamped类,表示机器人底座

        //调用transformlistener的transformpoint函数

        listener.transformPoint("base_link",laser_point,base_point);//参数目标框架target_frame,stamped_in以及stamped_out。

        //输出相关信息

        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,"tf_listener");

      ros::NodeHandle n;

      //定义一个transformlistener对象

      tf::TransformListener listener(ros::Duration(10))//等待10s,如果10s之后都还没收到消息,那么之前的消息就被丢弃掉。

      //创建一个timer对象,绑定了一个transformpoint的地址,后面是该函数transformpoint的参数

      ros::Timer timer=n.createrTimer(ros::Duration(1.0),boost::bind(&transformPoint,boost::ref(listener)));

      //在上面去实现transformPoint这个函数

     ros::spin();

    }

    对上面代码总结一下:

    在main函数实例化一个listener对象,然后创建一个定时器1s钟调用上面函数一次,......。

    下面把CMakeLists.txt修改一下

    add_executable(tf_listener src/tf_listener.cpp);

    add_executable(tf_publisher src/tf_publisher.cpp);

    target_link_libraries(tf_listener ${catkin_LIBRARIES})

    target_link_libraries(tf_publisher ${catkin_LIBRARIES})

    再写一个launch文件:

    <launch>

    //再添加一个frame称为camera把它固定在base_link上,用static_transform_publisher来指定base_link(父框架)和camera(子框架)的关系,

    //位置信息0.1 0.0 0.2,方向信息为0 0 0 1

    <node pkg="tf" type="static_transform_publisher" name="broadcaster" args="0.1 0.0 0.2 0 0 0 1 base_link camera 100">

    //我们要启动的node

    <node pkg="robot_setup_tf" type="tf_publisher" name="publisher"/>

    <node pkg="robot_setup_tf" type="tf_listener" name="listener"/>

    </launch>

    下面去编译

    catkin_make

    运行之

    roscore

    rosrun robot_setup_tf tf_listener

    rosrun robot_setup_tf tf_publisher

    然后进入rviz中去观察。

    然后再看看launch文件

    roslaunch robot_setup_tf demo.launch,在launch文件中我们又指定了一个坐标系框架叫做camera

    下面去看一下

    rosrun tf view_frames,生成一个PDF文件,可以看到

  • 相关阅读:
    通过反射操作泛型
    Android学习笔记_4_单元测试
    Android学习笔记_3_四种布局
    Validform 基于表单验证
    Android学习笔记_2_发送短信
    Android学习笔记_1_拨打电话
    css ul dl dt 表格分页 文本框样式
    创建properties文件保存在WEB项目的classes文件下
    PS快捷键和常用小知识
    Mysql跨数据库(在同一IP地址中)复制表
  • 原文地址:https://www.cnblogs.com/gary-guo/p/6746102.html
Copyright © 2020-2023  润新知