注意:
catkin_ws/src
下$ git clone https://github.com/ros-planning/navigation.gitcatkin_ws/src
下 ```shell
$ git clone https://github.com/ros-perception/slam_gmapping.git
```
- 安装方法2:
``` shell
$ sudo apt-get update
$ sudo apt-get install ros-melodic-gmapping
```博客地址:https://blog.csdn.net/xiaokai1999
webots版本:2020b rev1
ros版本:melodic在前面几章中分别介绍了在webots中如何创建自己的机器人、添加传感器以及使用手柄或键盘驱动它在仿真环境中移动。在本章中,你会学习到ROS系统最强大的特性之一,它能够让你的机器人自主导航和运动。
创建地图本身是一个很麻烦的工作,必须选择正确的工具来简化这项工作。在ROS中就提供了这样的工具能够帮助我们使用激光雷达和机器人的里程信息创建地图。这个工具是map_server地图服务器(http://wiki.ros.org/map_server)。在本示例中,你将会学到如何使用我们在webots中创建的机器人来创建、保存和加载地图。
我们将会使用一个launch文件来简化创建的过程。在webots_demo/launch文件夹下以slam.launch为名称创建一个新文件,然后添加以下代码:
<launch>
<!-- 打开webots -->
<include file="$(find webots_demo)/launch/webots.launch" />
<arg name="model" />
<arg name="gui" default="false" />
<param name="use_gui" value="$(arg gui)" />
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" />
<node name="robot_broadcaster" pkg="webots_demo" type="robot_broadcaster" />
<!-- 打开rviz -->
<node name="rviz" pkg="rviz" type="rviz" />
<!-- Gmapping建图算法,接收传感器数据建立地图 -->
<node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen" clear_params="true">
<param name="odom_frame" value="odom" />
<param name="base_frame" value="base_link" />
<param name="map_update_interval" value="0.75" />
<!-- Set maxUrange < actual maximum range of the Laser -->
<param name="maxRange" value="4.5" />
<param name="maxUrange" value="3.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.157" />
<param name="temporalUpdate" value="-1.0" />
<param name="resampleThreshold" value="0.5" />
<param name="particles" value="50" />
<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="/robot/Sick_LMS_291/laser_scan/layer0" />
</node>
</launch>
有了这个.launch文件,就可以迅速打开webots仿真环境、rviz和gmapping。
可以通过rviz和slam_gmapping算法来实时构建地图。
在控制台中启动这个launch文件:
$ roslaunch webots_demo slam.launch
可以使用第三章编写的控制程序来控制机器人建立地图:
$ rosrun webots_demo velocity_keyboard
建图过程如下:
最终建图效果:
完成了整个地图的探索,就可以通过map_server功能包将地图保存下来方便下次调用。我们可以通过以下命令来保存地图:
$ rosrun map_server map_saver -f map
[ INFO] [1610525218.211739274]: Waiting for the map
[ INFO] [1610525218.422685318]: Received a 480 X 544 map @ 0.050 m/pix
[ INFO] [1610525218.422736024]: Writing map occupancy data to map.pgm
[ INFO] [1610525218.428464420]: Writing map occupancy data to map.yaml
[ INFO] [1610525218.428634957]: Done
这个命令会创建两个文件,map.pgm和map.yaml。第一个文件是以.pem为格式的地图(可输出灰色地图格式)。另一个则是该地图的配置文件。
将这两个文件放至webots_demo/config
下,应当先创建该文件夹,下面会用到。
全局和局部代价地图分别是什么?
机器人将使用这两种导航算法在地图中移动
这些导航算法通过使用代价地图来处理地图中的各种信息。全局代价地图用于全局导航,局部代价地图用于局部导航。
代价地图的参数用于配置算法计算行为。它们也有最基本的通用参数,这些参数会保存在共享的文件中。
我们可以在三个最基本的配置文件中设定不同的参数。这三个文件如下:
在webots_demo/config下以global_costmap_params.yaml为名称创建一个新文件,并且添加以下代码:
global_costmap:
#“global_frame”参数定义了代价地图运行所在的坐标帧。
global_frame: map
#“robot_base_frame”参数定义了代价地图参考的的机器底盘的坐标帧。
robot_base_frame: base_link
#“update_frequency”参数决定了代价地图更新的频率。
update_frequency: 5.0
publish_frequency: 5.0
#“static_map”参数决定代价地图是否根据map_server提供的地图初始化。如果你不使用现有的地图,设为false。
static_map: true
在webots_demo/config下以local_costmap_params.yaml为名称创建一个新文件,并且添加以下代码:
local_costmap:
global_frame: odom
robot_base_frame: base_link
update_frequency: 5.0
publish_frequency: 5.0
static_map: true
#将“rolling_window”参数设置为true,意味着随着机器人在现实世界里移动,代价地图会保持以机器人为中心。
rolling_window: true
width: 6.0
height: 6.0
resolution: 0.05
这个基本规划器会产生一个速度命令来移动机器人。
在webots_demo/config下以base_local_planner_params.yaml为名称创建一个新文件,并且添加以下代码:
TrajectoryPlannerROS:
#速度限制
max_vel_x: 0.45
min_vel_x: 0.1
max_vel_theta: 1.0
min_in_place_vel_theta: 0.4
#加速度限制
acc_lim_theta: 3.2
acc_lim_x: 2.5
acc_lim_y: 2.5
#完整的机器人
holonomic_robot: false
配置好所有功能包必须文件后,只需要配置一个launch文件可以方便我们运行。
在webots_demo/launch文件夹下创建一个名为move_base.launch的新文件,并添加以下代码:
<launch>
<master auto="start"/>
<!-- Run the map server -->
<node name="map_server" pkg="map_server" type="map_server" args="$(find webots_demo)/config/map.yaml "/>
<!-- amcl定位-->
<node pkg="amcl" type="amcl" name="amcl" output="screen">
<remap from="scan" to="robot/Sick_LMS_291/laser_scan/layer0"/>
<param name="odom_frame_id" value="odom"/>
<param name="odom_model_type" value="diff-corrected"/>
<param name="base_frame_id" value="base_link"/>
<param name="global_frame_id" value="map"/>
<!--transform tolerance-->
<param name="transform_tolerance" value="0.9"/>
<!--overall filter-->
<param name="min_particles" value="150"/>
<param name="max_particles" value="400"/>
<param name="initial_pose_x" value="0.0"/>
<param name="initial_pose_y" value="0.0"/>
<param name="updata_min_a" value="0.1"/>
<param name="update_min_d" value="0.25"/>
<!--likelihood_field of laser-->
<param name="laser_min_range" value="1.0"/>
<param name="laser_max_range" value="25"/>
<param name="laser_max_beams" value="30"/>
<param name="laser_z_hit" value="0.95"/>
<param name="laser_z_rand" value="0.05"/>
<!--Odometry-->
<param name="odom_model_type" value="diff"/>
<param name="odom_alpha1" value="0.2"/>
<param name="odom_alpha2" value="0.2"/>
<param name="odom_alpha3" value="0.2"/>
<param name="odom_alpha4" value="0.2"/>
</node>
<!-- move_base 导航 -->>
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
<rosparam file="$(find webots_demo)/config/costmap_common_params.yaml" command="load" ns="global_costmap" />
<rosparam file="$(find webots_demo)/config/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam file="$(find webots_demo)/config/local_costmap_params.yaml" command="load" />
<rosparam file="$(find webots_demo)/config/global_costmap_params.yaml" command="load" />
<rosparam file="$(find webots_demo)/config/base_local_planner_params.yaml" command="load" />
<remap from="cmd_vel" to="cmd_vel"/>
<remap from="odom" to="odom"/>
<remap from="scan" to="robot/Sick_LMS_291/laser_scan/layer0"/>
<param name="base_global_planner" type="string" value="navfn/NavfnROS" />
<param name="base_local_planner" value="base_local_planner/TrajectoryPlannerROS"/>
</node>
</launch>
在这我把之前编辑的slam.launch分成了两个
/cmd_vel
会发布话题使用rostopic echo /cmd_vel
可以看到数据格式。
格式如下:
/cmd_vel会返回一个线性速度和角速度,这时,因为我们给webots的是两轮的速度,所以需要使用算法倒推回去。
算法如下(导航推测):
因为我们知道了线速度(Vk)和角速度(Wk)的值,那我们可以联立方程算出左轮速度(Vl)和右轮速度(Vr)的值。
本文也是基于笔者的学习和使用经验总结的,主观性较强,如果有哪些不对的地方或者不明白的地方,欢迎评论区留言交流~
到这,这个项目的一部分就已经告一段落了
✌Bye
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。