slam中frame变换连乘顺序

记录一下,在坐标变换中踩到的一个坑

在slam中进行坐标变换时,若想求得变换 T 2 1 T_2^1 T21,有下面两种方式可以使用:

  1. T 2 1 = T 0 1 ∗ T 2 0 T_2^1 = T_0^1 * T_2^0 T21=T01T20

  2. T 2 1 = T 2 0 ∗ T 0 1 T_2^1 = T_2^0 * T_0^1 T21=T20T01

然而当我们使用如下代码进行验证时

#include <Eigen/Geometry>
#include <iostream>

int main()
{
    Eigen::Quaternionf base_1_to_0(Eigen::AngleAxisf(M_PI / 3, Eigen::Vector3f::UnitX()) * Eigen::AngleAxisf(M_PI / 3, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(M_PI / 3, Eigen::Vector3f::UnitZ()));
    Eigen::Quaternionf base_2_to_0(Eigen::AngleAxisf(M_PI / 6, Eigen::Vector3f::UnitX()) * Eigen::AngleAxisf(M_PI / 6, Eigen::Vector3f::UnitY()) * Eigen::AngleAxisf(M_PI / 6, Eigen::Vector3f::UnitZ()));

    auto T0 = (base_1_to_0.inverse() * base_2_to_0).normalized();
    auto T1 = (base_2_to_0 * base_1_to_0.inverse()).normalized();

    std::cout<<"T0:"<<T0.w()<<" "<<T0.x()<<" "<<T0.y()<<" "<<T0.z() <<std::endl;
    std::cout<<"T1:"<<T1.w()<<" "<<T1.x()<<" "<<T1.y()<<" "<<T1.z() <<std::endl;

    Eigen::Vector3f vec(1,1,1);

    std::cout << "T0 matrix:\n" << T0.toRotationMatrix() << std::endl;
    std::cout << "T1 matrix:\n" << T1.toRotationMatrix() << std::endl;

    std::cout << "T0 vector:\n"
              << T0.toRotationMatrix() * vec << std::endl;
    std::cout << "T1 vector:\n"
              << T1.toRotationMatrix() * vec << std::endl;

    std::cout << "T0 eular:\n"
              << T0.toRotationMatrix().eulerAngles(0,1,2)/M_PI*180 << std::endl;
    std::cout << "T1 eular:\n"
              << T1.toRotationMatrix().eulerAngles(0,1,2)/M_PI*180 << std::endl;

    return 0;
}

却得到如下结果:

T0:0.853854 -0.306186 -0.0473672 -0.418258
T1:0.853854 -0.418258 -0.0473672 -0.306186
T0 matrix:
 0.645633  0.743269   0.17524
-0.685256   0.46262    0.5625
 0.337019 -0.483253  0.808013
T1 matrix:
 0.808013    0.5625   0.17524
-0.483253   0.46262  0.743269
 0.337019 -0.685256  0.645633
T0 vector:
 1.56414
0.339864
0.661779
T1 vector:
 1.54575
0.722636
0.297395
T0 eular:
145.156
169.907
130.979
T1 eular:
130.979
169.907
145.156

可以看出两种方式所得到的 T 2 1 T_2^1 T21结果是不一样的。

那么我们应该使用那种方式进行计算呢?

我们知道 T 2 1 T_2^1 T21的变换是:将 F r a m e 2 Frame_2 Frame2下的特征变换到 F r a m e 1 Frame_1 Frame1下进行表示,设 F r a m e 2 Frame_2 Frame2的特征为点 P 2 P^2 P2,我们分别用上面的两种方式去对 P 2 P^2 P2做变换:

  1. P 1 = T 2 1 ∗ P 2 = T 0 1 ∗ T 2 0 ∗ P 2 P^1 = T_2^1 * P^2 = T_0^1 * T_2^0 * P^2 P1=T21P2=T01T20P2
  2. P 1 = T 2 1 ∗ P 2 = T 2 0 ∗ T 0 1 ∗ P 2 P^1 = T_2^1 * P^2 = T_2^0 * T_0^1 * P^2 P1=T21P2=T20T01P2

可以看到在公式2的尾部 T 0 1 ∗ P 2 T_0^1 * P^2 T01P2 是没有实际的变换意义的,所以变换要使用第一种方法,即 所获得的最终变换的上标作为变换连乘的起始上标,最终变换的下标作为连乘变换的终止下标,中间消元部分的方向是由左下到右上进行消元。

结论:使用方法1: T 2 1 = T 0 1 ∗ T 2 0 T_2^1 = T_0^1 * T_2^0 T21=T01T20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值