You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将四元数旋转转换至正确坐标系以准确测量旋转角度

测试场景

将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 14:36:16