目前機(jī)器人使用中需要進(jìn)行 SLAM 建圖,因?yàn)橐苿?dòng)機(jī)器人想要實(shí)現(xiàn)自主行走,核心在于實(shí)現(xiàn)自主定位導(dǎo)航,在自主定位導(dǎo)航技術(shù)中會(huì)涉及到定位、建圖、路徑規(guī)劃等問(wèn)題,而地圖構(gòu)建的好壞將直接影響機(jī)器人的行走路徑。機(jī)器人想要到達(dá)某個(gè)目的地,需要和人類(lèi)繪制地圖一樣,描述環(huán)境、認(rèn)識(shí)環(huán)境的過(guò)程主要就是依靠地圖。
而目前建圖方式有激光雷達(dá)、視覺(jué)建圖、還有深度學(xué)習(xí)等。今天介紹的 cartographer 就屬于激光 slam。主流的激光 SLAM 算法有 hector、gmapping、karto、cartographer 等。
下面簡(jiǎn)單的介紹幾種 SLAM 算法:
1.hector 是一種結(jié)合了魯棒性較好的掃描匹方法 2D_SLAM 方法和使用慣性傳感系統(tǒng)的導(dǎo)航技術(shù)。傳感器的要求較高,高更新頻率小測(cè)量噪聲的激光掃描儀,不需要里程計(jì)。使空中無(wú)人機(jī)與地面小車(chē)在不平坦區(qū)域運(yùn)行存在運(yùn)用的可能性。作者利用現(xiàn)代激光雷達(dá)的高更新率和低距離測(cè)量噪聲,通過(guò)掃描匹配實(shí)時(shí)地對(duì)機(jī)器人運(yùn)動(dòng)進(jìn)行估計(jì)。所以當(dāng)只有低更新率的激光傳感器時(shí),即便測(cè)距估計(jì)很精確,對(duì)該系統(tǒng)都會(huì)出現(xiàn)一定的問(wèn)題。
hector 基于優(yōu)化的算法(解最小二乘問(wèn)題),優(yōu)缺點(diǎn):不需要里程計(jì),但對(duì)于雷達(dá)幀率要求很高 40Hz,估計(jì) 6 自由度位姿,可以適應(yīng)空中或者地面不平坦的情況。初值的選擇對(duì)結(jié)果影響很大,所以要求雷達(dá)幀率較高。?
2.gmapping 是一種基于粒子濾波的激光 SLAM 算法,它已經(jīng)集成在 ROS 中,是移動(dòng)機(jī)器人中使用最多的 SLAM 算法?;诹W訛V波的算法用許多加權(quán)粒子表示路徑的后驗(yàn)概率,每個(gè)粒子都給出一個(gè)重要性因子。但是,它們通常需要大量的粒子才能獲得比較好的的結(jié)果,從而增加該算法的的計(jì)算復(fù)雜性。此外,與 PF 重采樣過(guò)程相關(guān)的粒子退化耗盡問(wèn)題也降低了算法的準(zhǔn)確性。
缺點(diǎn):嚴(yán)重依賴(lài)?yán)锍逃?jì),無(wú)法適應(yīng)無(wú)人機(jī)及地面不平坦的區(qū)域,無(wú)回環(huán)(激光 SLAM 很難做回環(huán)檢測(cè)),大的場(chǎng)景,粒子較多的情況下,特別消耗資源。
3.karto 是基于圖優(yōu)化的 SLAM 算法,用高度優(yōu)化和非迭代 cholesky 矩陣進(jìn)行稀疏系統(tǒng)解耦作為解。圖優(yōu)化方法利用圖的均值表示地圖,每個(gè)節(jié)點(diǎn)表示機(jī)器人軌跡的一個(gè)位置點(diǎn)和傳感器測(cè)量數(shù)據(jù)集,箭頭的指向的連接表示連續(xù)機(jī)器人位置點(diǎn)的運(yùn)動(dòng),每個(gè)新節(jié)點(diǎn)加入,地圖就會(huì)依據(jù)空間中的節(jié)點(diǎn)箭頭的約束進(jìn)行計(jì)算更新。路標(biāo) landmark 越多,內(nèi)存需求越大,然而圖優(yōu)化方式相比其他方法在大環(huán)境下制圖優(yōu)勢(shì)更大。
?karto 采取的是 spa(karto_slam)或 g2o(nav2d),karto 的前端與后端采取的是單線(xiàn)程進(jìn)行。
4.LagoSLAM 是線(xiàn)性近似圖優(yōu)化,不需要初始假設(shè)。基本的圖優(yōu)化 slam 的方法就是利用最小化非線(xiàn)性非凸代價(jià)函數(shù) . 每次迭代, 解決局部凸近似的初始問(wèn)題來(lái)更新圖配置,過(guò)程迭代一定次數(shù)直到局部最小代價(jià)函數(shù)達(dá)到 . (假設(shè)起始點(diǎn)經(jīng)過(guò)多次迭代使得局部代價(jià)函數(shù)最小). 。假設(shè)圖中每個(gè)節(jié)點(diǎn)的相對(duì)位置和方向都是獨(dú)立的,作者求解了一個(gè)等價(jià)于非凸代價(jià)函數(shù)的方程組。為此,提出了一套基于圖論的程序,通過(guò)線(xiàn)性定位和線(xiàn)性位置估計(jì),得到非線(xiàn)性系統(tǒng)的一階近似。
?5.?cartographer 是 google 開(kāi)發(fā)的實(shí)時(shí)室內(nèi) SLAM 項(xiàng)目,cartographer 采用基于 google 自家開(kāi)發(fā)的 ceres 非線(xiàn)性?xún)?yōu)化的方法,cartographer 的亮點(diǎn)在于代碼規(guī)范與工程化,非常適合于商業(yè)應(yīng)用和再開(kāi)發(fā)。并且 cartographer 基于 submap 子圖構(gòu)建全局地圖的思想,能有效的避免建圖過(guò)程中環(huán)境中移動(dòng)物體的干擾。并且 cartographer 支持多傳感器數(shù)據(jù)(odometry、IMU、LaserScan 等)建圖,支持 2D_SLAM 和 3D_SLAM 建圖。
能天然的輸出協(xié)方差矩陣,后端優(yōu)化的輸入項(xiàng)。成本較低的雷達(dá)也能跑出不錯(cuò)的效果。cartographer 是 google 推出的一套基于圖優(yōu)化的 SLAM 算法。
cartographer 算法并沒(méi)有給人驚艷的感覺(jué),但該算法的主要目標(biāo)是實(shí)現(xiàn)低計(jì)算資源消耗,達(dá)到實(shí)時(shí) SLAM 的目的,所以很適合嵌入式端的使用。
這篇文章是介紹 cartographer 在 linuxPC 環(huán)境(Ubuntu16)下進(jìn)行源碼下載進(jìn)行 demo 測(cè)試的教程,本文的前提條件是你的電腦里已經(jīng)安裝了 ROS 以下版本的任意一個(gè):Noetic、Kinetic、Melodic。
算法分析
該算法主要分為兩個(gè)部分,第一個(gè)部分稱(chēng)為 Local SLAM, 該部分通過(guò)一幀幀的 Laser Scan 建立并維護(hù)一系列的 Submap,而所謂的 submap 就是一系列的 Grid Map。當(dāng)再有新的 Laser Scan 中會(huì)通過(guò) Ceres Scan Matching 的方法將其插入到子圖中的最佳位置。但是 submap 會(huì)產(chǎn)生誤差累積的問(wèn)題,因此,算法的第二個(gè)部分,稱(chēng)為 Global SLAM 的部分,就是通過(guò) Loop Closure 來(lái)進(jìn)行閉環(huán)檢測(cè),來(lái)消除累積誤差:當(dāng)一個(gè) submap 構(gòu)建完成,也就是不會(huì)再有新的 laser scan 插入到該 submap 時(shí),算法會(huì)將該 submap 加入到閉環(huán)檢測(cè)中。閉環(huán)檢測(cè)的本質(zhì)也是一個(gè)優(yōu)化問(wèn)題,該優(yōu)化問(wèn)題被表達(dá)成了一個(gè) pixel-accurate match 的形式,解決優(yōu)化問(wèn)題的方法是 Branch-and-Bound Approach.
安裝介紹
cartographer 的安裝主要包括三個(gè)部分:cartographer、cartographer-ros、ceres-solver。其中 cartographer 是計(jì)算的部分,cartographer-ros 是算法在 ROS 中通訊交互數(shù)據(jù)的部分,ceres-solver 谷歌開(kāi)發(fā)的一款用于非線(xiàn)性?xún)?yōu)化的庫(kù),在谷歌的開(kāi)源激光雷達(dá) slam 項(xiàng)目 cartographer 中被大量使用。
安裝的方法有兩種,一種是官網(wǎng)的集成式下載配置,一種是把 cartographer 需要的依賴(lài)部分分別安裝配置。
兩種方式區(qū)別就在于,第一種雖然方便,但是由于網(wǎng)絡(luò)問(wèn)題(你懂的)所以 Google 的相關(guān)文件下載會(huì)失敗,所以就出現(xiàn)了,把依賴(lài)單獨(dú)下載編譯,最后下載 cartographer 進(jìn)行編譯。
官網(wǎng)方式:
1.?安裝 wstool 下載工具、rosdep 和 ninja 編譯工具(ninja 是一個(gè)新型的編譯小工具,用來(lái)替換復(fù)雜的 make,從而實(shí)現(xiàn)快速編譯)
sudo apt-get update
sudo apt-get install -y python-wstool python-rosdep ninja-build
2.?建立一個(gè) wstool 下載+ROS 基本編譯的二合一環(huán)境
mkdir catkin_ws
cd?catkin_ws
wstool?init?src
wstool merge -t src https://raw.githubusercontent.com/googlecartographer/cartographer_ros/master/cartographer_ros.rosinstall
這是 wstool 命令生成 .rosinstall 的文件里面的內(nèi)容,可以看到設(shè)置了 cartographer、cartographer-ros 下載鏈接。
wstool?update?-t?src
靜靜等待下載,速度就取決你對(duì)于 Google 的認(rèn)知。
3. 安裝 proto3.
Protocol Buffers(簡(jiǎn)稱(chēng) Protobuf) ,是 Google 出品的序列化框架,與開(kāi)發(fā)語(yǔ)言無(wú)關(guān),和平臺(tái)無(wú)關(guān),具有良好的可擴(kuò)展性。Protobuf 和所有的序列化框架一樣,都可以用于數(shù)據(jù)存儲(chǔ)、通訊協(xié)議。
src/cartographer/scripts/install_proto3.sh
此外其實(shí)除了 Protobuf 我們還可以配置其他依賴(lài),這些腳本都在這個(gè)目錄,如果編譯過(guò)程中遇到依賴(lài)問(wèn)題就可以去利用腳本去下載。
4.rosdep?init 在安裝 ROS 時(shí)候就安裝過(guò)了,不過(guò)這個(gè)經(jīng)常會(huì)出現(xiàn)問(wèn)題,我之前寫(xiě)過(guò)一篇 ROS 安裝的文件,大家有興趣可以去看看
對(duì)于這個(gè)問(wèn)題,有兩種解決思路:訪問(wèn) DNS 解析環(huán)節(jié)解決或者直接切換軟件源。
DNS 解析環(huán)節(jié)解決:
切換 linux 軟件源:
sudo?rosdep?init
rosdep?update
rosdep?install?--from-paths?src?--ignore-src?--rosdistro=${ROS_DISTRO}?-y
5. 最后一步編譯
catkin_make_isolated --install --use-ninja
source?install_isolated/setup.bash
但是好多時(shí)候因?yàn)橄螺d問(wèn)題,就會(huì)出現(xiàn)這樣那樣的問(wèn)題,所以就出現(xiàn)了下面的方法,把包單獨(dú)下載,然后再進(jìn)行編譯安裝。
注?。涸谖揖幾g cartographer 過(guò)程中,和文章所寫(xiě)這種一氣呵成的感覺(jué)恰恰相反,我編譯了好多次才編譯成功的,而且中間出現(xiàn)各種編譯問(wèn)題,基本都是版本問(wèn)題。所以請(qǐng)大家注意下載各個(gè)分包的版本,切記,切記,切記~
你看我 probuf 版本下載記錄就知道了。
分包編譯方式:
cartographer 分成 6 個(gè)部分,分別是 eigen3.2.9,ceres1.13.0,protobuf 大于 3.0.0,cartographer,cartogpher_ros,abseil。分開(kāi)進(jìn)行編譯:
1.eigen
Eigen 是高級(jí) C ++ 模板標(biāo)頭庫(kù),用于線(xiàn)性代數(shù),矩陣和矢量運(yùn)算,幾何變換,數(shù)值求解器和相關(guān)算法。自 3.1.1 版以來(lái),Eigen 是根據(jù) Mozilla Public License 2.0 許可的開(kāi)源軟件。早期版本是根據(jù) GNU 較寬松通用公共許可證授權(quán)的。
注意警告:cartographer 對(duì) eigen,ceres,protobuf 有嚴(yán)格的版本限制,版本必須嚴(yán)格!?。?/p>
#選擇版本 3.2.9
git clone https://gitlab.com/libeigen/eigen.git
mkdir build
cd build
cmake ..
sudo make install
安裝完成
2.ceres
Ceres solver 是谷歌開(kāi)發(fā)的一款用于非線(xiàn)性?xún)?yōu)化的庫(kù),在谷歌的開(kāi)源激光雷達(dá) slam 項(xiàng)目 cartographer 中被大量使用。
注意:ceres 版本必須是 1.13.0,其它版本與 eigen3.2.9 不匹配
#選擇版本 1.13.0
git clone https://github.com/ceres-solver/ceres-solver.git
mkdir build
cd build
cmake ..
make -j8
sudo make install
編譯過(guò)程中如果出現(xiàn)這個(gè)編譯問(wèn)題:
Failed to find glog
-- Failed to find installed glog CMake configuration, searching for glog build directories exported with CMake.
-- Failed to find an installed/exported CMake configuration for glog, will perform search for installed glog components.
-- Failed to find glog - Could not find glog include directory, set GLOG_INCLUDE_DIR to directory containing glog/logging.h
這個(gè)原因是缺失 glog 庫(kù)(glog 是一個(gè) C++ 日志庫(kù),它提供 C++ 流式風(fēng)格的 API。在安裝 glog 之前需要先安裝 gflags,這樣 glog 就可以使用 gflags 去解析命令行參數(shù)),我們可以用 apt-get install 安裝,也可以下載源碼進(jìn)行編譯安裝 .
apt-get install 安裝:
sudo apt-get install libgoogle-glog-dev
下載源碼進(jìn)行編譯安裝:
git?clone?https://github.com/google/glog.git
cd?glog
mkdir?build
cmake?..
make
sudo make install
再重新進(jìn)行 cere 編譯安裝,又通過(guò)一關(guān)
3.?protobuf
Protocol Buffers(簡(jiǎn)稱(chēng) Protobuf) ,是 Google 出品的序列化框架,與開(kāi)發(fā)語(yǔ)言無(wú)關(guān),和平臺(tái)無(wú)關(guān),具有良好的可擴(kuò)展性。Protobuf 和所有的序列化框架一樣,都可以用于數(shù)據(jù)存儲(chǔ)、通訊協(xié)議。
注意:protobuf 安裝方式特殊,腳本安裝
選擇版本 3.0.0
git clone https://github.com/protocolbuffers/protobuf.git
./autogen.sh
這次也會(huì)遇到 error 問(wèn)題,
第一個(gè) error48: autoreconf: not found
是在不同版本的 tslib 下執(zhí)行 autogen.sh 產(chǎn)生。它們產(chǎn)生的原因一樣,是因?yàn)闆](méi)有安裝 automake 工具, ?用下面的命令安裝好就可以了。
sudo apt-get install autoconf automake libtool
第二個(gè) error 可能是下載問(wèn)題,這邊會(huì)提示你下載失敗,你可以選擇注釋掉,或者使用我提供的第二種編譯方法:
#如遇見(jiàn) Error,prot:443,注釋 autogen.sh 腳本 34 行
./configure
make -j8
sudo make install
sudo ldconfig
#測(cè)試一下 protobuf
protoc --version
#不出意外將會(huì)顯示 libprotoc 3.0.0
第二種編譯方法:
上文說(shuō)到,我們?cè)?cartographer/scripts 目錄下可以找到 cartographer 依賴(lài)文件的下載的腳本,這些的腳本里面還有編譯的選項(xiàng),這時(shí)候我們就可以看下 install_proto3.sh 這個(gè)文件,里面可以看到如下內(nèi)容:
mkdir build
cd build
cmake -G Ninja
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DCMAKE_BUILD_TYPE=Release
-Dprotobuf_BUILD_TESTS=OFF
../cmake
ninja
sudo ninja install
我們直接復(fù)制直接編譯即可。
4.abseil
abseil 是 google 開(kāi)源的 C++通用庫(kù),其目標(biāo)是作為標(biāo)準(zhǔn)庫(kù)的補(bǔ)充。abseil 不但提供了標(biāo)準(zhǔn)庫(kù)沒(méi)有但很常用的功能,也對(duì)標(biāo)準(zhǔn)庫(kù)的一些功能進(jìn)行了增強(qiáng)設(shè)計(jì),使用 abseil 庫(kù)能使程序性能和開(kāi)發(fā)效率都取得不錯(cuò)的提升。
cartographer 對(duì) abseil 沒(méi)有版本要求,但是一定要有。
git clone https://github.com/abseil/abseil-cpp.git
mkdir build
cd build
cmake .. -DCMAKE_CXX_STANDARD=11
make -j8
sudo make install
不過(guò)在后續(xù)編譯 abseil,大家可能會(huì)遇到這個(gè)問(wèn)題
CMake Error at CMakeLists.txt:49 (find_package):
By not providing "FindAbseil.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "Abseil", but
CMake did not find one.
Could not find a package configuration file provided by "Abseil" with any
of the following names:
AbseilConfig.cmake
abseil-config.cmake
Add the installation prefix of "Abseil" to CMAKE_PREFIX_PATH or set
"Abseil_DIR" to a directory containing one of the above files.If "Abseil"
provides a separate development package or SDK, be sure it has been
installed.
不過(guò)沒(méi)事,是因?yàn)?CMakeLists.txt 在進(jìn)行搜尋 absil 中,定義的名稱(chēng)和你編譯 abseil 名稱(chēng)不同,CMakeLists.txt 是大寫(xiě)的,而實(shí)際你編譯安裝后的包名稱(chēng)為小寫(xiě)。
修改如上所示:Abseil 修改為 absl?
5.carographer
注意:carographer 和 cartographer _ros 版本必須對(duì)應(yīng)
mkdir?cartographer
cd?cartographer?&?mkdir?src
cd?src
git?clone?https://github.com/cartographer-project/cartographer.git
git clone https://github.com/cartographer-project/cartographer_ros.git
catkin_make_isolated /*也可以用*/ catkin_make_isolated --install --use-ninja
編譯成功:
建圖開(kāi)發(fā)
現(xiàn)在安裝了 Cartographer 和 Cartographer 的 ROS 集成,官方也提供了一些數(shù)據(jù)集,Deutsches Museum(德意志博物館),這樣我就可以很方便測(cè)試 Cartographer 生成地圖和其他的功能了。
下載示例包(例如德意志博物館的 2D 和 3D 背包系列)到一個(gè)已知的位置
示例位于~/Downloads,并使用 roslaunch 來(lái)調(diào)出演示:
# Download the 2D backpack example bag.
wget -P ~/Downloads https://storage.googleapis.com/cartographer-public-data/bags/backpack_2d/cartographer_paper_deutsches_museum.bag
# Launch the 2D backpack demo.
roslaunch?cartographer_ros?demo_backpack_2d.launch?bag_filename:=${HOME}/Downloads/cartographer_paper_deutsches_museum.bag
# Download the 3D backpack example bag.
wget -P ~/Downloads https://storage.googleapis.com/cartographer-public-data/bags/backpack_3d/with_intensities/b3-2016-04-05-14-14-00.bag
# Launch the 3D backpack demo.
roslaunch cartographer_ros demo_backpack_3d.launch bag_filename:=${HOME}/Downloads/b3-2016-04-05-14-14-00.bag
又會(huì)是下載的問(wèn)題,這些文件又大,下載速度又慢還經(jīng)常失敗,我也是廢了九牛二虎之力下載下來(lái)的。
為了方便大家測(cè)試,大家可以公眾號(hào)后臺(tái)私我,或者添加我微信號(hào),我把我下載好的文件發(fā)給大家。
截圖有限,之前操作都忘記截圖了,導(dǎo)致現(xiàn)在就只有一個(gè)了,大家湊合看了哈。
生成 .pdstream 地圖(等待直到 cartographer_offline_node 完成),
roslaunch cartographer_ros offline_backpack_2d.launch bag_filenames:=${HOME}/Downloads/cartographer_paper_deutsches_museum.bag
然后運(yùn)行純定位:
roslaunch cartographer_ros demo_backpack_2d_localization.launch load_state_filename:=${HOME}/Download/cartographer_paper_deutsches_museum.bag.pbstream bag_filename:=${HOME}/Downloads/cartographer_paper_deutsches_museum.bag
此外還有 turtlebot 的數(shù)據(jù),其實(shí)都是一樣的,大家也可以看一下創(chuàng)客智造的 cartographer_turtlebot 教程。
這就是我分享的 cartographer 的簡(jiǎn)單測(cè)試使用,未來(lái)我會(huì)介紹更加詳細(xì)的 cartographer 使用以及源碼解析。此外如果大家有什么更好的思路,也歡迎分享交流哈。