TF_多坐标系下的转换

需求

现有坐标系统,父级坐标系统 world,下有两子级系统 son1,son2,son1 相对于 world,以及 son2 相对于 world 的关系是已知的,求 son1原点在 son2中的坐标,又已知在 son1中一点的坐标,要求求出该点在 son2 中的坐标

学习案例

静态坐标系的相对坐标系的发布
静态坐标系下坐标点的转换

实现思路:

  • 利用小乌龟节点,产生两只小乌龟作为son1 和 son2 ,左下角原点为world,编写tf广播,发布两个坐标系的相对关系
  • 随便设置一个在son1 的坐标,订阅广播,处理坐标转换。

代码实现

小乌龟产生,结合前面内容

参考:动态坐标系相对关系的发布:

顶层launch文件

<launch>

<!-- 小乌龟启动节点 -->
<node pkg="turtlesim" type="turtlesim_node" name="turtle1" output="screen"/>
<!-- 添加第二个小乌龟 -->
<node pkg="comunication_learn" type="turtlesim_create.py" name="turtle2" args= "turtle2 2 3 4 1.57"      output="screen"/>

<!-- 发布两个坐标系与世界坐标系的广播信息  -->
<node pkg="tf_learn" type="pub_tf_dynamic_m.py" name="son1" args= "/turtle1/pose world son1"      output="screen"/>
<node pkg="tf_learn" type="pub_tf_dynamic_m.py" name="son2" args= "/turtle2/pose world son2"      output="screen"/>

<node pkg="tf_learn" type="sub_tf_dynamic_m.py" name="listener_tf" args= "son2 son1"      output="screen"/>

</launch>

sub_tf_dynamic_m.py是接受相对坐标位置关系,并处理数据的文件。

#! usr/bin/env python

import rospy
import tf2_ros
import sys
from tf2_geometry_msgs import PointStamped
'''
需求:通过缓存获取坐标系之间的相对关系,然后进行数据处理
步骤:
    1.导包
    2.初始化ros节点
    3.创建缓存
    4.创建监听对象
    5.获取坐标系之间的相对关系  

'''
parent_link = sys.argv[1]
child_link = sys.argv[2]

if __name__ == "__main__":

    rospy.init_node("dynamic_tf_listener")
    rospy.loginfo("开始获取坐标系之间的相对关系")

    #创建缓存
    buffer = tf2_ros.Buffer()
    #等待缓存来临
    rospy.sleep(1)
    #创造监听对象
    listener = tf2_ros.TransformListener(buffer)

    rate = rospy.Rate(1)

    while not rospy.is_shutdown():
        try:
            #获取坐标系之间的相对关系
            trans = buffer.lookup_transform(parent_link, child_link, rospy.Time())
            rospy.loginfo("获取成功")
            rospy.loginfo("位置:%s"%trans.transform.translation)
            rospy.loginfo("四元数:%s"%trans.transform.rotation)

             # 5.创建一依赖于 son1 的坐标点,调用 API 求出该点在 son2 中的坐标
            point_source = PointStamped()
            point_source.header.frame_id = "son1"
            point_source.header.stamp = rospy.Time.now()
            point_source.point.x = 1
            point_source.point.y = 1
            point_source.point.z = 1

            point_target = buffer.transform(point_source, "son2",rospy.Duration(0.5))
            rospy.loginfo("point_target 所属的坐标系:%s",point_target.header.frame_id)
            rospy.loginfo("坐标点相对于 son2 的坐标:(%.2f,%.2f,%.2f)",
                        point_target.point.x,
                        point_target.point.y,
                        point_target.point.z
            )



        except Exception as e:
            rospy.logerr("错误提示:%s",e)
    rate.sleep()
        

    


在这里插入图片描述

总结

关键API

订阅者话题:rospy.Subscrible()
参数:订阅的话题名称、话题数据类型、回调函数、队列长度
在这里插入图片描述

程序挂起:rospy.spin()
保持主进程,等待调用回调函数

TF广播实例化:tf2_ros.TransformBroadcaster()
广播两个坐标系的相对位置关系
发送广播:tf2_ros.TransformBroadcaster.sendTransform(transform_msg)

TF接收
创建缓存区对象:buffer = tf2_ros.Buffer()
将TF消息放入缓存区内:tf2_ros.TransformLister(buffer)
延迟等待 数据进入缓冲区:rospy.sleep(1)

TF相对坐标系信息的处理:
获取坐标的相对关系(从缓冲区中,任意取坐标系即可):trans = buffer.lookup_transform(parent_link,child_link,rospy.Time())
相对坐标系位置关系查看:trans.transform.translation
相对坐标系的四元数位置查看:trans.transform.roration

TF的坐标点的坐标转换:
坐标点的转换:buffer.transform(point,link,rospy.Duration(0.5))
(point消息内含有坐标系关系,所以可以之间转移到link坐标系中)

遇到困难

  • 使用launch文件集成使用时,发现运行一次可以ctrl+c终止终端运行,但第二次运行后,无法终止。
  • 思考将各个部分模块化:即传入话题名称、父坐标系、子坐标系后可以广播TF,使用命令行使,出现节点重名问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值