如何将四元数旋转转换至正确坐标系以准确测量旋转角度
测试场景
将IMU佩戴在手腕位置,按照下图所示姿势伸展手臂,保持手臂位置固定后原地旋转一周,过程中分别计算欧拉俯仰角与四元数角度。
测试中观测到:欧拉俯仰角基本保持恒定,偏差仅来自手部轻微抖动带来的小幅误差,但计算得到的四元数角度呈现近似线性增长的趋势,测试数据见文件sample_data.csv。

问题描述
需要对现有计算逻辑做哪些修改,才能通过四元数准确测量旋转角度?
目前推测需要采用RPR'形式将四元数调整对齐至世界坐标轴,但不确定变换项P的具体取值,现有Matlab实现代码如下:
clc; clear; table = readtable("sample_data.csv", 'Delimiter', ','); euler_angles = zeros(length(table.w),1); quaternion_angles = zeros(length(table.w),1); for idx = 1:length(table.w) w = table.w(idx); x = table.x(idx); y = table.y(idx); z = table.z(idx); euler_angles(idx) = getEulerAngle(w,x,y,z); quaternion_angles(idx) = getQuaternionAngle(w,x,y,z); end figure(1); clf; hold on; plot(euler_angles,'ro'); ylabel("Angle in deg"); xlabel("Sample"); plot(quaternion_angles, 'bo'); hold off; legend('Euler','Quaternion'); function angle = getQuaternionAngle(w,x,y,z) q = quaternion(w,x,y,z); angle = acosd(w); end function angle = getEulerAngle(w, x, y, z) mag = (2*(y * w - z * x)); angle = rad2deg(asin(mag)); end
问题原因
现有四元数角度计算逻辑存在本质错误:直接对四元数w分量取反余弦得到的是四元数表示的全旋转对应的半角余弦,这个角度是绕IMU瞬时旋转轴的旋转角度,并非绕固定竖直旋转轴的转角。当IMU旋转轴和自身局部坐标轴不重合时,直接取该值无法得到目标旋转角度。
修正方案
你推测的RPR'对齐思路是正确的,其中变换项P就是测试初始时刻IMU局部坐标系到世界坐标系的基准旋转变换,取初始帧采集到的四元数即可,具体修改步骤:
- 采集测试开始、姿态稳定时的第一帧IMU四元数作为基准四元数
q0,计算其共轭(即单位四元数的逆)q0_inv - 对后续每一帧采集的四元数
q_curr,计算相对于初始姿态的相对旋转:q_rel = q0_inv * q_curr - 从相对旋转四元数中,提取绕竖直世界轴(重力方向)的旋转分量,计算得到的角度就是目标旋转角度,不会再出现随旋转线性漂移的问题。
内容的提问来源于stack exchange,提问作者angryip
相关产品推荐
相关产品推荐

