深蓝学院高翔《自动驾驶与机器人中的SLAM技术》第三章作业

第三章

第二章作业详解
第四章作业详解

第一题

在这里插入图片描述

第二题

  • 右乘模式下的dx更新
    在这里插入图片描述
  • 左乘模式下的dx更新
    在这里插入图片描述
    PS: 噪声不参与计算
    // 右乘模式下的dx更新
    auto update_dx_r = [&](Vec18T& dx) {
        dx.template block<3, 1>(0, 0) += dt * dx.template block<3, 1>(3, 0);    // &p
        dx_.template block<3, 1>(3, 0) += dt * (-R_.matrix() * SO3::hat(imu.acce_ - ba_) * dx.template block<3, 1>(6, 0) 
                                        - R_.matrix() * dx.template block<3, 1>(12, 0) 
                                        + dx.template block<3, 1>(15, 0));  // &v
        dx_.template block<3, 1>(6, 0) = (SO3::exp(-(imu.gyro_ - bg_) * dt).matrix()) * dx.template block<3, 1>(6, 0) 
                                        - dt * dx.template block<3, 1>(9, 0);  // &theta
    };

    // 左乘模式下的dx更新
    auto update_dx_l = [&](Vec18T& dx) {
        dx.template block<3, 1>(0, 0) += dt * dx.template block<3, 1>(3, 0);    // &p
        dx_.template block<3, 1>(3, 0) += dt * (-SO3::hat(R_.matrix() * (imu.acce_ - ba_)) * dx.template block<3, 1>(6, 0) 
                                        - R_.matrix() * dx.template block<3, 1>(12, 0) 
                                        + dx.template block<3, 1>(15, 0));  // &v
        dx_.template block<3, 1>(6, 0) =  - dt * R_.matrix() * dx.template block<3, 1>(9, 0);  // &theta
    };
  • 记录运行时间
    Timer timer;
    timer.start();
    bool with_less = true;
    if (!with_less) {
        dx_ = F * dx_;  
    }
    else {
        // update_dx_r(dx_);
        update_dx_l(dx_);
    }
    timer.stop();
    std::cout << "运行时间:" << timer.elapsed() << " 微秒" << std::endl;
  • 修改前:
    在这里插入图片描述

  • 修改后:
    在这里插入图片描述

可以很明显的观察到拆分计算后相对于矩阵运算运行时间加快。

第三题

左乘推导过程中,误差变量的运动方程中只有速度与旋转和右乘不同

在这里插入图片描述

  • 根据上图公式修改 Predict() 中 F 矩阵的推导
    Mat18T F = Mat18T::Identity();                                                 // 主对角线
    F.template block<3, 3>(0, 3) = Mat3T::Identity() * dt;                         // p 对 v
    // F.template block<3, 3>(3, 6) = -R_.matrix() * SO3::hat(imu.acce_ - ba_) * dt;  // v对theta 右乘
    F.template block<3, 3>(3, 6) = -SO3::hat(R_.matrix() * (imu.acce_ - ba_)) * dt;  // v对theta 左乘                         
    F.template block<3, 3>(3, 12) = -R_.matrix() * dt;                             // v 对 ba
    F.template block<3, 3>(3, 15) = Mat3T::Identity() * dt;                        // v 对 g
    // F.template block<3, 3>(6, 6) = SO3::exp(-(imu.gyro_ - bg_) * dt).matrix();     // theta 对 theta 右乘
    // F.template block<3, 3>(6, 9) = -Mat3T::Identity() * dt;                        // theta 对 bg 右乘
    F.template block<3, 3>(6, 9) = -R_.matrix() * dt;                        // theta 对 bg 左乘
  • 根据左乘公式修改 UpdateAndReset() 中对 名义状态变量 根据 误差 dx_ 的更新
    /// 更新名义状态变量,重置error state
    void UpdateAndReset() {
        p_ += dx_.template block<3, 1>(0, 0);
        v_ += dx_.template block<3, 1>(3, 0);
        // R_ = R_ * SO3::exp(dx_.template block<3, 1>(6, 0));    // !!!!改为左乘
        R_ = SO3::exp(dx_.template block<3, 1>(6, 0)) * R_;
        
        if (options_.update_bias_gyro_) {
            bg_ += dx_.template block<3, 1>(9, 0);
        }

        if (options_.update_bias_acce_) {
            ba_ += dx_.template block<3, 1>(12, 0);
        }

        g_ += dx_.template block<3, 1>(15, 0);

        // 以上为均值部分的误差更新,更新后可以简单的实现为dx_=0
        // 下面为协方差的更新,需要考虑重置后的切空间投影

        ProjectCov();
        dx_.setZero();
    }
  • 切空间投影同样需要修改,推导公式如下图

在这里插入图片描述

    /// 对P阵进行投影,参考式(3.63)
    void ProjectCov() {
        Mat18T J = Mat18T::Identity();
        // 右乘
        // J.template block<3, 3>(6, 6) = Mat3T::Identity() - 0.5 * SO3::hat(dx_.template block<3, 1>(6, 0));
        // 左乘
        J.template block<3, 3>(6, 6) = Mat3T::Identity() + 0.5 * SO3::hat(dx_.template block<3, 1>(6, 0));
        cov_ = J * cov_ * J.transpose();
    }
  • 观测过程同样需要修改成为 左乘 方式,根据下图公式修改 ObserveSE3()

在这里插入图片描述

    // 更新x和cov
    Vec6d innov = Vec6d::Zero();
    innov.template head<3>() = (pose.translation() - p_);          // 平移部分
    // innov.template tail<3>() = (R_.inverse() * pose.so3()).log();  // 旋转部分(3.67)  右乘
    innov.template tail<3>() = (pose.so3() * R_.inverse()).log();   // 旋转部分 左乘

第二题与第三题修改过后的运行结果,如下图

使用odom观测修正速度

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值