ROS中階筆記(七):機器人SLAM與自主導航—SLAM功能包的使用
1 機器人必備條件
1.1 硬件要求
(1)差分輪式機器人,可使用twist速度指令控制
$ rosmsg show geometry_msgs/Twist
geometry_msgs/Vector3 linear # linear:xyz方向上的線速度,單位是m/s;
float64 x
float64 y
float64 z
geometry_msgs/Vector3 angular # angular:xyz方向上的角速度,單位是rad/s。
float64 x
float64 y
float64 z
(2)機器人必須安裝激光雷達等測距設備,可以獲取環境深度信息。
(3)最好使用正方形和圓形的機器人,其他外形的機器人雖然可以使用但是效果可能不佳。
1.2 深度信息
1.2.1 激光雷達
$ rosmsg show sensor_msgs/LaserScan # 查看激光雷達消息結構
std_msgs/Header header
uint32 seq
time stamp
string frame_id
float32 angle_min
float32 angle_max
float32 angle_increment
float32 time_increment
float32 scan_time
float32 range_min
float32 range_max
float32[] ranges
float32[] intensities
angle_min:可檢測范圍的起始角度; (—180——180度 )
angle_max:可檢測范圍的終止角度,與angle_min組成激光雷達的可檢測范圍;
angle_increment:相鄰數據幀之間的角度步長;
time_incremen:采集到相鄰數據幀之間的時間步長,當傳感器處於相對運動狀態時進行補償使用。
scan_time:采集一幀數據所需要的視覺;
rang_min:最近可檢測深度的閾值;
rang_max:最遠可檢測深度的閾值;
ranges:一幀深度數據的存儲數組。
intensities:每個激光點的強度
1.2.2 kinect
Kinect等GRB-D攝像頭,也可以通過紅外攝像頭獲取周圍環境的深度信息。
depthimage_to_laserscan功能包:將三維點雲數據轉換為二維激光雷達數據;
<!--depthimage_to_laserscan節點,將點雲深度數據轉換成激光數據-->
<node pkg="depthimage_to_laserscan" type="depthimage_to_laserscan" name="depthimage_to_laserscan" output="screen">
<remap from="image" to="/kinect/depth/image_raw"/>
<remap from="camera_info" to=/kinect/depth/camera_info"/>
<remap froam="scan" to="/scan"/>
<param name="output_frame_id" value="/camera_link"/>
</node>
1.3 里程計信息
$ rosmsg show nav_msgs/odometry
pose:機器人當前位置坐標,包括機器人的XYZ三軸位置與方向參數,以及用於校正誤差的方差矩陣
twist:機器人當前的運動狀態,包括XYZ三軸的線速度與角速度,以及用於校正誤差的方差矩陣。
注意:ROS中所有的坐標系都是右手坐標系。
1.4 仿真環境
在視頻中給出了一個仿真環境:
$ roslaunch mbot_gazebo mbot_laser_nav_gazebo.launch # 啟動仿真環境
# 使用Building Editor創建仿真環境cloister.world
2 SLAM功能包的使用方法
論文參考:https://openslam-org.github.io/gmapping.html
2.1 gmapping
2.1.1 gmapping 功能包
基於激光雷達
Rao-Blackwellized 粒子濾波算法
二維柵格地圖
需要機器人提供里程計信息OpenSlam開源算法
輸出地圖話題:nav_msgs/OccupancyGrid
$ rosmsg show nav_msgs/OccupancyGrid
2.1.2 柵格地圖取值原理
2.1.3 gmapping安裝
$ sudo apt-get install ros-kinetic-gmapping
2.1.4 配置gmapping節點
參考: http://wiki.ros.org/gmapping
catkin_ws/src/mbot_navigation/launch/gmapping.launch
<launch>
<arg name="scan_topic" default="scan" />
<node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen" clear_params="true">
<param name="odom_frame" value="odom"/>
<param name="map_update_interval" value="5.0"/>
<!-- Set maxUrange < actual maximum range of the Laser -->
<param name="maxRange" value="5.0"/>
<param name="maxUrange" value="4.5"/>
<param name="sigma" value="0.05"/>
<param name="kernelSize" value="1"/>
<param name="lstep" value="0.05"/>
<param name="astep" value="0.05"/>
<param name="iterations" value="5"/>
<param name="lsigma" value="0.075"/>
<param name="ogain" value="3.0"/>
<param name="lskip" value="0"/>
<param name="srr" value="0.01"/>
<param name="srt" value="0.02"/>
<param name="str" value="0.01"/>
<param name="stt" value="0.02"/>
<param name="linearUpdate" value="0.5"/>
<param name="angularUpdate" value="0.436"/>
<param name="temporalUpdate" value="-1.0"/>
<param name="resampleThreshold" value="0.5"/>
<param name="particles" value="80"/>
<param name="xmin" value="-1.0"/>
<param name="ymin" value="-1.0"/>
<param name="xmax" value="1.0"/>
<param name="ymax" value="1.0"/>
<param name="delta" value="0.05"/>
<param name="llsamplerange" value="0.01"/>
<param name="llsamplestep" value="0.01"/>
<param name="lasamplerange" value="0.005"/>
<param name="lasamplestep" value="0.005"/>
<remap from="scan" to="$(arg scan_topic)"/>
</node>
</launch>
2.1.5 啟動gmapping演示(激光雷達)
分別開啟三個終端運行以下命令:
$ roslaunch mbot_gazebo mbot_laser_nav_gazebo.launch # 啟動仿真環境
$ roslaunch mbot_navigation gmapping_demo.launch # 啟動建圖節點,灰色地圖建成,黑色障礙物
$ roslaunch mbot_teleop mbot_teleop.launch #啟動鍵盤控制節點
建圖完畢,保存地圖
$ rosrun map_server map_saver -f cloister_gmapping
# cloister_gmapping是文件名的意思,是自己保存文件名的意思
# 保存的路徑在當前/home文件夾下,有兩個文件.pgm和.yaml
2.1.6 啟動gmapping(kinect)
建圖效果不佳(不推薦)
$ roslaunch mbot_gazebo mbot_kinect_nav_gazebo.launch
$ roslaunch mbot_navigation gmapping_demo.launch
$ roslaunch mbot_teleop mbot_teleop.launch
2.2 hector_slam
2.2.1 hector_slam功能包
基於激光雷達
高斯牛頓方法
二維柵格地圖
不需要里程計數據
輸出地圖話題:
nav_msgs/OccupancyGrid
2.2.2 安裝hector_slam
$ sudo apt-get install ros-kinetic-hector-slam
2.2.3 配置hector_mapping節點
參數說明可參考:http://wiki.ros.org/hector_slam
catkin_ws/src/mbot_navigation/launch/hector.launch
<launch>
<node pkg = "hector_mapping" type="hector_mapping" name="hector_mapping" output="screen">
<!-- Frame names -->
<param name="pub_map_odom_transform" value="true"/>
<param name="map_frame" value="map" />
<param name="base_frame" value="base_footprint" />
<param name="odom_frame" value="odom" />
<!-- Tf use -->
<param name="use_tf_scan_transformation" value="true"/>
<param name="use_tf_pose_start_estimate" value="false"/>
<!-- Map size / start point -->
<param name="map_resolution" value="0.05"/>
<param name="map_size" value="2048"/>
<param name="map_start_x" value="0.5"/>
<param name="map_start_y" value="0.5" />
<param name="laser_z_min_value" value = "-1.0" />
<param name="laser_z_max_value" value = "1.0" />
<param name="map_multi_res_levels" value="2" />
<param name="map_pub_period" value="2" />
<param name="laser_min_dist" value="0.4" />
<param name="laser_max_dist" value="5.5" />
<param name="output_timing" value="false" />
<param name="pub_map_scanmatch_transform" value="true" />
<!-- Map update parameters -->
<param name="update_factor_free" value="0.4"/>
<param name="update_factor_occupied" value="0.7" />
<param name="map_update_distance_thresh" value="0.2"/>
<param name="map_update_angle_thresh" value="0.06" />
<!-- Advertising config -->
<param name="advertise_map_service" value="true"/>
<param name="scan_subscriber_queue_size" value="5"/>
<param name="scan_topic" value="scan"/>
</node>
</launch>
2.2.4 啟動hector_slam演示
分別開啟三個終端運行以下命令:
$ roslaunch mbot_gazebo mbot_laser_nav_gazebo.launch # 動一個gazebo仿真節點
$ roslaunch mbot_navigation hector_demo.launch # hector建圖節點
$ roslaunch mbot_teleop mbot_teleop.launch # 啟動一個鍵盤控制節點
第一個節點啟動了gazebo仿真,它使用仿真的雷達給出了一個scan掃描數據;而后下面的節點訂閱了這個數據並進行處理,最后得到一個二維柵格地圖。
hector這個算法有一個很大的問題,就是在於它的自定位,它利用自身的激光雷達數據進行定位,如果上一次的掃描數據與下一次的掃描數據基本一致的話,它就很難確定自己是否在運動,例如當我給一個足夠大的空間,這里有一條沒有任何特征點的長廊,長度遠遠超過激光掃描的最大距離時,hector基本就失去了建圖的能力。
2.3 cartographer
2.3.1 cartographer功能包
2016年10月5日,谷歌開源
基於圖網絡的優化方法
二維或三維條件下的定位及建圖功能
設計目的是在計算資源有限的情況下,實時獲取相對較高精度的2D地圖
主要基於激光雷達
后續會支持更多傳感器和機器人平台,同時不斷增加新的功能。
2.3.2 cartographer安裝
方法一:(新方法)
sudo apt-get update
sudo apt-get install ros-<your ros version>-cartographer* # 安裝全部關於cartographer的包
方法二:原來的方法(有好處)
cartographer功能功能包沒有集成到ROS的軟件源里面,所以需要采用源碼編譯方式進行安裝。為了不與其他安裝包沖突,最好為cartographer專門創建一個工作空間,這里我們創建了一個工作空間catkin_google_ws:
1、安裝工具:
$ sudo apt-get update
$ sudo apt-get install -y python-wstool python-rosdep ninja-build
2、初始化工作空間:
$ mkdir google_ws # 創建工作空間,名稱為google_ws
$ cd google_ws
$ wstool init src
3、設置下載地址(掛VPN最好)
在新建的工作空間下輸入下邊指令:
# 如果這一步錯誤,見下面方法一、方法二
$ wstool merge -t src https://raw.githubusercontent.com/googlecartographer/cartographer_ros/master/cartographer_ros.rosinstall
$ wstool update -t src
說明:配置Cartographer需要三個包,分別是:Cartographer、Cartographer_ros 和ceres-solver。
方法一:
# 如果無法從google取出代碼可以從github提取code:
# 在~/google_ws/src下目錄下面ctrl+h打開隱藏文件夾,修改里面第三個包的下載地址:
https://github.com/ceres-solver/ceres-solver.git
方法二:
# 輸入完第一個命令后需要改文件的下載地址,另起終端輸入:
$ gedit google_ws/src/.rosinstall
# 將最后一個git來源網址由https://ceres-solver.googlesource.com/ceres-solver.git改為https://github.com/ceres-solver/ceres-solver.git 如該果可以掛VPN可以不改。
4、安裝功能包依賴
# 安裝 proto3.sh
進入protobuf的release版本下載頁,link:https://github.com/protocolbuffers/protobuf/releases
# 在google_ws目錄下
# protobuf的下載太慢,可以在官網手動下載好,放到cartographer目錄下(和src同級,具體操作如下)
$ src/cartographer/scripts/install_proto3.sh
# 安裝 deb 依賴,出現錯誤可以忽略
$ sudo rosdep init
$ rosdep update
$ rosdep install --from-paths src --ignore-src --rosdistro=${kinetic} -y
5、編譯功能包
$ catkin_make_isolated --install --use-ninja # 在google_ws目錄下,編譯
6、在當前終端,設置環境變量
source install_isolated/setup.bash #設置環境變量,在當前終端中設置環境變量,只能在當前終端查找
建議把該句source命令直接寫入系統的bashrc環境里
$ vim ./bashrc
source install_isolated/setup.bash # 然后把該句source命令添加到最后一行即可
2.3.3 啟動2D、3D 演示
# 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
啟動Revo LDS demo演示
啟動PR2 demo填示
wget -P ~/Downloads https://storage.googleapis.com/cartographer-public-data/bags/pr2/2011-09-15-08-32-46.bag
roslaunch cartographer_ros demo_pr2.launch bag_filename:=~/Downloads/2011-09-15-08-32-46.bag
2.3.4 把cartographer功能包運行到自己的機器人上
由於傳感器的rostopic不同,我們需要對cartographer訂閱的名稱進行修改,需要在launch文件中進行修改,但是修改后發現沒有任何作用,這是因為修改后需要重新按照上面的流程進行編譯安裝,這個可能是因為在安裝的時候其實已經把launch文件安裝到系統中了,所以我們調用的時候還是調用系統中的launch文件
1、配置cartographer節點
mbot_navigation/launch/cartographer_demo_rplidar.launch
2、參數配置
mbot_navigation/config/rplidar.lua
2.3.5 啟動cartographer仿真
catkin_make_isolated --install--use-ninja
roslaunch mbot_ gazebo mbot_laser_nav_gazebo.launch
roslaunch cartographer_ros cartographer_demo_rplidar.launch
roslaunch mbot_teleop mbot_teleop.launch
2.4 ORB_SLAM
2.4.1 ORB_SLAM功能包
基於特征點的實時單目SLAM系統
實時解算攝像機的移動軌跡
構建三維點雲地圖
不僅適用於手持設備獲取的一組連續圖像,也可以應用於汽車行駛過程中獲取的連續圖像Raul Mur-Artal,J.M.M.Montiel和Juan D.Tardos於2015年發表在IEEE Transactions on Robotics上
2.4.2 ORB_SLAM2安裝
1、安裝工具&下載源碼:
sudo apt-get install libboost-all-dev libblas-dev liblapack-dev
git clone https://github.com/raulmur/ORB_SLAM2.git ORB_SLAM2 # 克隆到home下
2、安裝eigen3.2.10
去官網下載:http://eigen.tuxfamily.org/index.php?title=Main_Page
解壓源碼包,並進入目錄:
mkdir build
cd build
cmake ..
make
sudo make install
3、編譯g2o
cd ~/ORB_SLAM2/Thirdparty/g2o/
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
4、編譯DBoW2
cd ~/ORB_SLAM2/Thirdparty/DBoW2/
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
5、編譯Pangolin
sudo apt-get install libglew-dev
git clone https://github.com/stevenlovegrove/Pangolin.git
cd Pangolin
mkdir build && cd build
cmake ..
cmake --build .
6、編譯ORM_SLAM
cd ~/ORB_SLAM2
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make
7、編譯功能包(配置ROS環境)
# 首先修改.bashrc文件
$ cd ~
$ gedit .bashrc
# 打開.bashrc文件在最后一行加入
source ~/ORB_SLAM2/Examples/ROS/ORB_SLAM2/build/devel/setup.bash
$ source ~/.bashrc
$ export ROS_PACKAGE_PATH=${ROS_PACKAGE_PATH}:/home/ggk/ORB_SLAM2/Examples/ROS
$ cd ~/ORB_SLAM2
$ chmod +x build_ros.sh
$ ./build_ros.sh
第7步,編譯功能包 出現的問題:
解決方法:
修改 ~/ORB_SLAM2/Examples/ROS/ORB_SLAM2/CMakeLists.txt,添加 -lboost_system
2.4.3 啟動單目SLAM示例(基於數據包)
KITTI:http://www.cvlibs.net/datasets/kitti/eval_odometry.php,是室外,雙目
1、首先下載數據包TUM:這個主要是室內,單目和RGB-D
https://vision.in.tum.de/data/datasets/rgbd-dataset/download#freiburg1_desk
在ORB-SLAM2下新建文件夾Data,把測試的數據解壓在這里。
TUM數據集分為相機fr1,fr2,fr3,對應TUM1-3.yaml;
一般第一次測試用fr1/xyz這個數據集,這個就是x,y,z方向來回動,用來檢測一下系統出沒出什么問題。
其他的數據看名字就知道,比如desk就是在桌子附近來回轉,room就是在房間里面掃來掃去。
值得注意的是,運行其他數據集的時候,單目不一定能追蹤成功,在台式機上能成功的在虛擬機上也不一定能成功,這就需要我們進行一些調整,比如調整初始化需求數量等,這個關系到對SLAM系統的理解。
2、分別打開三個終端運行下面的三個命令:
$ roscore
# 進入ORB_SLAM2目錄下啟動Mono功能節點。
# 看到開啟的等待數據的可視化建圖界面
$ rosrun ORB_SLAM2 Mono Vocabulary/ORBvoc.txt Examples/ROS/ORB_SLAM2/Asus.yaml
# 進入數據包所在目錄下,運行命令
# /camera/image_raw表示播放的數據要發布的話題名稱,此時可以在界面中看到建圖的效果
$ rosbag play rgbd_dataset_freiburg1_desk.bag /camera/rgb/image_color:=/camera/image_raw
PATH_TO_VOCABULARY:算法參數文件,在ORB_SLAM2/Vocabulary中,將其中的壓縮包解壓即可;
PATH_TO_SETTINGS_FILE:相機參數設置文件,需要對camera進行標定產生,也可以使用ORB_SLAM2/Examples/ROS/ORB_SLAM2中已有的設置文件Asus.yaml。
2.4.4 啟動AR示例(基於數據包)
$ roscore
# 進入ORB_SLAM2目錄下啟動Mono功能節點。
# 看到開啟的等待數據的可視化建圖界面
$ rosrun ORB_SLAM2 MonoAR Vocabulary/ORBvoc.txt Examples/ROS/ORB_SLAM2/Asus.yaml
# 進入數據包所在目錄下,運行命令
# /camera/image_raw表示播放的數據要發布的話題名稱,此時可以在界面中看到建圖的效果
$ rosbag play rgbd_dataset_freiburg1_desk.bag /camera/rgb/image_color:=/camera/image_raw
點擊界面Insert Cube,看到正方形插入進來,展示AR效果
2.4.5 啟動ORB_SLAM示例(真實攝像頭)
$ roslaunch mbot_navigation usb_cam_remap.launch
# 進入ORB_SLAM2目錄下啟動Mono功能節點。
# 看到開啟的等待數據的可視化建圖界面
$ rosrun ORB_SLAM2 Mono Vocabulary/ORBvoc.txt Examples/ROS/ORB_SLAM2/Asus.yaml
2.4.6 啟動AR示例(真實攝像頭)
攝像頭要運動起來,來完成地圖構建
$ roslaunch mbot_vision usb_cam_remap.launch
# 進入ORB_SLAM2目錄下啟動Mono功能節點。
# 看到開啟的等待數據的可視化建圖界面
$ rosrun ORB_SLAM2 MonoAR Vocabulary/ORBvoc.txt Examples/ROS/ORB_SLAM2/Asus.yaml
3 參考資料
2.3 參考資料
Compiling Cartographer ROS
https://google-cartographer-ros.readthedocs.io/en/latest/compilation.html#building-installation
ROS slam-google cartographer編譯和demo運行
https://blog.csdn.net/x_r_su/article/details/52927564
Google Cartographer安裝教程
https://blog.csdn.net/xmy306538517/article/details/81455625
ubuntu18.04配置cartographer