【问题标题】:Unit testing euler-to-quaternion implementation fails单元测试欧拉到四元数的实现失败
【发布时间】:2020-02-04 14:23:04
【问题描述】:

我目前正在尝试实现一个四元数,我需要在其中进行欧拉到四元数的转换。我当前的实现看起来像这样,我从 here 中删减出来的

void Quaternion::FromEuler(double x, double y, double z)
{
    z *= Math::DegToRad;
    y *= Math::DegToRad;
    x *= Math::DegToRad;

    double xCos = Math::Cos(x / 2);
    double xSin = Math::Sin(x / 2);
    double yCos = Math::Cos(y / 2);
    double ySin = Math::Sin(y / 2);
    double zCos = Math::Cos(z / 2);
    double zSin = Math::Sin(z / 2);

    W = zCos * yCos * xCos + zSin * ySin * xSin;
    X = zCos * yCos * xSin - zSin * ySin * xCos;
    Y = zSin * yCos * xSin + zCos * ySin * xCos;
    Z = zSin * yCos * xCos - zCos * ySin * xSin;
}

我正在使用以下单元测试来测试实现

TEST(Quaternions, FromEuler)
{
    Quaternion quaternion(45, 90, 180);


    ExpectNear(quaternion, 0.6532815, -0.2705981, 0.6532815, 0.270598);
}

以下方式失败。

  Expected | Actual     
X  0.6533   -0.6533
Y -0.2706    0.2706
Z  0.6533    0.6533
W  0.2706    0.2706

预期值是从各种网站获得的,它们产生的值相同,但符号不同,类似于我当前的输出与预期输出的差异。

我也尝试了几种不同的实现,都产生了相同类型的失败。

这是因为轮换有several representations,在这种情况下,我的单元测试失败实际上是一个假阴性?如果是这样,我该如何实施正确的单元测试?

【问题讨论】:

  • Math:: 命名空间是什么?这是什么图书馆?
  • 这是我的,函数调用只是标准库的包装。 DegToRad 实现为 M_PI / 180.0
  • 不能完全是reproduce,不清楚您的代码中的变量与链接的维基百科页面中的变量有何关系。 Quaternion 在你的代码中是如何定义的?
  • 我在实现中更改了参数的顺序,所以它是 (X, Y, Z) 而不是维基百科的 (Z, Y, X) 顺序 - 如果您在你的主要功能它会输出相同的。这是完整的四元数实现。有点长添加到 OP。 hastebin.com/zoxojokiyi.cpp
  • 您的问题似乎是混合了通用的X,Y,Z 名称,其中Conversion between quaternions and Euler angles 通常用yaw, pitch, roll 来描述,而您选择的Axes Convention 很重要。

标签: c++ unit-testing quaternions euler-angles


【解决方案1】:

通过简单的数学可以推断出您对结果的期望是错误的:z_deg == 180,即 z_rad == PI,将给出 zCos 值 0.0:PI/2 的 cos 为 0.0。知道了这一点,你就可以简化W,X,Y,Z的计算,忽略所有带有zCos的产品。

由于 x/2 和 y/2 也在第一象限,xCosxSinyCosySinzSin 的所有值都是正数。因此,X 的结果必须是负数(0.0 减去一些正数)。而且,Y 的结果必须是正数:某个正数乘积加上 0.0。

这只是从您的代码和给定的参数中得出的。结论是,要么期望是错误的,要么您在算法中发现了错误。至少(正如预期的那样)实际结果是合理的:-)

那么,检查您的代码和期望,也许您有来自不同来源的混合实现和期望?或者,如果它们来自同一来源,并且您没有犯任何复制错误,则原作者计算错误......

【讨论】:

  • 你和大卫都一针见血。我错误地使用 x、y 和 z 坐标转换偏航、俯仰和滚动。不过,在与 Unity 的四元数进行比较时,我发现了一些不一致之处。我原始帖子中发布的问题已得到修复,因此我将针对其他问题发布一个新问题。感谢您的帮助! :)
猜你喜欢
  • 2012-06-21
  • 2019-10-27
  • 1970-01-01
  • 1970-01-01
  • 2013-06-22
  • 2014-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多