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

时间:2019-07-13 14:44:54

标签: unity3d quaternions imu

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

Qimu1 =位于下臂的imu的四元数

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

我在Unity中制作了两个对象,分别代表上臂和下臂。下臂是上臂的子对象,并通过角色关节连接到上臂。

这是上臂的脚本:

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;

我想获得的是使用2个IMU在Unity3D中进行手臂运动的可视化表示。现在,如果我保持肘部伸展,脚本将起作用。但是,一旦我开始弯曲肘部,下臂物体就开始围绕同一轴连续旋转。

1 个答案:

答案 0 :(得分: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;