INS/GNSS组合导航(十二)四元数的几点说明

本文详细介绍了四元数在三维旋转表示中的应用,包括其与旋转矩阵、欧拉角的转换关系,特别区分了右手系和左手系的定义,并提供了C++和Python代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.概述

四元数的相关内容已经非常详尽,本文不再详细说明,重点是介绍四元数与旋转矩阵的转换关系。

简单来说,Quaternion(四元数)是一种常用的三维空间旋转的表示法。四元数由一个实部和三个虚部构成,写作如下形式:

                                                \mathbf{q}=q_1 i + q_2 j + q_3 k+q_0 

也有写成如下:

                                                \mathbf{q}=q_1 i + q_2 j + q_3 k +q_4

或者按照旋转矩阵定义,

                                                \mathbf{q}=q_w + q_x i + q_y j + q_z k

其中i, j, k为三个基向量,满足一定的计算规则,类似复数中虚部。

具体来说,最早是有Hamilton于1843提出并定义了相关的计算法则。

计算法则符合右手系,定义如下:

                                                        i^2=j^2=k^2=ijk=-1 \\ i\times j =k \\ j \times k=i \\ k \times i=j

但是除此之外,还有按照左手系定义的JPL四元数,可参考Indirect Kalman Filter for 3D Attitude Estimation

两种定义形式的对比如下,具体信息可重点参考一篇对比四元数的经典文献

Quaternion kinematics for the error-state KF

详细内容可参考以下几篇博客:

四元数旋转表达(Hamilton notation & JPL notation)

 右手系转左手系、旋转矩阵转四元数、四元数的两种表达(Hamilton/JPL)

从四元数到旋转矩阵_四元数转换为旋转矩阵-优快云博客

两种定义形式导致很容易混乱,本人推荐车载领域常用的右手系定义方式。具体可参考这篇文档:

四元数的两种 notation:Hamilton 和 JPL

PSHamilton四元数通常表达的是局部系local frame 比如载体系b系,到全局系global frame比如参考坐标系 n系的旋转,JPL四元数表达的是global 到local的旋转。两种情况下的旋转矩阵互为转置矩阵。

特别注意① 对于不同文献的引用与转载,经常出现一篇文献中Hamilton 与JPL两种

                        形式混用, 这是一种误读,说明使用者没有注意到两者的区别和来历.

                  对于四元数的书写形式,通常有如下三种写法:

                                \mathbf q=\begin{bmatrix} q_0 \\ q_1 \\ q_2 \\ q_3 \end{bmatrix} \quad \quad \quad \quad \quad \quad \quad \quad\quad\quad\quad(1)

                                \mathbf q=\begin{bmatrix} q_1 \\ q_2 \\ q_3 \\ q_4 \end{bmatrix}\quad \quad \quad \quad \quad \quad \quad \quad\quad\quad\quad(2)

   &nbs

