autolabor-m1-doc/navigationKit/development/slamintro.md

246 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 激光SLAM
## 目录
* SLAM介绍
* 基于激光SLAM的机器人自主导航
* Autolabor M1 SLAM 导航功能详解
* 2D SLAM 实现原理
* 3D SLAM 实现原理
## SLAM介绍
**SLAM**,全称是 Simultaneous Localization and Mapping同时定位与地图构建。
SLAM 技术解决的是,我在哪里?(**定位**Localization )我周围是什么样?(**建图**Mapping这两个问题。
移动设备从未知环境中的某一点开始运动,根据传感器获取到的数据,即时计算获取传感器的位置并绘制周围的环境。
![](imgs/slamintro1.jpg)
SLAM 的应用很广泛,有扫地机器人、无人驾驶汽车、无人机,三维场景重建等。
根据使用传感器不同SLAM的可分为激光SLAM和视觉SLAMVSLAM本文介绍的是激光SLAM对视觉SLAM相关知识感兴趣的可以[看这里](/usedoc/navigationKit2/version_two/development/vslamintro)。
## 基于激光SLAM的机器人自主导航
激光SLAM导航指的是使用激光雷达采集的数据进行建图与定位SLAM并在构建的环境地图中自动导航规划+控制)。
![](imgs/slamintro2.png)
地图构建完成后,给出目标点,根据当前位置信息与已知环境地图规划出可行走路径,控制机器人运动,最终达到目标点。
![](imgs/slamintro3.png)
以上只是简单概述了机器人导航的流程,但 SLAM 与 路径规划/Planning 都是很复杂的内容,在此不做过多的探讨。
## Autolabor M1 SLAM 导航功能详解
Autolabor SLAM 导航使用的是谷歌开源的 [Cartographer](https://github.com/googlecartographer/cartographer_ros)支持多平台和传感器配置提供2D和3D实时同步定位与建图使用回环检测消除建图产生的累积误差建图效果更好在国内外众多机器人应用上得到了广泛使用。
> Cartographer is a system that provides real-time simultaneous localization and mapping (SLAM) in 2D and 3D across multiple platforms and sensor configurations.
![](imgs/slamintro4.gif)
### 2D SLAM 实现原理
#### 传感器介绍
2D SLAM 用到的传感器有:
* 单线激光雷达x2安装在M1内部前后位置
* 编码器/轮速里程计x2安装在车体内部前侧
![](imgs/software_intro_6.png)
#### 2D SLAM 建图
![](imgs/software_intro_1.jpg)
| 步骤 | 输入数据 | 操作 | 输出数据 | 使用ROS包 |
|-----|------------------|--------------------------------------------|----------------|-------------------------------------------------------------------------------------------------------|
|1 | 左编码器数据 右编码器数据 | 使用运动模型计算编码器数据得到符合ROS标准的里程计数据| 里程计数据| [autolabor_pro_driver](http://www.autolabor.com.cn/usedoc/ap1/sendCommand)|
|2 | 前雷达数据 后雷达数据 | 过滤并融合前后激光雷达采集的数据,得到机器人周围环境点云数据| 雷达点云数据 | [cartographer_ros](https://google-cartographer-ros.readthedocs.io/en/latest/) [laser_filters](http://wiki.ros.org/laser_filters) |
|3 | 里程计数据 点云数据 | 点云匹配| 相对位姿数据 子地图数据 | [cartographer_ros](https://google-cartographer-ros.readthedocs.io/en/latest/)|
|4 | 相对位姿数据 子地图数据 | 回环检测,得到子地图拼接的全地图数据 | 地图数据 | [cartographer_ros](https://google-cartographer-ros.readthedocs.io/en/latest/)|
Cartographer 2D 建图 launch配置示例
```
<!-- 建图节点 -->
<node name="cartographer_node" pkg="cartographer_ros"
type="cartographer_node" args="
-configuration_directory $(find autolabor_navigation_launch)/params/cartographer
-configuration_basename second_generation_mapping.lua"
output="screen">
</node>
<node name="cartographer_occupancy_grid_node" pkg="cartographer_ros" type="cartographer_occupancy_grid_node" args="-resolution 0.05" />
```
#### 2D SLAM 导航
![](imgs/software_intro_2.jpg)
| 步骤 | 输入数据 | 操作 | 输出数据 | 使用ROS包 |
|-----|------------------|--------------------------------------------|----------------|-------------------------------------------------------------------------------------------------------|
|1 | 左编码器数据 右编码器数据 | 使用运动模型计算编码器数据得到符合ROS标准的里程计数据| 里程计数据| [autolabor_pro_driver](http://www.autolabor.com.cn/usedoc/ap1/sendCommand)|
|2|前雷达数据 后雷达数据 里程计数据 地图数据|将机器人的实时数据与已构建的地图进行匹配|当前机器人在环境中的位姿| [cartographer_ros](https://google-cartographer-ros.readthedocs.io/en/latest/)|
|3| 目标机器人位姿| 给机器人制定一个目标点| |[move_base](http://wiki.ros.org/move_base/)|
|4| 当前机器人位姿 地图数据 目标机器人位姿| 根据机器人当前位姿与地图数据,进行全局规划路线| 路径数据(初步预估导航路线) |[global_planner(dijkstra) ](http://wiki.ros.org/global_planner)|
|5| 路径数据 地图数据 前雷达数据 后雷达数据 | 根据规划路径开始导航,进行过程中随着实际环境、障碍物变化,进行局部路径规划,实时避障| 局部路径规划 避障 |[costmap_2d ](http://wiki.ros.org/cost_map)[teb_local_planner](http://wiki.ros.org/teb_local_planner)|
|6| 速度信息 /cmd_vel | 向底层发送速度命令 | |[move_base](http://wiki.ros.org/move_base/)|
说明:
1. move_base, global_planner(dijkstra), costmap_2d 这些功能包(package)都从属于
Navigation 导航这个大的功能包集teb_local_planner 是navigation包的一个插件。
2. 机器人导航过程中,会按照周围环境、实时障碍物做调整不断规划调整路径,向底层发布指令,步骤五和六是一个多次的过程,并非一次就结束了。
Cartographer 2D 导航 launch配置示例
```
<!-- 定位模块 -->
<node name="cartographer_node" pkg="cartographer_ros"
type="cartographer_node" args="
-configuration_directory $(find autolabor_navigation_launch)/params/cartographer
-configuration_basename second_generation_location.lua
-load_state_filename $(find autolabor_navigation_launch)/map/map.pbstream"
output="screen">
</node>
<node name="cartographer_occupancy_grid_node" pkg="cartographer_ros"
type="cartographer_occupancy_grid_node" args="
-resolution 0.05
--noinclude_unfrozen_submaps"
output="screen">
</node>
<node pkg="cartographer_initialpose" type="cartographer_initialpose" name="cartographer_initialpose" >
<param name="configuration_directory" value="$(find autolabor_navigation_launch)/params/cartographer" />
<param name="configuration_basename" value="second_generation_location.lua" />
</node>
<!-- 导航模块 -->
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
<rosparam file="$(find autolabor_navigation_launch)/params/navigation/move_base/navigation_move_base.yaml" command="load" />
<rosparam file="$(find autolabor_navigation_launch)/params/navigation/costmap/two_laser_global_costmap_params.yaml" command="load" ns="global_costmap"/>
<rosparam file="$(find autolabor_navigation_launch)/params/navigation/costmap/two_laser_local_costmap_params.yaml" command="load" ns="local_costmap"/>
<rosparam file="$(find autolabor_navigation_launch)/params/navigation/global_planer/global_planner_params.yaml" command="load" ns="GlobalPlanner"/>
<rosparam file="$(find autolabor_navigation_launch)/params/navigation/local_planer/navigation_teb_local_planner_params.yaml" command="load" ns="TebLocalPlannerROS"/>
</node>
```
### 3D SLAM 实现原理
#### 传感器介绍
3D SLAM 用到的传感器有:
* 多线激光雷达安装在M1套件内
* 单线激光雷达x2安装在M1内部前后位置
* 编码器/轮速里程计x2安装在车体内部前侧
* 惯导安装在M1套件内
![](imgs/software_intro_7.png)
#### 3D SLAM 建图
![](imgs/software_intro_4.jpg)
| 步骤 | 输入数据 | 操作 | 输出数据 | 使用ROS包 |
|-----|------------------|--------------------------------------------|----------------|-------------------------------------------------------------------------------------------------------|
|1 | 左编码器数据 右编码器数据 | 使用运动模型计算编码器数据得到符合ROS标准的里程计数据| 里程计数据| [autolabor_pro_driver](http://www.autolabor.com.cn/usedoc/ap1/sendCommand)|
|2 | 多线雷达数据 惯导数据 里程计数据 | 点云匹配| 相对位姿数据 子地图数据 | [cartographer_ros](https://google-cartographer-ros.readthedocs.io/en/latest/)|
|3 | 相对位姿数据 子地图数据 | 回环检测,得到子地图拼接的全地图数据 | 地图数据 | [cartographer_ros](https://google-cartographer-ros.readthedocs.io/en/latest/)|
Cartographer 3D 建图 launch配置示例
```
<!-- 建图节点 -->
<node name="cartographer_node" pkg="cartographer_ros"
type="cartographer_node" args="
-configuration_directory $(find autolabor_navigation_launch)/params/cartographer
-configuration_basename third_generation_mapping.lua"
output="screen">
<remap from="points2" to="rslidar_points" />
</node>
<node name="cartographer_occupancy_grid_node" pkg="cartographer_ros" type="cartographer_occupancy_grid_node" args="-resolution 0.05" />
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find autolabor_navigation_launch)/rviz/3d_mapping.rviz" />
```
#### 3D SLAM 导航
![](imgs/software_intro_5.jpg)
| 步骤 | 输入数据 | 操作 | 输出数据 | 使用ROS包 |
|-----|------------------|--------------------------------------------|----------------|-------------------------------------------------------------------------------------------------------|
|1 | 左编码器数据 右编码器数据 | 使用运动模型计算编码器数据得到符合ROS标准的里程计数据| 里程计数据| [autolabor_pro_driver](http://www.autolabor.com.cn/usedoc/ap1/sendCommand)|
|2|多线雷达数据 惯导数据 里程计数据 地图数据|将机器人的实时数据与已构建的地图进行匹配|当前机器人在环境中的位姿| [cartographer_ros](https://google-cartographer-ros.readthedocs.io/en/latest/)|
|3| 目标机器人位姿| 给机器人制定一个目标点| |[move_base](http://wiki.ros.org/move_base/)|
|4| 当前机器人位姿 地图数据 目标机器人位姿| 根据机器人当前位姿与地图数据,进行全局规划路线| 路径数据(初步预估导航路线) |[global_planner(dijkstra) ](http://wiki.ros.org/global_planner)|
|5| 路径数据 地图数据 前雷达数据 后雷达数据 多线雷达数据 | 根据规划路径开始导航,进行过程中随着实际环境、障碍物变化,进行局部路径规划,实时避障| 局部路径规划 避障 |[costmap_2d ](http://wiki.ros.org/cost_map)[teb_local_planner](http://wiki.ros.org/teb_local_planner)|
|6| 速度信息 /cmd_vel | 向底层发送速度命令 | |[move_base](http://wiki.ros.org/move_base/)|
说明:
1. move_base, global_planner(dijkstra), costmap_2d 这些功能包(package)都从属于
Navigation 导航这个大的功能包集teb_local_planner 是navigation包的一个插件。
2. 机器人导航过程中,会按照周围环境、实时障碍物做调整不断规划调整路径,向底层发布指令,步骤五和六是一个多次的过程,并非一次就结束了。
Cartographer 3D 导航 launch配置示例
```
<!-- 定位模块 -->
<node name="cartographer_node" pkg="cartographer_ros"
type="cartographer_node" args="
-configuration_directory $(find autolabor_navigation_launch)/params/cartographer
-configuration_basename third_generation_location.lua
-load_state_filename $(find autolabor_navigation_launch)/map/map_3d.pbstream"
output="screen">
<remap from="points2" to="rslidar_points" />
</node>
<node pkg="map_server" type="map_server" name="map_server" args="$(find autolabor_navigation_launch)/map/map_3d.yaml" />
<node pkg="cartographer_initialpose" type="cartographer_initialpose" name="cartographer_initialpose" >
<param name="configuration_directory" value="$(find autolabor_navigation_launch)/params/cartographer" />
<param name="configuration_basename" value="third_generation_location.lua" />
</node>
<!-- 导航模块 -->
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
<rosparam file="$(find autolabor_navigation_launch)/params/navigation/move_base/navigation_move_base.yaml" command="load" />
<rosparam file="$(find autolabor_navigation_launch)/params/navigation/costmap/3d_global_costmap_params.yaml" command="load" ns="global_costmap"/>
<rosparam file="$(find autolabor_navigation_launch)/params/navigation/costmap/3d_local_costmap_params.yaml" command="load" ns="local_costmap"/>
<rosparam file="$(find autolabor_navigation_launch)/params/navigation/global_planer/global_planner_params.yaml" command="load" ns="GlobalPlanner"/>
<rosparam file="$(find autolabor_navigation_launch)/params/navigation/local_planer/navigation_teb_local_planner_params.yaml" command="load" ns="TebLocalPlannerROS"/>
<param name="TebLocalPlannerROS/xy_goal_tolerance" value="0.2" />
<param name="TebLocalPlannerROS/yaw_goal_tolerance" value="0.5" />
</node>
```