ros2笔记-7.1 机器人导航介绍
7.1 机器人导航介绍
7.1.1 同步定位与地图构建
想要导航,就是要确定当前位置跟目标位置。确定位置就是定位问题。
手机的卫星导航在室内 受屏蔽,需要其他传感器获取位置信息。
利用6.5 章节的仿真,打开并运行
会发现轨迹跟障碍物都被记录下来,但是转弯过程出现较大偏差。因此SLAM是同步定位与地图构建(Simultaneous Localization And Mapping)被用来解决机器人定位和见图问题。
分为:激光slam,视觉slam 两种
7.1.2 机器人导航
分为3部分:全局路径规划、局部路径规划、恢复行为三部分。
全局路径规划:全局路径规划算法属于静态规划算法,根据已有的地图信息(SLAM)为基础进行路径规划,寻找一条从起点到目标点的最优路径。
局部路径规划:机器人根据全局 规划路径行驶的过程中发现障碍物时进行障碍物规避的局部避障策略,根据小范围环境重新创建一张局部的代价地图。然后进行路径规划,与全局路径规划相辅相成。
恢复行为:发现行走过程被挡住,没法绕过去,尝试脱困动作称为恢复行为。
7.2 使用 slam_toolbox 完成建图
安装slam_toolbox
sudo apt install ros-$ROS_DISTRO-slam-toolbox
启动tool-box
bohu@bohu-TM1701:~/chapt7/chapt7_ws$ ros2 launch slam_toolbox online_async_launch.py use_sim_time:=True
[INFO] [launch]: All log files can be found below /home/bohu/.ros/log/2025-01-14-19-58-56-245647-bohu-TM1701-33422
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [async_slam_toolbox_node-1]: process started with pid [33432]
[async_slam_toolbox_node-1] [INFO] [1736855936.666816293] [slam_toolbox]: Node using stack size 40000000
[async_slam_toolbox_node-1] [INFO] [1736855936.849725390] [slam_toolbox]: Using solver plugin solver_plugins::CeresSolver
[async_slam_toolbox_node-1] [INFO] [1736855936.850539163] [slam_toolbox]: CeresSolver: Using SCHUR_JACOBI preconditioner.
[async_slam_toolbox_node-1] [WARN] [1736855937.739584413] [slam_toolbox]: minimum laser range setting (0.0 m) exceeds the capabilities of the used Lidar (0.1 m)
[async_slam_toolbox_node-1] Info: clipped range threshold to be within minimum and maximum range!
slam-toolbox 接受输入两个:
来自雷达的/scan话题,用于获取雷达数据。
来自里程计坐标系的odom到机器人的base_footprint之间的变化。
产生的地图数据会通过/map话题发布。可以通过rviz通过话题订阅。
打开终端,通过键盘控制机器人移动。添加了map,TF ,robotModel之后。
获取的地图是乱的,问题是走直线没问题,转弯进房间就是乱的。
小鱼老师说需要重新调整里程计标定
我折腾了回去,把第6章视频有看了一遍,调整了协方差矩阵参数。终于再跑一遍好了,形成了书上完整的地图。
保存地图
新建功能包fishbot_navigation2,新建文件夹maps.在maps下指令保存命令
ros2 run nav2_map_server map_saver_cli -f room
[WARN] [1736859960.290999663] [map_saver]: Free threshold unspecified. Setting it to default value: 0.250000
[WARN] [1736859960.291040822] [map_saver]: Occupied threshold unspecified. Setting it to default value: 0.650000
[WARN] [1736859960.530664620] [map_io]: Image format unspecified. Setting it to: pgm
[INFO] [1736859960.531061091] [map_io]: Received a 376 X 221 map @ 0.05 m/pix
[INFO] [1736859960.676217431] [map_io]: Writing map occupancy data to room.pgm
[INFO] [1736859960.677935222] [map_io]: Writing map metadata to room.yaml
[INFO] [1736859960.678163871] [map_io]: Map saved
[INFO] [1736859960.678190540] [map_saver]: Map saved successfully
[INFO] [1736859960.679332572] [map_saver]: Destroying
打开文件夹可以看到图片room.pgm
还有个图片描述文件:room.yaml
image: room.pgm
mode: trinary
resolution: 0.05
origin: [-10.4, -6.46, 0]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.25
参数意义不同:
image是描述地图文件名称
mode:地图类型,trinary是每个像素点有三种可能状态:障碍物的占据(occupied)用黑色表示,无障碍自由(free)用白色表示,未知(unknown)的用灰色表示。
resolution:表示分标率,0.05单位是米
origin:地图坐标是原点。单位是米
negate表示取反。0不取反
剩下两个参数表示阈值。占据阈值(occupied_thresh),比如0.65,则表示栅格占据率大于0.65的认为是有障碍物。空闲阈值(free_thresh),比如0.25,则表示栅格占据率小于0.25的认为没有障碍物。那在free_thresh和occupied_thresh之间的则认为是未知区域(未探索)
为啥这样呢不是0,1表示?小鱼老师解释是传感器有噪声(有误差),所以有没有障碍物不是完全确定。所以也把地图数据分割为一块块的栅格来表达地图信息,就是栅格地图。