如何在Unity中获得2个四元数的相对旋转

Posted

技术标签:

【中文标题】如何在Unity中获得2个四元数的相对旋转【英文标题】:How to get the relative rotation of 2 quaternions in Unity 【发布时间】:2019-11-23 00:00:39 【问题描述】:

我正在尝试分别使用两个 IMU 获得上臂和下臂之间的角度。我校准了 imu 并使用四元数来获得 Unity 3D 中上臂和下臂对象的全局方向。

Qimu1 = 来自下臂 imu 的四元数

Qimu2 = 来自上臂 imu 的四元数。

我在 Unity 中制作了两个对象,分别代表上臂和下臂。其中lowerarm 是upperarm 的子对象,使用Character 关节连接到upperarm。

这是上臂的脚本:

if (Input.GetKeyDown(KeyCode.Space))
        
            Qstart2 = Qimu2;
        

        transform.localRotation = Qstart2 * Quaternion.Inverse(Qimu2);

下臂脚本:

if (Input.GetKeyDown(KeyCode.Space))
        
            Qstart1 = Qimu1;
        

        Qimu1new = Qstart1 * Quaternion.Inverse(Qimu1);
        Quaternion Qdiff = Quaternion.Inverse(Qimu1new) * Qimu2;
        transform.localRotation = Qdiff;

我想获得的是 Unity3D 中使用 2 个 IMU 的手臂运动的视觉表示。现在,如果我保持肘部伸展,脚本就可以工作。但只要我开始弯曲肘部,下臂对象就会开始围绕同一轴连续旋转。

【问题讨论】:

你能解释更多关于Qstart1Qstart2的信息吗?它们是否被更改或设置在其他地方? Qstart 最初是空的,它是一种校准 IMU 的方法。当它从我按下空格时开始计算其相对方向时。因此它被设置一次。 试试transform.localRotation = Quaternion.Inverse(Qstart2 * Quaternion.Inverse(Qimu2)) * Qimu1new; 这是否达到了您的预期? 是的!它确实做到了!抱歉,我之前无法测试。但这正是我所需要的。谢谢!虽然不太明白为什么...... 【参考方案1】:

我们可以使用一些代数来计算下臂变换的相对旋转:

公式Qstartx * Quaternion.Inverse(Qimux) 为您提供了该部分相对于身体的旋转:

upper arm's rotation relative to body = Qstart2 * Quaternion.Inverse(Qimu2)
lower arm's rotation relative to body = Qstart1 * Quaternion.Inverse(Qimu1)

我们知道,因为下臂是上臂的子代:

lower arm's rotation relative to body 
    = upper arm's rotation relative to body * lowerArmTransform.relativeRotation

通过替换,我们可以确定:

Qstart1 * Quaternion.Inverse(Qimu1) 
    = (Qstart2 * Quaternion.Inverse(Qimu2)) * lowerArmTransform.relativeRotation

左边两边乘以Quaternion.Inverse(Qstart2 * Quaternion.Inverse(Qimu2))

Quaternion.Inverse(Qstart2 * Quaternion.Inverse(Qimu2)) * Qstart1 
* Quaternion.Inverse(Qimu1) 
    = Quaternion.Inverse(Qstart2 * Quaternion.Inverse(Qimu2)) 
      * ( Qstart2 * Quaternion.Inverse(Qimu2) )
      * lowerArmTransform.relativeRotation

Quaternion.Inverse(Qstart2 * Quaternion.Inverse(Qimu2)) * ( Qstart2 * Quaternion.Inverse(Qimu2) ) 取消:

Quaternion.Inverse(Qstart2 * Quaternion.Inverse(Qimu2)) * Qstart1 
* Quaternion.Inverse(Qimu1) 
    = lowerArmTransform.relativeRotation

由于Qimu1new = Qstart1 * Quaternion.Inverse(Qimu1);,我们可以得出结论:

lowerArmTransform.relativeRotation = Quaternion.Inverse(Qstart2 * Quaternion.Inverse(Qimu2)) * Qimu1new;

【讨论】:

以上是关于如何在Unity中获得2个四元数的相对旋转的主要内容,如果未能解决你的问题,请参考以下文章

使用四元数的Unity3D相对偏移对象旋转

四元数运动学笔记旋转的雅克比矩阵

unity--------------------四元数的旋转与原理

Unity编程Unity中关于四元数的API详解

unity----------------------四元数的概念

Unity四元数