Ros 通信之TF坐标变换

Ros 通信之TF坐标变换_第1张图片

1.定义:

TF功能包能够查询五秒前现在的坐标系相当于之前坐标系的所有节点的关系

机器人某一物体相当于机器人中心坐标系在哪里

机器人坐标系相对于全局坐标系的位置

2.实现TF坐标变换

A.广播TF变换 B.监听TF变换 创建树形结构 每一个节点获取所有的数据

3.TF坐标变换例程 小海龟坐标变换例程

sudo apt-get install ros-kinetic-turtle-tf
roslaunch turtle_tfturle_tf_demo.launch
rosrun turrlesim turtle_teleop_key     启动键盘控制海龟运动
rosrun tf view_frames

可以发现第二只海龟跟着第一只海龟不断运动去追寻我的第一个海龟

查看两个小海龟之间的关系

1号 和 2号 海龟的关系

tf tf_echo turtlel turtle2 

4.进入src 创建 TF 广播器 

广播器   TransformBroadcaster  接口

#include 
#include 
#include 

std::string turtle_name;

void poseCallback(const turtlesim::PoseConstPtr& msg)
{
    // tf广播器
    static tf::TransformBroadcaster br;

    // 根据乌龟当前的位姿,设置相对于世界坐标系的坐标变换
    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);

    // 发布坐标变换
    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];

    // 订阅乌龟的pose信息
    ros::NodeHandle node;
    ros::Subscriber sub = node.subscribe(turtle_name+"/pose", 10, &poseCallback);

    ros::spin();

    return 0;
};

5.进入src 创建 TF 监听器

#include 
#include 
#include 
#include 

int main(int argc, char** argv)
{
    // 初始化节点
    ros::init(argc, argv, "my_tf_listener");

    ros::NodeHandle node;

    // 通过服务调用,产生第二只乌龟turtle2
    ros::service::waitForService("spawn");
    ros::ServiceClient add_turtle =
    node.serviceClient("spawn");
    turtlesim::Spawn srv;
    add_turtle.call(srv);

    // 定义turtle2的速度控制发布器
    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
        {
            // 查找turtle2与turtle1的坐标变换
            listener.waitForTransform("/turtle2", "/turtle1", ros::Time(0), ros::Duration(3.0));
            listener.lookupTransform("/turtle2", "/turtle1", ros::Time(0), transform);
        }
        catch (tf::TransformException &ex) 
        {
            ROS_ERROR("%s",ex.what());
            ros::Duration(1.0).sleep();
            continue;
        }

        // 根据turtle1和turtle2之间的坐标变换,计算turtle2需要运动的线速度和角速度
        // 并发布速度控制指令,使turtle2向turtle1移动
        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;
};

6.添加cmakelist 资源更新

Ros 通信之TF坐标变换_第2张图片

7. 编写launch文件发布多个节点

 
    
    

    
    

    
    
    

    
    

 

你可能感兴趣的:(Ubantu20.04,+,ROS,理论篇,人工智能,迁移学习)