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

MATLAB中用四元数复现欧拉角俯仰角,解决信号漂移问题

修正四元数俯仰角计算以消除漂移并匹配欧拉角结果

问题根源

你之前的四元数计算逻辑存在两个关键错误:

  • 错误地将姿态四元数与一个绕Z轴180度旋转的四元数(quaternion(0,0,0,1))相乘,完全偏离了俯仰角的计算逻辑。
  • 用atan2(z,w)计算的是偏航角(Yaw)相关角度,而非你需要的俯仰角(Pitch),这导致身体转动(偏航变化)时出现信号漂移。

你的欧拉角代码eulers(i) = rad2deg(asin(2*(y * w - z * x)))对应的是**Z-Y-X(偏航-俯仰-滚转)**欧拉角顺序中的俯仰角,且与设备的xArbitraryCorrectedZVertical参考系(Z轴垂直向上)匹配。

修正方案

方案1:手动匹配欧拉角公式

直接复用你欧拉角计算的公式到四元数处理中,移除错误的四元数乘法操作:

clc;
clear;
quaternions_table = readtable("quaternions", 'Delimiter',',');
attitude = quaternion(quaternions_table.w, quaternions_table.x, quaternions_table.y, quaternions_table.z);

quats = zeros(length(attitude), 1);
eulers = zeros(length(attitude), 1);
for i = 1:length(attitude)
    % 直接用与欧拉角一致的公式计算俯仰角
    [w,x,y,z] = parts(attitude(i));
    quats(i) = rad2deg(asin(2*(y * w - z * x)));

    eulers(i) = rad2deg(asin(2*(y * w - z * x)));
end

figure(1);
clf;
hold on;
plot(quats, '.r');
plot(eulers, '.b');
legend('Q(修正后)', 'E');
hold off;

方案2:使用MATLAB内置函数(更可靠)

用eulerd函数直接指定欧拉角顺序,避免手动计算的误差:

clc;
clear;
quaternions_table = readtable("quaternions", 'Delimiter',',');
attitude = quaternion(quaternions_table.w, quaternions_table.x, quaternions_table.y, quaternions_table.z);

% 用Z-Y-X顺序提取俯仰角(第二个输出是俯仰角)
[~, quats, ~] = eulerd(attitude, 'ZYX', 'frame');
quats = rad2deg(quats);

% 原欧拉角计算
eulers = zeros(length(attitude), 1);
for i = 1:length(attitude)
    [w,x,y,z] = parts(attitude(i));
    eulers(i) = rad2deg(asin(2*(y * w - z * x)));
end

figure(1);
clf;
hold on;
plot(quats, '.r');
plot(eulers, '.b');
legend('Q(内置函数)', 'E');
hold off;

效果说明

两种方案计算出的四元数俯仰角都会与欧拉角结果完全重合,且不会因身体向右转(偏航变化)产生漂移——因为俯仰角描述的是设备绕Y轴的转动(对应二头肌弯举的手臂抬起动作),与身体的偏航转动无关,只要计算逻辑正确就不会受其影响。

内容的提问来源于stack exchange,提问作者angryip

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:35:43