我在Unity3D中创建了两个对象,分别代表一个上臂(父级)和一个下臂(子级),并通过字符关节进行连接。这些对象的旋转由2个四元数驱动,我从位于上臂和下臂的IMU收集它们。我校准两个四元数。我的目标是可视化肘部弯曲/伸展。
名称中的Q表示它是四元数。 QImu表示它是来自IMU的四元数。 Qstart表示它是IMU的初始启动方向。
// upperarm script attached to upperarm object
if (Input.GetKeyDown(KeyCode.Space))
{
QstartUpperArm = QimuUpperArm;
}
transform.localRotation = QstartUpperArm * Quaternion.Inverse(QimuUpperArm);
// lowerarm script attached to lowerarm object
if (Input.GetKeyDown(KeyCode.Space))
{
QstartLowerArm = QimuLowerArm;
}
QimuLowerArm = QstartLowerArm * Quaternion.Inverse(QimuLowerArm);
transform.localrotation = Quaternion.Inverse(Qstart2 * Quaternion.Inverse(Qimu2)) * Qimu1new;
Upperarm对象正在完全按预期旋转。但是,下臂对象的y轴反转了一个。所有其他轴都可以。如何使用四元数更改一个轴的符号?
答案 0 :(得分:0)
您不应该直接在Quaternion
中执行此操作。听起来您似乎将Quaternion
(具有4个成分x,y,z,w
)与x,y,z
中的Euler空间表示相混淆。
您可以尝试使用类似的东西
var invertedRotation = Quaternion.Euler(Vector3.Scale(QimuLowerArm.eulerAngles, Vector3.up * -1));
取决于要反转的旋转角度(在代码中没有清楚看到这一点)。
eulerAngles
返回Quaternion
Vector3.Scale
乘以Vector3
的分量。在这种情况下,Vector3.up * -1 == new Vector3(0, -1, 0);
Quaternion.Euler
为给定的Euler角旋转生成Quaternion
。这里必须要注意的是,旋转顺序依次为x
然后z
然后y
,但是由于您要反转后者,所以应该没问题。
另一种afaik(不太确定)是
w
组件我仍然不会直接在四元数中这样做,因为顺序很重要,但是确实如此。
var invertedRotation = new Quaternion (QimuLowerArm.x, - QimuLowerArm.y, QimuLowerArm.z, -QimuLowerArm.w);