从零手写VIO的第三课的作业,在此记录
我总结的一份从零学VIO第三讲的思维导图从零手写VIO(三)


文章目录

  • 估计曲线
    • 绘制阻尼因子随迭代变化的曲线
      • 保存lamada
      • 画出lambda变化图
    • 将曲线参数改成y=ax^2 +bx+c
      • 残差计算
      • 雅克比计算
      • main函数
    • 其他阻尼因子更新策略
  • 公式推导

估计曲线

绘制阻尼因子随迭代变化的曲线

我的思路是保存代码中的lamada,然后使用Python绘制出图。

保存lamada

bool Problem::Solve(int iterations) {if (edges_.size() == 0 || verticies_.size() == 0) {std::cerr << "\nCannot solve problem without edges or verticies" << std::endl;return false;}TicToc t_solve;// 统计优化变量的维数,为构建 H 矩阵做准备SetOrdering();// 遍历edge, 构建 H = J^T * J 矩阵MakeHessian();// LM 初始化ComputeLambdaInitLM();// LM 算法迭代求解bool stop = false;int iter = 0;std::vector<double> lambdas;std::string filename = "lambda.txt";std::ofstream save_lambda;save_lambada.open(filename.c_str());while (!stop && (iter < iterations)) {std::cout << "iter: " << iter << " , chi= " << currentChi_ << " , Lambda= " << currentLambda_<< std::endl;lambadas.push_back(currentLambda_);bool oneStepSuccess = false;int false_cnt = 0;while (!oneStepSuccess)  // 不断尝试 Lambda, 直到成功迭代一步{// setLambdaAddLambdatoHessianLM();// 第四步,解线性方程 H X = BSolveLinearSystem();//RemoveLambdaHessianLM();// 优化退出条件1: delta_x_ 很小则退出if (delta_x_.squaredNorm() <= 1e-6 || false_cnt > 10) {stop = true;break;}// 更新状态量 X = X+ delta_xUpdateStates();// 判断当前步是否可行以及 LM 的 lambda 怎么更新oneStepSuccess = IsGoodStepInLM();// 后续处理,if (oneStepSuccess) {// 在新线性化点 构建 hessianMakeHessian();// TODO:: 这个判断条件可以丢掉,条件 b_max <= 1e-12 很难达到,这里的阈值条件不应该用绝对值,而是相对值
//                double b_max = 0.0;
//                for (int i = 0; i < b_.size(); ++i) {//                    b_max = max(fabs(b_(i)), b_max);
//                }
//                // 优化退出条件2: 如果残差 b_max 已经很小了,那就退出
//                stop = (b_max <= 1e-12);false_cnt = 0;} else {false_cnt++;RollbackStates();   // 误差没下降,回滚}}iter++;// 优化退出条件3: currentChi_ 跟第一次的chi2相比,下降了 1e6 倍则退出if (sqrt(currentChi_) <= stopThresholdLM_)stop = true;}for(size_t i=0;i < lambdas.size(); i++){save_lambda<<lambdas[i]<<" "<<std::endl;}std::cout << "problem solve cost: " << t_solve.toc() << " ms" << std::endl;std::cout << "   makeHessian cost: " << t_hessian_cost_ << " ms" << std::endl;return true;
}

重新编译代码,运行testCurveFitting,即可在工作区间下生成lambda.txt

0.001
699.051
1864.14
1242.76
414.252
138.084
46.028
15.3427
5.11423
1.70474
0.568247
0.378832

画出lambda变化图

在工作区新建一个文件夹scripts,在此文件夹下面放置Python脚本
draw_lambda.py

# -*- coding: utf-8 -*-
"""
Created on Thu june 20 16:23:24 2020@author: hyj
"""import numpy as np;
import matplotlib
import matplotlib.pyplot as plt
import osfilepath = os.path.abspath('.')
y = []
with open(filepath + '/lambada.txt','r') as f:data = f.readlines() #txt 所有字符串读进datafor line in data:  odom = line.split()        #将单个数据分隔开存好  numbers_float = map(float, odom) #转化为浮点数  y.append( numbers_float[0] )plt.plot(y)
plt.show()