### 将 INS 点云数据转换为 ECEF 坐标系的方法 要将点云数据从 INS 坐标系转换到地球中心地球固定 (ECEF) 坐标系,需要考虑以下几个关键因素: #### 1. 外参数校正 在外参标定过程中,描述扫描仪坐标系与惯导坐标系之间的位置关系非常重要。这包括三个安置角和三个安置距离分量[^3]。这些外参用于补偿安装误差,特别是在安置角上的偏差会对最终点云精度产生显著影响。 因此,在进行坐标变换之前,必须先对外部参数进行精确标定并应用修正矩阵 \( T_{\text{scanner-to-INS}} \),该矩阵可以表示为: ```python import numpy as np def get_transformation_matrix(angles, distances): """ 构建从扫描仪到INS坐标的转换矩阵。 参数: angles: 安置角度 [roll, pitch, yaw] distances: 安置距离 [dx, dy, dz] 返回: transformation_matrix: 4x4 变换矩阵 """ roll, pitch, yaw = angles dx, dy, dz = distances R_x = np.array([[1, 0, 0], [0, np.cos(roll), -np.sin(roll)], [0, np.sin(roll), np.cos(roll)]]) R_y = np.array([[np.cos(pitch), 0, np.sin(pitch)], [0, 1, 0], [-np.sin(pitch), 0, np.cos(pitch)]]) R_z = np.array([[np.cos(yaw), -np.sin(yaw), 0], [np.sin(yaw), np.cos(yaw), 0], [0, 0, 1]]) rotation_matrix = R_z @ R_y @ R_x translation_vector = np.array([dx, dy, dz]).reshape((3, 1)) transformation_matrix = np.eye(4) transformation_matrix[:3, :3] = rotation_matrix transformation_matrix[:3, 3:] = translation_vector return transformation_matrix ``` 通过上述方法构建的外部参数矩阵 \( T_{\text{scanner-to-INS}} \) 应用于原始点云数据以消除安装误差。 --- #### 2. INS 数据的时间同步与姿态解算 在 GNSS/INS 集成系统中,通常会利用扩展卡尔曼滤波器 (EKF) 来估计载体的姿态、速度和位置信息[^1]。具体来说,INS 提供的姿态信息(四元数或旋转矩阵形式)以及位置信息是后续坐标转换的基础。 假设已知某时刻 \( t_k \)INS 输出: - **位置**: \( P_{\text{INS},k}^{ECEF} = [X,Y,Z]^T \) 表示当前车辆在 ECEF 下的位置; - **姿态**: \( Q_{\text{INS},k} \) 或者对应的旋转矩阵 \( R_{\text{INS},k} \) 描述了 INS 当前相对于 ECEF 的方向; 则可以通过以下方式完成点云数据的转换。 --- #### 3. 点云数据的转换过程 给定点云中的某个点 \( p_i^{\text{INS}} \in \mathbb{R}^3 \)INS 局部坐标系下的表达式,其对应于 ECEF 坐标系下点 \( p_i^{\text{ECEF}} \) 的计算如下所示: \[ p_i^{\text{ECEF}} = P_{\text{INS},k}^{ECEF} + R_{\text{INS},k} \cdot T_{\text{scanner-to-INS}} \cdot p_i^{\text{INS}} \] 其中, - \( P_{\text{INS},k}^{ECEF} \): INS 记录的当前位置向量; - \( R_{\text{INS},k} \): INS 态度旋转矩阵; - \( T_{\text{scanner-to-INS}} \): 扫描仪至 INS 的外部参数矩阵。 以下是 Python 实现的一个简单例子: ```python def transform_point_cloud_to_ecef(point_cloud_ins, ins_position_ecef, ins_rotation_matrix, scanner_to_ins_transform): """ 将点云从 INS 坐标系转换到 ECEF 坐标系。 参数: point_cloud_ins: N x 3 数组,表示点云在 INS 坐标系下的坐标 ins_position_ecef: 3 x 1 向量,表示 INS 设备在 ECEF 中的位置 ins_rotation_matrix: 3 x 3 旋转矩阵,表示 INS 到 ECEF 的旋转 scanner_to_ins_transform: 4 x 4 转换矩阵,表示扫描仪到 INS变换 返回: point_cloud_ecef: N x 3 数组,表示点云在 ECEF 坐标系下的坐标 """ homogenous_points = np.hstack((point_cloud_ins, np.ones((len(point_cloud_ins), 1)))) transformed_points = homogenous_points @ scanner_to_ins_transform.T[:, :3].T rotated_points = transformed_points @ ins_rotation_matrix.T point_cloud_ecef = rotated_points + ins_position_ecef.reshape(1, 3) return point_cloud_ecef ``` 此函数接受输入点云及其相关参数,并返回经过转换后的 ECEF 坐标系下的点云。 --- #### 工具支持 如果希望简化开发流程,可借助一些成熟的工具包来进行处理。例如 PSINS 工具箱提供了完整的捷联惯导系统数据处理功能,涵盖了惯性传感器数据分析、初始对准、AVP 更新解算等内容[^4]。此外,还可以结合 ROS 和 OpenCV 这样的框架进一步优化实现效率。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scott198512

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值