我在每个时间段T
都有陀螺仪+加速计数据。
使用C ++,我想计算每次对象的旋转 - 它可以在其轴上旋转。我已经读过,用四元数(不是欧拉角)表示系统的旋转是很方便的。
如何从角速度(从陀螺仪)转换为四元数表示?我认为为了做到这一点,我需要使用数值方法求解微分方程。
答案 0 :(得分:7)
我不确定您正在寻找哪种语言,但C ++ Boost库具有正常工作Quaternion class(quaternion.hpp)。我已经使用这个库来创建一个简单的旋转类来计算结果或旋转关于任意向量的点,而且难度很小。
更新:根据您的评论,我认为您不一定需要使用四元数库来确定给定时间的角位置,给定恒定角速度或角加速度。您需要做的就是弄清楚该角度是什么,然后使用四元数类来计算向量旋转时的旋转向量的位置。
给定恒定角加速度α,初始角速度ω(t 0 )和初始角位置θ(t 0 )在[0,2π]范围内在某个时刻t的角位置> t 0 ,θ(t)由下式给出:
θ(t) = [θ(t0) + ω(t0)*(t-t0) + α*(t-t0)2/2] mod 2π
这里,mod2π运算只是减去n2π时的残差,其中n是确保残差在[0,2π]范围内所需的整数。对于恒定的角速度(即α= 0),最后一项消失。
那就是说,你真正需要做的就是在恒定加速度下跟踪一段时间内的角度(或者如果它不是恒定的话,确定那段时间内的平均加速度)并更新角度。然后,将关于旋转矢量的结果旋转应用于用于累积旋转的四元数。这可以很容易地作为C ++类实现。
但是,如果你正在寻找一个开源工具来做到这一点,我希望任何游戏物理建模库都绰绰有余。一些开源的是Bullet和Open Dynamics Library。
答案 1 :(得分:3)
您是否会谈论 Slerp ? (球面线性插值)
请参阅Jonathan Blow的文章“ Understanding Slerp, Then Not Using It ”,其中包含C ++中的示例源代码......
http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/
答案 2 :(得分:2)
来自陀螺仪的每个样本代表一个小的旋转:
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!
如果您的旋转度大于几度,或者您需要最高精度,则需要密切关注如何获得四元数。
编辑:请注意,上面的代码假设* =被定义为由四元数和实数标量进行四元数乘法。某些形式的这些函数(以及明显的构造函数)将出现在任何合理的四元数库中。
答案 3 :(得分:1)