运行该脚本

将曲线参数改成y=ax^2 +bx+c

代码修改如下:

残差计算

// 计算曲线模型误差virtual void ComputeResidual() override{Vec3 abc = verticies_[0]->Parameters();  // 估计的参数//residual_(0) = std::exp( abc(0)*x_*x_ + abc(1)*x_ + abc(2) ) - y_;  // 构建残差residual_(0) = abc(0)*x_*x_ + abc(1)*x_ + abc(2)  - y_;  // 构建残差}

雅克比计算

// 计算残差对变量的雅克比virtual void ComputeJacobians() override{//Vec3 abc = verticies_[0]->Parameters();//double exp_y = std::exp( abc(0)*x_*x_ + abc(1)*x_ + abc(2) );Eigen::Matrix<double, 1, 3> jaco_abc;  // 误差为1维,状态量 3 个,所以是 1x3 的雅克比矩阵//jaco_abc << x_ * x_ * exp_y, x_ * exp_y , 1 * exp_y;jaco_abc << x_ * x_ , x_  , 1 ;jacobians_[0] = jaco_abc;}

main函数

主要是把观测值的计算公式改一下

// 构造 N 次观测for (int i = 0; i < N; ++i) {double x = i/100.;double n = noise(generator);// 观测 ydouble y = a*x*x + b*x + c + n;
//        double y = std::exp( a*x*x + b*x + c );

N=100的时候,估计出的abc结果不是很好,为了更好的结果,将数据点的个数N改为1000
结果:

其他阻尼因子更新策略

Marquardt 更新策略

Nielsen 更新策略:

Nielsen更新策略代码为:

bool Problem::IsGoodStepInLM() {double scale = 0;scale = delta_x_.transpose() * (currentLambda_ * delta_x_ + b_);scale += 1e-3;    // make sure it's non-zero :)// recompute residuals after update state// 统计所有的残差double tempChi = 0.0;for (auto edge: edges_) {edge.second->ComputeResidual();tempChi += edge.second->Chi2();}double rho = (currentChi_ - tempChi) / scale;if (rho > 0 && isfinite(tempChi))   // last step was good, 误差在下降{double alpha = 1. - pow((2 * rho - 1), 3);alpha = std::min(alpha, 2. / 3.);double scaleFactor = (std::max)(1. / 3., alpha);currentLambda_ *= scaleFactor;ni_ = 2;currentChi_ = tempChi;return true;} else {currentLambda_ *= ni_;ni_ *= 2;return false;}
}

公式推导

参考 公式推导

