从陀螺仪计算四元数加速度计数据

发布于 2024-09-25 04:23:11 字数 164 浏览 6 评论 0原文

我有每个时间段T的陀螺仪+加速度计数据。

使用 C++,我想计算对象每次的旋转 - 它可以绕其轴旋转。我读到用四元数(而不是欧拉角)来表示系统的旋转很方便。

如何从角速度(来自陀螺仪)转换为四元数表示?我认为为了做到这一点,我需要使用数值方法求解微分方程。

I have gyroscope + accelerometer data at each time period T.

Using C++, I want to calculate the rotation of the object at each time - it can rotate on its axes. I've read that it is convenient to represent the rotation of the system in terms of quaternions (not in Euler angles).

How can I transform from angular velocity (from gyroscope) to the quaternions representation? I think in order to do it I need to solve the differential equation using numerical methods.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

那请放手 2024-10-02 04:23:11

我不确定您要寻找哪种语言,但 C++ Boost 库有一个有效的 四元数类 (四元数.hpp)。我使用这个库创建了一个简单的旋转类,用于计算结果或围绕任意向量旋转点,几乎没有困难。

更新:根据您的评论,我认为在给定恒定角速度或角加速度的情况下,您不一定需要使用四元数库来计算给定时间的角位置。您需要做的就是找出该角度是什么,然后使用四元数类来计算矢量围绕旋转矢量旋转您计算出的角度时的位置。

给定恒定角加速度 α、初始角速度 ω(t0) 和初始角位置 θ(t0),范围 [0, 2π) 内的角位置在某个时间t> t0, θ(t) 由下式给出:

θ(t) = [θ(t0) + ω(t0)*(t-t0) + α*(t-t0)2/2] mod 2π

这里 mod 2π 运算只是减去 n2π 时的残差,其中 n 是确保残差在 [0, 2π) 范围内所需的整数。对于恒定角速度(即 α=0),最后一项就消失了。

也就是说,您真正需要做的就是在恒定加速度下跟踪一段时间间隔内的角度(如果不恒定,则确定该时间段内的平均加速度)并更新角度。然后,将围绕旋转向量产生的旋转应用到用于累积旋转的四元数。这可以很容易地实现为 C++ 类。

不过,如果您正在寻找一个开源工具来执行此操作,我希望任何游戏物理建模库都足够了。一些开源的有 Bullet打开动态库

I'm not sure which language you're looking for, but the C++ Boost library has a working Quaternion class (quaternion.hpp). I've used this library to create a simple rotation class for computing the results or rotating points about arbitrary vectors with very little difficulty.

UPDATE: Based on your comment, I don't think you necessarily need to use a quaternion library to figure out your angular position at a given time, given either a constant angular velocity or angular acceleration. All you need to do is to figure out what that angle is, and then use the quaternion class to compute the position of vectors when rotated about your rotation vector by the angle you've computed.

Given a constant angular acceleration α, an initial angular velocity ω(t0) and initial angular position θ(t0) in the range [0, 2π) the angular position at some time t > t0, θ(t) is given by:

θ(t) = [θ(t0) + ω(t0)*(t-t0) + α*(t-t0)2/2] mod 2π

Here the mod 2π operation is simply the residual when subtracting n2π where n is the integer required to ensure the residual is in the range [0, 2π). For a constant angular velocity (i.e. α=0) the last term drops out.

That said, all you really need to do is to keep track of the angle over some interval of time under constant acceleration (or determine the average acceleration over that time if it's not constant) and update the angle. You then apply the resulting rotation about your rotation vector to the quaternion you're using to accumulate your rotations. This can be easily implemented as a C++ class.

Still, if you're looking for an open source tool to do this, I expect that any of the game physics modeling libraries will be more than adequate. A couple of open source ones are Bullet and the Open Dynamics Library.

原来是傀儡 2024-10-02 04:23:11

您会谈论Slerp吗? (球面线性插值)

请参阅 Jonathan Blow 的文章“了解 Slerp,然后不使用它”,其中有 C++ 示例源代码...

http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/

Would you be talking about a Slerp? (Spherical Linear Interpolation)

See Jonathan Blow's article "Understanding Slerp, Then Not Using It" which has example source in C++...

http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/

趁年轻赶紧闹 2024-10-02 04:23:11

陀螺仪的每个样本都代表一个小的旋转:

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!

如果您的旋转大于几度,或者如果您需要最大的精度,您可以将其转换为四元 数。将需要更加密切地关注如何获得四元数。

编辑:请注意,上面的代码假设 *= 被定义为通过四元数和实标量进行四元数乘法。这些函数的某种形式(以及明显的构造函数)将出现在任何合理的四元数库中。

Each sample from your gyroscopes represents a small rotation:

rot_x = angV_x * timestep
rot_y = angV_y * timestep
rot_z = angV_z * timestep

If the resulting rotations are small, you can convert this directly into a quaternion by taking half the rotation angle:

// 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!

If your rotations are larger than a few degrees, or if you need maximum accuracy, you will need to pay closer attention to how you get your quaternion.

EDIT: Note that the above code assumes *= is defined to do quaternion multiplication by both quaternions and real scalars. Some form of these functions (as well as the obvious constructor) will be present in any reasonable quaternion library.

荭秂 2024-10-02 04:23:11

什么语言?例如,对于 Python cgkit 有一个漂亮的 quat 模块(四元数初始化来自旋转矩阵,而不是“角速度”,但大概您可以从后者构建前者?)和 euclid.py 具有四元数类的 Python 源代码,包括从旋转矩阵和其他方式构建它的类方法。

What language? E.g. for Python cgkit has a nifty quat module (quaternions initialized from a rotation matrix, not "an angular velocity", but presumably you can build the former from the latter?) and euclid.py has Python source code for a Quaternion class including class methods to build it from rotation matrix and in other ways.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文