旋转矩阵的特征 - 重新正交化

时间:2014-04-15 10:15:07

标签: algorithm math rotation eigen rotational-matrices

在乘以大量旋转矩阵后,由于舍入问题(去正交化),最终结果可能不再是有效的旋转矩阵

重新正交化的一种方法是遵循以下步骤:

  1. 将旋转矩阵转换为轴角度表示(link
  2. 将轴角度转换回旋转矩阵(link
  3. Eigen库中有什么内容通过隐藏所有细节来做同样的事情吗?或者有更好的食谱吗?

    由于特殊的奇点情况,必须小心处理此程序,因此如果Eigen为此提供了更好的工具,那就太棒了。

4 个答案:

答案 0 :(得分:10)

我不使用Eigen,也没有费心去查找API,但这里是一个简单,计算上便宜且稳定的程序来重新正交化旋转矩阵。该正交化过程取自Direction Cosine Matrix IMU: Theory William Premerlani和Paul Bizard;方程19-21。

xyz成为(略微混乱)旋转矩阵的行向量。让error=dot(x,y)其中dot()是点积。如果矩阵是正交的,xy的点积,即error将为零。

error分布在xy上:x_ort=x-(error/2)*yy_ort=y-(error/2)*x。第三行z_ort=cross(x_ort, y_ort),根据定义与x_orty_ort正交。

现在,您仍然需要对x_orty_ortz_ort进行标准化,因为这些向量应该是单位向量。

x_new = 1/2*(3-dot(x_ort,x_ort))*x_ort
y_new = 1/2*(3-dot(y_ort,y_ort))*y_ort
z_new = 1/2*(3-dot(z_ort,z_ort))*z_ort

就是这样,已经完成了。

使用Eigen提供的API实现它应该很容易。您可以轻松地提出其他正交化程序,但我认为它不会在实践中产生明显的差异。我在我的运动跟踪应用程序中使用了上述程序,并且它工作得非常好;它既稳定又快速。

答案 1 :(得分:1)

与此同时:

#include <Eigen/Geometry>

Eigen::Matrix3d mmm;
Eigen::Matrix3d rrr;
                rrr <<  0.882966, -0.321461,  0.342102,
                        0.431433,  0.842929, -0.321461,
                       -0.185031,  0.431433,  0.882966;
                     // replace this with any rotation matrix

mmm = rrr;

Eigen::AngleAxisd aa(rrr);    // RotationMatrix to AxisAngle
rrr = aa.toRotationMatrix();  // AxisAngle      to RotationMatrix

std::cout <<     mmm << std::endl << std::endl;
std::cout << rrr     << std::endl << std::endl;
std::cout << rrr-mmm << std::endl << std::endl;

这是一个好消息,因为我可以摆脱我的自定义方法,让人头疼一点(怎么能确定他能处理所有奇点呢?),

但我真的希望你对更好/替代的方式发表意见:)

答案 2 :(得分:1)

Singular Value Decomposition应该非常强大。引用参考文献:

  

设M =UΣV是M的奇异值分解,则R = UV。

对于矩阵,Σ中的奇异值应非常接近1。矩阵R保证为orthogonal,这是旋转矩阵的定义属性。如果在计算原始旋转矩阵时没有任何舍入误差,则R将与数值精度内的M完全相同。

答案 3 :(得分:0)

另一种方法是使用Eigen::Quaternion来表示您的轮换。这很容易标准化,并且rotation*rotation产品通常更快。如果您有很多rotation*vector产品(具有相同的矩阵),则应将四元数局部转换为3x3矩阵。