我在每个时间段都有陀螺仪+加速度计数据T
。
使用 C++,我想每次计算对象的旋转 - 它可以在其轴上旋转。我读过用四元数(不是欧拉角)来表示系统的旋转很方便。
如何从角速度(从陀螺仪)转换为四元数表示?我认为为了做到这一点,我需要使用数值方法求解微分方程。
我在每个时间段都有陀螺仪+加速度计数据T
。
使用 C++,我想每次计算对象的旋转 - 它可以在其轴上旋转。我读过用四元数(不是欧拉角)来表示系统的旋转很方便。
如何从角速度(从陀螺仪)转换为四元数表示?我认为为了做到这一点,我需要使用数值方法求解微分方程。
我不确定您正在寻找哪种语言,但 C++ Boost 库有一个有效的四元数类( quaternion.hpp )。我使用这个库创建了一个简单的旋转类,用于计算任意向量的结果或旋转点,难度很小。
更新:根据您的评论,我认为在给定角速度或角加速度的情况下,您不一定需要使用四元数库来计算您在给定时间的角位置。您需要做的就是弄清楚该角度是多少,然后使用四元数类来计算向量在围绕旋转向量旋转您计算的角度时的位置。
给定一个恒定的角加速度 α,初始角速度 ω(t 0 ) 和初始角位置 θ(t 0 ) 在 [0, 2π) 范围内的角位置在某个时间 t > t 0 , θ(t) 给定经过:
θ(t) = [θ(t 0 ) + ω(t 0 )*(tt 0 ) + α*(tt 0 ) 2 /2] mod 2π
这里的 mod 2π 运算只是减去 n2π 时的残差,其中 n 是确保残差在 [0, 2π) 范围内所需的整数。对于恒定的角速度(即α=0),最后一项退出。
也就是说,您真正需要做的就是在恒定加速度的某个时间间隔内跟踪角度(或者如果它不是恒定的,则确定该时间段内的平均加速度)并更新角度。然后,您将关于旋转矢量的结果旋转应用于您用来累积旋转的四元数。这可以很容易地实现为 C++ 类。
尽管如此,如果您正在寻找一个开源工具来执行此操作,我希望任何游戏物理建模库都绰绰有余。Bullet和Open Dynamics Library是几个开源的。
陀螺仪的每个样本都代表一个小旋转:
rot_x = angV_x * timestep
rot_y = angV_y * timestep
rot_z = angV_z * timestep
如果产生的旋转很小,您可以通过取一半的旋转角度将其直接转换为四元数:
// for small rotations, quick & dirty quaternion is sufficient
// (note: all angles *must* be in radians!)
float k = timestep * 0.5;
quaternion raw_delta_Q(1.0, angV_x*k, angV_y*k, angV_z*k); // unnormalized!
// combine rotation for current timestep with orientation state
estimated_orient_Q *= raw_delta_Q; // multiply by unnormalized delta
estimated_orient_Q *= 1 / norm(estimated_orient_Q); // then renormalize it!
如果您的旋转大于几度,或者如果您需要最大精度,则需要密切注意如何获得四元数。
编辑:请注意,上面的代码假设 *= 被定义为通过四元数和实标量进行四元数乘法。这些函数的某种形式(以及明显的构造函数)将出现在任何合理的四元数库中。
你会谈论Slerp吗?(球面线性插值)
请参阅 Jonathan Blow 的文章“了解 Slerp,然后不使用它”,其中包含 C++ 中的示例源...
http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/