VIO-slam 系統構建

文章目錄

  • 目錄

    文章目錄

    前言

    一、VIO系統數據的獲取:圖像傳感器選型、IMU傳感器選型

    二、建立linux系統+ROS環境

    三、如何讀取圖像數據

    四、如何讀取IMU傳感器數據

    五、標定圖像和IMU數據的外參、相機的內參

    六、移植VINS-MONO或者VINS-FUSION:主要調試獲取圖像和imu的訂閱數據

    七、實踐VIO中遇到的問題

    總結


前言

分享一些自己學習+實踐 VIO視覺融合慣導的定位算法系統工程化過程

一、VIO系統數據的獲取:圖像傳感器選型、IMU傳感器選型

二、建立linux系統+ROS環境

三、如何讀取圖像數據

四、如何讀取IMU傳感器數據

五、標定圖像和IMU數據的外參、相機的內參

六、移植VINS-MONO或者VINS-FUSION:主要調試獲取圖像和imu的訂閱數據

七、實踐VIO中遇到的問題

1、在運行vins-mono中發現,Eigen報錯,vins_estimator: /usr/include/eigen3/Eigen/src/Core/DenseStorage.h:109: Eigen::internal::plain_array<T, Size, MatrixOrArrayOptions, 16>::plain_array() [with T = double; int Size = 270; int MatrixOrArrayOptions = 0]: Assertion `(internal::UIntPtr(eigen_unaligned_array_assert_workaround_gcc47(array)) & (15)) == 0 && "this assertion is explained here: " "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" " **** READ THIS WEB PAGE !!! ****"' failed.

解決問題:

1)查閱Eigen官方文檔找到問題所在。原因是Eigen庫為了使用SSE加速,在內存上分配了128位的指針,涉及字節對齊問題,該問題在編譯時不會報錯,只在運行時報錯。

原因1:類中有Eigen類型的成員變量
class Foo
{
? //...
? Eigen::Vector2d v;
? //...
};
//...
Foo *foo = new Foo;
?在生成定長的Matrix或Vector對象時,需要開辟內存,調用默認構造函數,通常x86下的指針是32位,內存位數沒對齊就會導致程序運行出錯。而對于動態變量(例如Eigen::VectorXd)會動態分配內存,因此會自動地進行內存對齊。

解決方法:在public下寫一個宏EIGEN_MAKE_ALIGNED_OPERATOR_NEW

class Foo
{
? ...
? Eigen::Vector2d v;
? ...
public:
? EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
...
Foo *foo = new Foo;
這個宏在new一個對象時會總是返回一個對齊的指針。

如果想要通過模板參數來定義一個定長變量,可以使用宏EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)。若NeedsToAlign是True,則進行對齊運算;若NeedsToAlign為False,則采用默認的對齊方式。

template<int n> class Foo
{
? typedef Eigen::Matrix<float,n,1> Vector;
? enum { NeedsToAlign = (sizeof(Vector)%16)==0 };
? ...
? Vector v;
? ...
public:
? EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
};
...
Foo<4> *foo4 = new Foo<4>; // foo4 is guaranteed to be 128bit-aligned
Foo<3> *foo3 = new Foo<3>; // foo3 has only the system default alignment guarantee
如果覺得到處放EIGEN_MAKE_ALIGNED_OPERATOR_NEW太過繁瑣,還可以采用以下的兩種措施。

1)禁用對齊

class Foo
{
? ...
? Eigen::Matrix<double,2,1,Eigen::DontAlign> v;
? ...
};
這種方法在將變量賦值到一個臨時的對齊向量時,仍然有可能重新啟用矢量化。

void Foo::bar()
{
? Eigen::Vector2d av(v);
? // use av instead of v
? ...
? // if av changed, then do:
? v = av;
}
2)私有結構體

將定長的對象存儲到私有結構體中,在構建主對象時固定分配內存。這里的明顯優勢是類Foo在對齊問題上保持不變。缺點是無論如何都需要堆分配。

struct Foo_d
{
? EIGEN_MAKE_ALIGNED_OPERATOR_NEW
? Vector2d v;
? ...
};
struct Foo {
? Foo() { init_d(); }
? ~Foo() { delete d; }
? void bar()
? {
? ? // use d->v instead of v
? ? ...
? }
private:
? void init_d() { d = new Foo_d; }
? Foo_d* d;
};
?原因2:STL容器中的元素是Eigen數據結構
使用Eigen::aligned_allocator告訴容器進行16字節對齊。

std::map<int, Eigen::Vector4f>
將其改成

std::map<int, Eigen::Vector4f, std::less<int>,?
? ? ? ? ?Eigen::aligned_allocator<std::pair<const int, Eigen::Vector4f> > >
另一種方法,使用宏EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION

#include<Eigen/StdVector>
/* ... */
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Matrix2d)
std::vector<Eigen::Vector2d>
?原因3:通過值傳遞定長Eigen對象
void func(Eigen::Vector4d v);
在c++中使用值傳遞都是一個很糟糕的選項,意味著很多無用拷貝,這兒還會造成程序崩潰。通常采用引用傳遞:

void my_function(const Eigen::Vector2d& v);
?原因4:編譯器對棧對齊做了錯誤假設(例如Windows上的GCC)
void foo()
{
? Eigen::Quaternionf q;
? //...
}
?GCC中編譯器假設堆棧是16字節對齊,但在Windows中堆棧只能保證4字節對齊。當從另一個線程或另一個編譯器編譯的二進制文件調用函數時,可能會破壞堆棧對齊。

有三種方法可供參考:

1)局部

__attribute__((force_align_arg_pointer)) void foo()
{
? Eigen::Quaternionf q;
? //...
}
2)全局

-mincoming-stack-boundary=2
相當于告訴GCC堆棧需要2*2=4字節對齊

3) 全局

-mstackrealign
相當于向所有函數添加force_align_arg_pointer

如果不想要進行向量化,可以在編譯時使用EIGEN_DONT_ALIGN_STATICALLY選項禁用所有16字節靜態對齊,但保持16位堆對齊。或者同時使用EIGEN_DONT_VECTORIZE和EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT,這保持了16位的對齊代碼,但不支持向量化。
?

2、ubuntu 16.4 的 ros kinetic 依賴的是boost158版本,使用167版本編譯程序,就會報?or -rpath-link)
/usr/bin/ld: warning: libboost_thread.


總結

1、基礎矩陣、單一性矩陣、本征矩陣為什么能計算出相機的旋轉和平移;其原理是什么
2、相機旋轉的時候為什么能用IMU進行測量其旋轉的角度

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

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

相關文章

MySQL5.7多源復制的實驗

MySQL5.7多源復制的實驗 node1: 192.168.2.171 master1 node2: 192.168.2.172 slave node3: 192.168.2.170 master2 node2上執行&#xff1a; change master to master_host192.168.2.171, master_userrpl, master_passwordAbcd1234, master_port3306, master_log…

最優化課堂筆記04:非線性規劃(考點4-5例題)

目錄 4.1 多元函數的泰勒展開 4.2方向導數與梯度 4.2.1方向導數 n元函數在點沿特定方向的方向導數 4.2.2梯度 4.3二次函數及正定矩陣 4.4凸函數與凸規劃 4.4.1凸函數 4.4.2凸規劃 4.4無約束優化問題的極值條件 4.5約束優化問題的極值條件&#xff08;重點考點&#x…

k近鄰算法C++二維情況下的實現

k近鄰算法C二維實現 這是一個k近鄰算法的二維實現&#xff08;即K2的情況&#xff09;。 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <cmath> u…

java——對象學習筆記

1.面向對象&#xff08;OOP&#xff09;的三大特性 對象的行為&#xff08;behavior&#xff09;&#xff1a;可以對對象施加哪些操作&#xff0c;或者可以對對象施加哪些方法。 對象的狀態&#xff08;state&#xff09;&#xff1a;當施加那些方法后&#xff0c;對象如何響應…

C++獲取一段算法程序耗時方法

1、添加頭文件庫#include <chrono> 2、代碼編寫 std::chrono::steady_clock::time_point t1 std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point t2 std::chrono::steady_clock::now(); std::chrono::duration<double> time_used12 st…

cisco 動態路由協議RIP筆記

動態路由協議RIP router(config)#router rip 啟動RIP進程 router(config-router)#network 1.0.0.0 宣告主網絡號 router(config-router)#version 2 使用版本v2 router(config-router)#no auto-summary 關閉路由匯總功能 本文轉自 meteor_hy 51CTO博客&#xff0c;原文鏈接&a…

EBS FORM開發問題總結

1&#xff0c;form是基于單表視圖建立的&#xff0c;沒有寫on-insert此類的觸發器。在視圖上加了個rownum列結果導致form上的列不能更新 據說此種情形下的form會判斷視圖上的列是否屬于基表&#xff0c;不屬于的話會導致整個塊不能更新。 2&#xff0c;在form界面上顯示行號 在…

Django 學習資源

相關的分享&#xff1a; 開發者頭條&#xff1a;http://toutiao.io/search?utf8%E2%9C%93&qdjango 極客頭條及Django資訊&#xff1a;http://www.csdn.net/tag/django/news 一些優秀的文章&#xff1a; Django 常用測試方法&#xff1a;https://messense.me/django-common…

orb-slam2在PC和ARM上運行

ORBSLAM2的編譯與運行 環境&#xff1a;Ubuntu16.04 ORBSLAM2 &#xff08;1&#xff09;安裝工具 sudo apt-get install cmake sudo apt-get install git sudo apt-get install gcc g (2) 安裝pangolin 安裝依賴項&#xff1a; sudo apt-get install libglew-dev sudo ap…

爛泥:智能DNS使用與配置

公司的業務現在已經擴展到海外&#xff0c;對外提供的統一接口都是通過域名來解析的&#xff0c;但是海外用戶訪問國內接口的話&#xff0c;你懂的&#xff0c;很慢的。為了提高域名解析的速度&#xff0c;打算使用智能DNS功能&#xff0c;來解決海外用戶域名解析慢的問題。 PS…

現代制造工程——考試復習01

第一部分 金屬切削原理 1.切削過程中工件上的加工表面分類 2.不同工藝的工件和刀具的相對關系 3.不同工藝的主運動和進給運動的方向 4.思考&#xff1a;主運動一般只有一個&#xff0c;但是進給運動一個也可以是多個 5.切削三要素&#xff08;必考&#xff09; 6.思考&#x…

C++,C++編程,Windows編程,MFC

編程  我們日常生活中接觸到的電子類產品中的應用都是由編程而來  為什么編程&#xff0c;偷懶  我們通過編程驅使&#xff08;指揮&#xff0c;命令&#xff09;的是電信號  為什么上面說編程是偷懶&#xff0c;電的發現&#xff0c;給人們帶來了便利&#xff0c;人們…

orb-slam2 代碼邏輯梳理

1、開發大型C系統&#xff0c;可以首先從頭文件開始&#xff1b;先把頭文件的各種接口定義好&#xff1b;含義定義好&#xff1b;實現的時候只管內部實現就行&#xff0c;不需要管理外部的邏輯交互 2、定義在類中的變量&#xff0c;可以在前面加個小標志&#xff0c;mcamerMati…

eclipse中java項目轉換為web項目

123456789101112經常在eclipse中導入web項目時&#xff0c;出現轉不了項目類型的問題&#xff0c;導入后就是一個java項目&#xff0c;有過很多次經歷&#xff0c;今天也有同事遇到類似問題&#xff0c;就把這個解決方法記下來吧&#xff0c;免得以后再到處去搜索。解決步驟&am…

讓執行程序引用特定目錄下的Dll

當寫一個軟件&#xff0c;特別是大型的軟件&#xff0c;經常會引用一些第三方的類庫&#xff0c;再加上一些自己的項目&#xff0c;如果這些Dll全都放在主目錄下的話&#xff0c;會顯得比較雜亂。我們希望將項目的類庫分類成文件夾存放&#xff0c;這樣才顯得比較整潔。 解決方…

Angularjs controller之間的通信

剛剛看了網上的一些關于控制器之間的通信&#xff1b;然后結合自己項目做了一些&#xff0c;這里主要做的是二個同級之間的controller通信。 Html&#xff1a; 1 <html>2 <script src"http://apps.bdimg.com/libs/angular.js/1.3.9/angular.min.js"><…

最優化課堂筆記05——一維最優化方法(含重點:黃金分割法)

5-1 一維搜索區間的確定 搜索區間只是適用于單峰區間 、 例子 5.2 黃金分割法&#xff08;重點&#xff09; 上面的a與b都會跟著計算的推進而變化的 例子重點 5.3二次插值法 總結&#xff1a; 5.4 切線法&#xff08;牛頓法&#xff09; 5.5 割線法&#xff08;不需要計算導數&…

C++中靜態成員數據初始化問題

C中靜態成員數據初始化問題 1、靜態成員變量&#xff1a;定義為靜態成員意味著它能被所有的實例化對象所共有&#xff0c;其修改值為該類的其它所有實例所見。 下面看一個例子 class people { public:people(int i):id(i){num;} private:static int num;int id; }; num為靜…

moss2010 sharepoint 2010配置人員搜索

配置人員搜索 http://technet.microsoft.com/zh-cn/library/ee721049.aspx 相關補丁 http://support.microsoft.com/kb/2276339/zh-cn Search Configuration in SharePoint 2010 http://blog.concurrency.com/sharepoint/search-configuration-in-sharepoint-2010/ SharePoint …