从零手写VIO(三)——LM算法相关推荐

  1. 从零手写VIO(7)

    从零手写VIO(7) 文章目录 从零手写VIO(7) 前言 一.VINS-Course代码解析 二.作业(7) 1.simulation-test.cpp修改 2.Sysytem.cpp修改 3.co ...

  2. [从零手写VIO|第五节]——后端优化实践——单目BA求解代码解析

    长篇警告⚠⚠⚠ 目录 solver 全流程回顾 Solver三要素 Solver求解中的疑问 核心问题 代码解析 1. TestMonoBA.cpp 2. 后端部分: 2.1 顶点 2.2 边(残差) ...

  3. 手写VIO --学习笔记 - Part1

    目录 一.VIO文献阅读 二.四元数和李代数更新 三.其他导数 参考 一.VIO文献阅读 阅读VIO 相关综述文献,回答以下问题: 1.视觉与IMU进行融合之后有何优势? IMU:(Inertial ...

  4. 《视觉SLAM进阶:从零开始手写VIO》第二讲作业-IMU仿真、MU imu_utils标定

    <视觉SLAM进阶:从零开始手写VIO>第二讲作业-IMU仿真.MU imu_utils标定 作业题目: 1 仿真代码解析 仿真代码地址:https://github.com/HeYiji ...

  5. 深蓝学院《从零开始手写VIO》作业三

    深蓝学院<从零开始手写VIO>作业三 深蓝学院<从零开始手写VIO>作业三 1. 代码修改 2. 公式推导 3. 公式证明: 深蓝学院<从零开始手写VIO>作业三 ...

  6. 从零开始手写VIO第三章作业(含关键点细节及思维过程)

    文章目录 前言·与同主题博文的不同 1.代码修改 1.1阻尼因子 µ 随着迭代变化的曲线图 1.2完成曲线y = ax^2^ + bx + c的参数估计 1.3实现其他更优秀的阻尼因子策略 2.公式推 ...

  7. 乘法逆元 java_java写的三个求乘法逆元的算法

    java写的三个求乘法逆元的算法: 第一个是著名的扩展欧拉算法 第二个是网上发现的一个牛人写的算法 第三个是我这个菜鸟补充的一个最垃圾的算法 在对较小的数进行运算的时候,后两种算法都比第一个快,第三个 ...

  8. 【图像隐写】基于LSB+DWT+DCT三种算法实现图像和音频水印嵌入提取含Matlab源码

    1 简介 基于LSB+DWT+DCT三种算法实现图像和音频水印嵌入提取. 1.1 LSB算法 根据LSB算法简单易实现的特点,结合在图像置乱技术中很好特性的Arnold变换.利用变化产生影子图像.通过 ...

  9. 写了三百篇算法题解,关于如何刷题有些话我想对你说

    这篇文章憋了我挺久的,感觉都快憋出内伤,一次次的打开 Typora 写几十个字,一次次的修改删除最后关闭 Typora,如此反复. 为什么会如此纠结? 或许是太狂妄了,我真的想让那些看了这篇文章的人都 ...

  10. 《视觉SLAM进阶:从零开始手写VIO》第三讲 基于优化的IMU预积分与视觉信息融合 作业

    <视觉SLAM进阶:从零开始手写VIO>第三讲 基于优化的IMU预积分与视觉信息融合 作业 文章目录 <视觉SLAM进阶:从零开始手写VIO>第三讲 基于优化的IMU预积分与视 ...

最新文章

  1. php explore im,浏栏器器-explore.class.php_php
  2. 线程撕裂者安装linux,Linux FreeBSD 12.1跑分测试:在AMD Ryzen线程撕裂者3970X上快得刷新认知...
  3. windows下多进程加协程并发模式
  4. Java 洛谷 P1028 数的计算
  5. 将表单请求提交到本页
  6. 卓越管理的秘密(Behind Closed Doors)
  7. x265-确定slice type-2
  8. Blazor+Dapr+K8s微服务之服务调用
  9. 开启事物_《原神》全新角色甘雨登场 「浮生孰来」活动祈愿开启_新闻资讯_最新手游时评_原创手游资讯...
  10. android 自定义圆形pop,Android布局自定义Shap圆形ImageView可以单独设置背景与图片...
  11. 2019湖南职高计算机总分是多少,2019湖南高职单招一般多少分能过
  12. 上海.NET俱乐部聚会筹备进展
  13. c语言判断素数(质数)
  14. weico.android批量转发,weico android|Weico新浪微博3.3.5 客户端_手机软件
  15. ARDUINO 入门学习第三课
  16. android 图片缩放工具,批量图片缩放软件下载-批量图片缩放 安卓版v1.3.1-PC6安卓网...
  17. 2020牛客寒假算法基础集训营4 G - 音乐鉴赏(概率与期望)
  18. 专业办公套件WPS Office 2020 for Mac
  19. 【1235. 规划兼职工作】
  20. 气势恢弘大气的英文字体免费下载[otf,ttf,woff]

热门文章

  1. 如何使用EditPlus3编写汇编语言
  2. 实用软件工程(张海藩)课后答案
  3. 淦!推荐10款程序员专用高清壁纸!!
  4. 算法图解——の——二分查找【附带pdf下载链接】
  5. Python:jieba库的介绍与使用
  6. c语言转化音乐格式转换器安卓版,MP3格式转换器APP
  7. 苹果iOS设备解锁软件:iToolab UnlockGo
  8. 每日一题_36. 有效的数独
  9. 海店湾:劲爆!这款APP的横空出世,是美女们的福利还是潮流?
  10. 40题计算机程序设计基础(C语言)编程习题