# 10.4 map_server & amcl
在某些固定场景下,我们已经知道了地图(无论通过SLAM还是测量),这样机器人每次启动最好就能直接加载已知地图,而是每次开机都重建。在这种情况下,就需要有一个节点来发布`/map`,提供场景信息了。
## 10.3.1 map_server
map_server是一个和地图相关的功能包,它可以将已知地图发布出来,供导航和其他功能使用,也可以保存SLAM建立的地图。
要让map_server发布`/map`,需要输入给它两个文件:
* 地图文件,通常为pgm格式;
* 地图的描述文件,通常为yaml格式
例如在`ROS-Academy-for-Beginners`里,我们提供了软件博物馆的地图文件,见`slam_sim_demo/maps`下:
Software_Museum.pgm
![slam_gmapping](https://img.kancloud.cn/4a/2a/4a2a3129ef9c12dbfab8fe84faf1e9ba_505x495.png)
Software_Museum.yaml
```xml
image: Software_Museum.pgm #指定地图文件
resolution: 0.050000 #地图的分辨率 单位为m/pixel
origin: [-25.000000, -25.000000, 0.000000] #地图的原点
negate: 0 #0代表 白色为空闲 黑色为占据
occupied_thresh: 0.65 #当占据的概率大于0.65认为被占据
free_thresh: 0.196 #当占据的概率小于0.196认为无障碍
```
其中占据的概率 occ = (255-color_avg)/255.0, color_avg为RGB三个通道的平均值。
有了以上两个文件,你可以通过指令来加载这张地图,map_server相关命令如下:
| map_server命令 | 作用 |
| :------: | :------: |
| `rosrun map_server map_server Software_Museum.yaml` | 加载自定义的地图 |
| `rosrun map_server map_saver -f mymap` | 保存当前地图为mymap.pgn和mymap.yaml |
当我运行`rosrun map_server map_server ***.yaml`时,会有以下的通信接口:
### Topic
通常我们是在launch文件中加载map_server,发布地图。而map_server发布的消息包括:
* /map_metadata: 发布地图的描述信息
* /map: 发布锁存的地图消息
### Service
amcl的服务只有一个:
* static_map: 用于请求和响应当前的静态地图。
### Param
amcl有一个参数需要设置,就是发布地图的frame。
* ~frame_id: string类型,默认为map。 绑定发布的地图与tf中的哪个frame,通常就是map。
有两个概念不要搞混淆,map既是一个topic,也是一个frame,前者是topic通信方式中的一个话题,信息交互的频道,后者是tf中的一个坐标系,map_frame需要和其他的frame相连通。
## 10.3.2 amcl
Adaptive Mentcarto Localization(AMCL),蒙特卡洛自适应定位是一种很常用的定位算法,它通过比较检测到的障碍物和已知地图来进行定位。
AMCL上的通信架构如上图所示,与之前SLAM的框架很像,最主要的区别是`/map`作为了输入,而不是输出,因为AMCL算法只负责定位,而不管建图。
![slam_gmapping](https://img.kancloud.cn/d0/51/d0515ab5d8334845b69ba87e5899dd9f_1838x815.JPG)
同时还有一点需要注意,AMCl定位会对里程计误差进行修正,修正的方法是把里程计误差加到`map_frame`和`odom_frame`之间,而`odom_frame`和`base_frame`之间是里程计的测量值,这个测量值并不会被修正。这一工程实现与之前gmapping、karto的做法是相同的。
![slam_gmapping](https://img.kancloud.cn/f3/12/f31233922814113db6517ef91bb1b0ec_960x720.png)
### 演示截图
amcl算法演示效果图如下:
![](https://img.kancloud.cn/e9/41/e941748bead805be8554f9bdd0098963_987x899.png)
- 前言
- 第一章 ROS简介
- 机器人时代的到来
- ROS发展历程
- 什么是ROS
- 安装ROS
- 安装ROS-Academy-for-Beginners教学包
- 二进制与源码包
- 安装RoboWare Studio
- 单元测试一
- 第二章 ROS文件系统
- Catkin编译系统
- Catkin工作空间
- Package软件包
- CMakeLists.txt
- package.xml
- Metapacakge软件元包
- 其他常见文件类型
- 单元测试二
- 第三章 ROS通信架构(一)
- Node & Master
- Launch文件
- Topic
- Msg
- 常见msg类型
- 单元测试三
- 第四章 ROS通信架构(二)
- Service
- Srv
- Parameter server
- Action
- 常见srv类型
- 常见action类型
- 单元测试四
- 第五章 常用工具
- Gazebo
- RViz
- Rqt
- Rosbag
- Rosbridge
- moveit!
- 单元测试五
- 第六章 roscpp
- Client Library与roscpp
- 节点初始、关闭与NodeHandle
- Topic in roscpp
- Service in roscpp
- Param in roscpp
- 时钟
- 日志与异常
- 第七章 rospy
- Rospy与主要接口
- Topic in rospy
- Service in rospy
- Param与Time
- 第八章 TF与URDF
- 认识TF
- TF消息
- tf in c++
- tf in python
- 统一机器人描述格式
- 附录:TF数学基础
- 三维空间刚体运动---旋转矩阵
- 三维空间刚体运动---欧拉角
- 三维空间刚体运动---四元数
- 第九章 SLAM
- 地图
- Gmapping
- Karto
- Hector
- 第十章 Navigation
- Navigation Stack
- move_base
- costmap
- Map_server & Amcl
- 附录:Navigation工具包说明
- amcl
- local_base_planner
- carrot_planner
- clear_costmap_recovery
- costmap_2d
- dwa_local_planner
- fake_localization
- global_planner
- map_server
- move_base_msg
- move_base
- move_slow_and_clear
- navfn
- nav_core
- robot_pose_ekf
- rotate_recovery