如何实现两个固定坐标系之间的变换?

摘要

本博客提供了在ROS中快速实现固定(静态)坐标系变换的标准模板和应用实例,便于后续查阅。

关键词

ROS, TF, 固定(静态)坐标系变换

前言

在许多机器人或控制相关领域,主要依赖的坐标系可能并不是东北天坐标系,比如在海洋工程领域或制导定位领域,东北地坐标系在很多时候反而更加常用。还有很多情况下,机器人的活动范围会被局限在一定区域内,描述机器人在这个区域中的运动时,如果使用的是全局地图下的坐标系,不如在这个局部区域中选取一个固定位置作为参考坐标系来的方便,然而选取新的位置作为坐标系涉及到坐标系的平移和旋转,因此如果要在ROS中快速实现固定坐标系变换(又称静态坐标系变换),有必要学习ROS中提供的对应封装函数,本博客提供了在ROS中快速实现固定坐标系变换的标准模板和应用实例,便于后续查阅。

方法

基本模板

# Neccessary library
import rospy
import tf
import tf2_ros
import geometry_msgs.msg

# ...

#static initial frame transform: parent_frame->child_frame
static_transformStamped = geometry_msgs.msg.TransformStamped()
broadcaster = tf2_ros.StaticTransformBroadcaster()

static_transformStamped.header.stamp = rospy.Time.now()
static_transformStamped.header.frame_id = "parent_frame"
static_transformStamped.child_frame_id = "child_frame"

static_transformStamped.transform.translation.x = 0.0
static_transformStamped.transform.translation.y = 0.0
static_transformStamped.transform.translation.z = 0.0

quat = tf.transformations.quaternion_from_euler(np.pi, 0, np.pi/2) #roll, pitch, yaw
static_transformStamped.transform.rotation.x = quat[0]
static_transformStamped.transform.rotation.y = quat[1]
static_transformStamped.transform.rotation.z = quat[2]
static_transformStamped.transform.rotation.w = quat[3]

broadcaster.sendTransform(static_transformStamped)

# ...

注意事项

Q:最初始的坐标系是什么坐标系?

Rviz中默认的最初始坐标系名称是map,可以在Rviz侧边栏Global Options中的Fix Frame栏看到。该名称可以被用户在此栏任意修改。

Q:坐标系旋转顺序?

不同的旋转顺序会导致不同的旋转结果。ROS中的标准旋转顺序是:
父系x正轴->父系y正轴->父系z正轴
出处见下图:(来源链接:http://wiki.ros.org/tf2/Tutorials/Quaternions
ROS官方文档中对旋转顺序的定义

Q:四元数在ROS中的排布?

应用

目标

为初始全局坐标系取名为world,然后生成一个东北地坐标系,其x正轴朝北,y正轴朝东,z正轴朝地,坐标原点在world坐标系下位于(10,5,2),将该坐标系取名为NED。NED坐标系需要在Rviz中展现出来。

操作过程

  1. 在功能包中新建脚本,脚本路径为: catkin_ws/ros_basic/scripts/static_transformation.py
    具体过程略
  2. 编写脚本。脚本代码如下(代码已经过测试):
#!/usr/bin/env python3
# coding: utf-8

# Neccessary library
import rospy
import tf
import tf2_ros
import geometry_msgs.msg
import numpy as np

rospy.init_node("static_transformation")
static_transformStamped = geometry_msgs.msg.TransformStamped()

broadcaster = tf2_ros.StaticTransformBroadcaster()
static_transformStamped.header.stamp = rospy.Time.now()
static_transformStamped.header.frame_id = "world"
static_transformStamped.child_frame_id = "NED"

static_transformStamped.transform.translation.x = 10.0
static_transformStamped.transform.translation.y = 5.0
static_transformStamped.transform.translation.z = 2.0

quat = tf.transformations.quaternion_from_euler(np.pi, 0, np.pi/2)
static_transformStamped.transform.rotation.x = quat[0]
static_transformStamped.transform.rotation.y = quat[1]
static_transformStamped.transform.rotation.z = quat[2]
static_transformStamped.transform.rotation.w = quat[3]

broadcaster.sendTransform(static_transformStamped)
while not rospy.is_shutdown():
    pass
  1. 为脚本赋予可执行文件权限。
    具体过程略
  2. 启动roscore,source python文件,rosrun python文件。
    具体过程略
  3. 在Rviz中add tf,展示对应坐标系情况
    具体过程略,注意要在Rviz里,Global Options中,Fixed Frame的名字改成"world"

结果

Rviz中x,y,z轴分别用红、绿、蓝三种颜色的轴表示。Rviz中展示结果如下:

俯视图:
在Rviz中add tf,展示对应坐标系情况俯视图
后视图:
在Rviz中add tf,展示对应坐标系情况后视图

延伸阅读

如何查看/获取固定坐标系之间变换以后的变换矩阵?
如何实现动态坐标系变换?
ROS中如何实现将一个基于A坐标系下的三维向量变换到基于B坐标系下?
如何保存Rviz展示模板?
“#!/usr/bin/env python3” 的作用是什么?
如何展示当前所有坐标系之间的联结关系?

参考文献

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值