多坐标系变换

功能包:
tf2、tf2_ros、tf2_geometry_msgs、roscpp rospy std_msgs geometry_msgs、turtlesim

1. 发布方:

为了方便,使用静态坐标变换发布:

<launch>
    <!-- 发布 son1 相当于 world 以及 son2 相当于 world 的坐标关系 -->
    <node pkg = "tf2_ros" type = "static_transform_publisher" name = "son1" args = "5 0 0 0 0 0 /world /son1" output = "screen" />
    <node pkg = "tf2_ros" type = "static_transform_publisher" name = "son2" args = "3 0 0 0 0 0 /world /son2" output = "screen" />

</launch>

在这里插入图片描述

2. C++ 实现:

#include "ros/ros.h"
#include "tf2_ros/transform_listener.h"
#include "tf2_ros/buffer.h"
#include "geometry_msgs/PointStamped.h"
#include "tf2_geometry_msgs/tf2_geometry_msgs.h"
#include "geometry_msgs/TransformStamped.h"
/*
    订阅方实现:1.计算 son1  son2 的相对关系 2.son1 中的某个坐标点在 son2 中的坐标值

    流程:
        1.包含头文件
        2.编码、初始化、NodeHandle 创建
        3.创建订阅对象
        4.编写解析逻辑
        5.spinOnce()
*/

int main(int argc, char *argv[])
{
    // 2.编码、初始化、NodeHandle 创建
    setlocale(LC_ALL,"");
    ros::init(argc,argv,"tfs_sub");
    ros::NodeHandle nh;
    // 3.创建订阅对象
    tf2_ros::Buffer buffer;
    tf2_ros::TransformListener sub(buffer);
    // 4.编写解析逻辑

    //创建坐标点
    geometry_msgs::PointStamped psAtSon1;
    psAtSon1.header.stamp = ros::Time::now();
    psAtSon1.header.frame_id = "son1";
    psAtSon1.point.x = 1.0 ;
    psAtSon1.point.y = 2.0 ;
    psAtSon1.point.z = 3.0 ;

    ros::Rate rate(10);
    while (ros::ok())
    {
        //核心
        try{
            //1.计算 son1  son2 的相对关系
            /*
                参数1:目标坐标系   B
                参数2:源坐标系     A
                参数3:ros::Time(0) 取间隔最短的两个坐标关系帧计算相对关系
                返回值:geometry_msgs::TransformStamped 源相对于目标坐标系的相对关系
            */
            geometry_msgs::TransformStamped son1ToSon2 = buffer.lookupTransform("son2","son1",ros::Time(0));
            ROS_INFO("son1 相对于 son2 的信息:父级:%s, 子级:%s, 偏移量(%.2f,%.2f,%.2f)" ,
                    son1ToSon2.header.frame_id.c_str(),  //son2
                    son1ToSon2.child_frame_id.c_str() ,  //son1
                    son1ToSon2.transform.translation.x,
                    son1ToSon2.transform.translation.y,
                    son1ToSon2.transform.translation.z);
            //2.计算 son1 中的某个坐标点在 son2 中的坐标值
            geometry_msgs::PointStamped psAtSon2 = buffer.transform(psAtSon1,"son2");
            ROS_INFO("坐标点在 Son2 中的值(%.2f,%.2f,%.2f)",
                    psAtSon2.point.x,
                    psAtSon2.point.y,
                    psAtSon2.point.z
                    );
        }
        catch(const std::exception& e)
        {
            ROS_INFO("错误提示:%s",e.what());
        }
    // 5.spinOnce()
    ros::spinOnce();
    }
    return 0;
}

输出:
在这里插入图片描述

3. python实现:

#! /usr/bin/env python
from email import header
import rospy
import tf2_ros
from tf2_geometry_msgs import tf2_geometry_msgs
from geometry_msgs.msg import TransformStamped

if __name__ == "__main__":
    # 2.初始化节点
    rospy.init_node("static_sub_p")
    # 3.创建订阅对象
    # 3-1.创建缓存对象
    buffer = tf2_ros.Buffer()
    # 3-2.创建订阅对象的坐标点
    sub = tf2_ros.TransformListener(buffer)
    # 4.组织被转换的坐标点
    ps = tf2_geometry_msgs.PointStamped()
    # 时间戳 -- 0
    # ps.header.stamp =rospy.Time()
    ps.header.stamp = rospy.Time.now()
    # 坐标系
    ps.header.frame_id = "son1"
    ps.point.x = 1.0
    ps.point.y = 2.0
    ps.point.z = 3.0
    # 5.转换逻辑实现,调用tf封装的算法
    rate = rospy.Rate(10)
    while not rospy.is_shutdown():
        try:
            #----------计算 son1 相对于 son2 的坐标关系
            """
                参数1: 目标坐标系
                参数2: 源坐标系
                参数3: rospy.Time(0) ------- 取时间间隔最近的两个坐标系帧(son1 相对 world  son2 相当于 world )计算结果
                返回值: son1  son2 的坐标系关系
            """
            ts = buffer.lookup_transform("son2","son1",rospy.Time(0))
            rospy.loginfo("父级坐标系:%s,子级坐标系:%s,偏移量(%.2f,%.2f,%.2f)",
                    ts.header.frame_id,
                    ts.child_frame_id,
                    ts.transform.translation.x,
                    ts.transform.translation.y,
                    ts.transform.translation.z,
                    )
            # 转换实现
            ps_out = buffer.transform(ps,"son2")
            # 6.输出结果
            rospy.loginfo("转换后的坐标:(%.2f,%.2f,%.2f),参考的坐标系:%s",
                            ps_out.point.x,
                            ps_out.point.y,
                            ps_out.point.z,
                            ps_out.header.frame_id
                            )
        except Exception as e:
            rospy.logwarn("错误提示:%s",e)
        rate.sleep()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值