從零入門激光SLAM(二十)——IESKF代碼實現

大家好呀,我是一個SLAM方向的在讀博士,深知SLAM學習過程一路走來的坎坷,也十分感謝各位大佬的優質文章和源碼。隨著知識的越來越多,越來越細,我準備整理一個自己的激光SLAM學習筆記專欄,從0帶大家快速上手激光SLAM,也方便想入門SLAM的同學和小白學習參考,相信看完會有一定的收獲。如有不對的地方歡迎指出,歡迎各位大佬交流討論,一起進步。博主創建了一個科研互助群Q:772356582,歡迎大家加入討論。

源碼是高博大佬的,網址如下?

slam_in_autonomous_driving/src/ch8 at master · gaoxiang12/slam_in_autonomous_driving · GitHub

下面對代碼的邏輯和主要函數進行解析

一、IESKF結構

  • 參數配置/設置狀態變量

    struct Options {Options() = default;/// IEKF配置int num_iterations_ = 3;  // 迭代次數double quit_eps_ = 1e-3;  // 終止迭代的dx大小/// IMU 測量與零偏參數double imu_dt_ = 0.01;         // IMU測量間隔double gyro_var_ = 1e-5;       // 陀螺測量標準差double acce_var_ = 1e-2;       // 加計測量標準差double bias_gyro_var_ = 1e-6;  // 陀螺零偏游走標準差double bias_acce_var_ = 1e-4;  // 加計零偏游走標準差/// RTK 觀測參數double gnss_pos_noise_ = 0.1;                   // GNSS位置噪聲double gnss_height_noise_ = 0.1;                // GNSS高度噪聲double gnss_ang_noise_ = 1.0 * math::kDEG2RAD;  // GNSS旋轉噪聲/// 其他配置bool update_bias_gyro_ = true;  // 是否更新biasbool update_bias_acce_ = true;  // 是否更新bias};// nominal stateSO3 R_;VecT p_ = VecT::Zero();VecT v_ = VecT::Zero();VecT bg_ = VecT::Zero();VecT ba_ = VecT::Zero();VecT g_{0, 0, -9.8};// error stateVec18T dx_ = Vec18T::Zero();// covarianceMat18T cov_ = Mat18T::Identity();// noiseMotionNoiseT Q_ = MotionNoiseT::Zero();GnssNoiseT gnss_noise_ = GnssNoiseT::Zero();Options options_;
    
  • 設置初始條件
    void SetInitialConditions(Options options, const VecT& init_bg, const VecT& init_ba,const VecT& gravity = VecT(0, 0, -9.8)) {BuildNoise(options);options_ = options;bg_ = init_bg;ba_ = init_ba;g_ = gravity;cov_ = 1e-4 * Mat18T::Identity();cov_.template block<3,?3>(6, 6) = 0.1 * math::kDEG2RAD * Mat3T::Identity();}
    //構建噪聲模型
    void BuildNoise(const Options& options) {double ev = options.acce_var_;double et = options.gyro_var_;double eg = options.bias_gyro_var_;double ea = options.bias_acce_var_;double ev2 = ev;  // * ev;double et2 = et;  // * et;double eg2 = eg;  // * eg;double ea2 = ea;  // * ea;// set QQ_.diagonal() << 0, 0, 0, ev2, ev2, ev2, et2, et2, et2, eg2, eg2, eg2, ea2, ea2, ea2, 0, 0, 0;double gp2 = options.gnss_pos_noise_ * options.gnss_pos_noise_;double gh2 = options.gnss_height_noise_ * options.gnss_height_noise_;double ga2 = options.gnss_ang_noise_ * options.gnss_ang_noise_;gnss_noise_.diagonal() << gp2, gp2, gh2, ga2, ga2, ga2;
    }
    
  • 使用IMU預測

    bool IESKF<S>::Predict(const IMU& imu) {/// Predict 部分與ESKF完全一樣,不再解釋assert(imu.timestamp_ >= current_time_);double dt = imu.timestamp_ - current_time_;if (dt > (5 * options_.imu_dt_) || dt < 0) {LOG(INFO) << "skip this imu because dt_ = " << dt;current_time_ = imu.timestamp_;return false;}VecT new_p = p_ + v_ * dt + 0.5 * (R_ * (imu.acce_ - ba_)) * dt * dt + 0.5 * g_ * dt * dt;VecT new_v = v_ + R_ * (imu.acce_ - ba_) * dt + g_ * dt;SO3 new_R = R_ * SO3::exp((imu.gyro_ - bg_) * dt);R_ = new_R;v_ = new_v;p_ = new_p;Mat18T F = Mat18T::Identity();F.template block<3,?3>(0, 3) = Mat3T::Identity() * dt;F.template block<3,?3>(3, 6) = -R_.matrix() * SO3::hat(imu.acce_ - ba_) * dt;F.template block<3,?3>(3, 12) = -R_.matrix() * dt;F.template block<3,?3>(3, 15) = Mat3T::Identity() * dt;F.template block<3,?3>(6, 6) = SO3::exp(-(imu.gyro_ - bg_) * dt).matrix();F.template block<3,?3>(6, 9) = -Mat3T::Identity() * dt;cov_ = F * cov_ * F.transpose() + Q_;current_time_ = imu.timestamp_;return true;
    }
    
  • 迭代觀測模型

    using CustomObsFunc = std::function<void(const SE3& input_pose, Eigen::Matrix<S, 18, 18>& HT_Vinv_H,Eigen::Matrix<S, 18, 1>& HT_Vinv_r)>;
    // 使用自定義觀測函數更新濾波器
    bool IESKF<S>::UpdateUsingCustomObserve(IESKF::CustomObsFunc obs) {// H陣由用戶給定// 保存當前的旋轉矩陣SO3 start_R = R_;Eigen::Matrix<S, 18, 1> HTVr;Eigen::Matrix<S, 18, 18> HTVH;Eigen::Matrix<S, 18, Eigen::Dynamic> K;Mat18T Pk, Qk;//進入殘差更新循環for (int iter = 0; iter < options_.num_iterations_; ++iter) {// 調用用戶提供的觀測函數//GetNominalSE3()獲取當前名義狀態位姿
    //SE3 GetNominalSE3() const { return SE3(R_, p_); }//HTVH卡爾曼更新步驟中用于修正預測的協方差矩陣//HTVr卡爾曼更新步驟中用于修正預測的狀態變量obs(GetNominalSE3(), HTVH, HTVr);// 投影協方差矩陣PMat18T J = Mat18T::Identity();J.template block<3,?3>(6, 6) = Mat3T::Identity() - 0.5 * SO3::hat((R_.inverse() * start_R).log());Pk = J * cov_ * J.transpose();// 卡爾曼更新Qk = (Pk.inverse() + HTVH).inverse();   // 計算更新后的協方差矩陣Qkdx_ = Qk * HTVr; // 計算狀態增量dx_// LOG(INFO) << "iter " << iter << " dx = " << dx_.transpose() << ", dxn: " << dx_.norm();//將增量dx_合并到名義變量中Update();// 檢查增量的范數是否小于終止閾值if (dx_.norm() < options_.quit_eps_) {break;}}// 更新協方差矩陣update Pcov_ = (Mat18T::Identity() - Qk * HTVH) * Pk;// 再次投影協方差矩陣PMat18T J = Mat18T::Identity();Vec3d dtheta = (R_.inverse() * start_R).log();J.template block<3,?3>(6, 6) = Mat3T::Identity() - 0.5 * SO3::hat(dtheta);cov_ = J * cov_ * J.inverse();// 重置狀態增量dx_.setZero();return true;
    }

詳情請見...

?從零入門激光SLAM(二十)——IESKF代碼解釋 - 古月居 (guyuehome.com)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/14410.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/14410.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/14410.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ansible自動化運維中的file文件模塊模塊應用詳解

作者主頁&#xff1a;點擊&#xff01; Ansible專欄&#xff1a;點擊&#xff01; 創作時間&#xff1a;2024年5月21日15點21分 &#x1f4af;趣站推薦&#x1f4af; 前些天發現了一個巨牛的&#x1f916;人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xf…

【Java筆記】第8章:面向對象的三大特性(封裝、繼承、多態)

前言1. 三大特性概述2. 封裝3. 繼承4. 多態結語 #include<GUIQU.h> int main { 上期回顧:【Java筆記】第7章&#xff1a;面向對象 個人主頁&#xff1a;C_GUIQU 歸屬專欄&#xff1a;【Java學習】 return 一鍵三連; } 前言 各位小伙伴大家好&#xff01;上期小編給大家…

后端技術常用網站

技術說明官網SpringBootMVC框架https://spring.io/projects/spring-bootSpringCloud微服務框架https://spring.io/projects/spring-cloud/MyBatis-PlusORM框架https://mp.baomidou.com/Swagger-UI文檔生產工具https://github.com/swagger-api/swagger-uiKibana分析和可視化平臺…

SO_REUSEPORT 之 TCP負載均衡驗證

首先啟動兩個tcp server&#xff0c; 代碼里開啟 SO_REUSEPORT [my_testlocalhost test]$ ./tcp_server_reuseport & [1] 1864 [my_testlocalhost test]$ Server listening on port 8888[my_testlocalhost test]$ ./tcp_server_reuseport & [2] 1865 [my_testlocalh…

網絡工程師備考1——基礎學習

認識設備 1 交換機 一、什么是交換機&#xff1f; 實現不同電腦之間數據的轉發 換機是一種用于電(光)信號轉發的網絡設備。 它可以為接入交換機的任意兩個網絡節點提供獨享的電信號通路。最常見的交換機是以太網交換機。交換機工作于OSI參考模型的第二層&#xff0c;即數據…

使用 Supabase 的 Realtime + Storage 非常方便呢

文章目錄 &#xff08;一&#xff09;Supabase&#xff08;二&#xff09;Realtime&#xff08;消息&#xff09;&#xff08;2.1&#xff09;Python 消息訂閱&#xff08;2.2&#xff09;JavaScript 消息訂閱 &#xff08;三&#xff09;Storage&#xff08;存儲&#xff09;&…

Linux:Ubuntu修改root密碼

Linux&#xff1a;Ubuntu修改root密碼 修改默認grub配置文件 rootshanxin:~# vim /etc/default/grub# 主要修改內容如下&#xff1a;GRUB_DEFAULT0 #GRUB_TIMEOUT_STYLEhidden 注釋這一行 GRUB_TIMEOUT5 # 將這一行的時間改為5秒進行開啟啟動的grub文件的復寫 rootshanxin:~…

芯課堂 | UI Creator 物理鍵盤移植指南

LVGL提供輸入設備的種類一共有5種&#xff0c;分別是&#xff1a;touchpad&#xff08;觸摸板&#xff09;、mouse&#xff08;鼠標&#xff09;、keypad&#xff08;鍵盤&#xff09;、encoder&#xff08;編碼器&#xff09;、button&#xff08;外部按鍵&#xff09;。而基于…

Tron 節點 性能壓測

文章目錄 一、代碼說明1.1 主要功能1.2 代碼示例1.3 代碼解釋1.4 執行流程 二、結果分析三、參數解釋3.1 numWorkers 和 numRequests 說明3.2 使用場景 四、注意事項 最近搭建了一個TRON節點&#xff0c;同事不相信我的自建節點比官方更靠譜&#xff0c;咱們給他使用golang寫一…

如何成為一個專業的AI產品經理?

可以找專業的老師帶。 可以找專業的內容學。 可以多遇挫折并快速學習&#xff0c;屢敗屢戰&#xff0c;筆者本人從業AI十年有余&#xff0c;吃了不少苦&#xff0c;有過很多或成功或失敗的經歷。 成為一個專業的AI產品經理需要一系列專業知識和技能的積累&#xff0c;以及在…

axios - 簡 單 的 請 求 模 板

import {message } from ant-design-vue import axios from axios import {useUserStore } from @/store/modules/user import router from @/routerconst instance = axios.create({baseURL: http://192.168.110.171:5201,timeout: 5000, })* 請求攔截器 insta

切換Ubuntu開機的主題

要將Ubuntu系統的啟動畫面&#xff08;即開機時的顯示界面&#xff09;從Lubuntu切換回原生的Ubuntu界面&#xff0c;可以按照以下步驟操作&#xff1a; 1. 安裝原生Ubuntu的plymouth主題 首先&#xff0c;確保你已經安裝了原生Ubuntu的plymouth主題。打開終端并運行以下命令…

基于Matlab卷積神經網絡(CNN)人臉識別系統

歡迎大家點贊、收藏、關注、評論啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代碼。 文章目錄 一項目簡介 二、功能三、系統四. 總結 一項目簡介 一、項目背景與意義 人臉識別技術作為計算機視覺領域的一個重要分支&#xff0c;已經廣泛應用于安全監控、身份驗證…

Python基礎知識歸納總結

目錄 一、線性表 總結 二、棧 三、隊列 四、哈希表 五、字符串 六、正則表達式 綜合示例 一、線性表 線性表&#xff08;通常用列表表示&#xff09;是一種按線性順序存儲元素的數據結構。 插入元素 (append, insert) 刪除元素 (remove, pop) 查找元素 (index) 更新…

FreeRTOS學習——FreeRTOS隊列(下)之隊列創建

本篇文章記錄我學習FreeRTOS隊列創建的知識。主要分享隊列創建需要使用的初始化函數、隊列復位函數。 需要進一步了解FreeRTOS隊列的相關知識&#xff0c;讀者可以參考以下文章&#xff1a; FreeRTOS學習——FreeRTOS隊列&#xff08;上&#xff09;_freertos 單元素隊列-CSDN博…

Spring、SpringMVC、SpringBoot 三者之間是什么關系

Spring、SpringMVC、SpringBoot 是三個獨立的框架&#xff0c;它們之間的關系是: 1. Spring是一個Java的輕量級應用框架&#xff0c;提供了基于IoC和AOP的支持&#xff0c;用于構建企業級應用。Spring有多 個模塊&#xff0c;包括 Spring Core、Spring Context、Spring JDBC、…

高質量油封選擇的重要性

在現代工業和機械系統中&#xff0c;油封的作用至關重要。它們不僅防止潤滑劑泄漏&#xff0c;還阻止污染物進入系統&#xff0c;從而保障設備的正常運行。選擇高質量的油封對于保證設備性能、延長使用壽命和降低維護成本至關重要。本文將從多個角度探討選擇高質量油封的重要性…

【hackmyvm】Slowman靶機

文章目錄 主機探測端口探測FTP匿名登錄 目錄探測hydra爆破mysql爆破zip------fcrackzip爆破密碼-----john提權 主機探測 ┌──(root?kali)-[/home/kali] └─# fping -ag 192.168.9.1/24 2>/dev/null 192.168.9.221 主機192.168.9.224 靶機端口探測 ┌──(roo…

送變電乙級資質申請攻略:關鍵步驟與注意事項

關鍵步驟&#xff1a; 工商注冊與資本核實&#xff1a; 確保企業已正式注冊&#xff0c;且注冊資金不少于100萬元人民幣&#xff0c;同時準備企業法人營業執照等相關證明文件。 人員配置與注冊&#xff1a; 根據資質要求&#xff0c;配置齊全合理的專業技術人員&#xff0c;包括…

【教程】Linux 安裝 kkFileView 文檔在線預覽項目 及優化

【教程】Linux 安裝 kkFileView 文檔在線預覽項目 官網 kkFileView - 在線文件預覽 (keking.cn) 安裝包 可以直接下載成品 也可以下載source 源碼 自己編譯 kkFileView 發行版 - Gitee.com 打開IDEA 然后先clear 再install 然后在 file-online-preview\server\target 目錄…