ROS1云课→27机器人SLAM小结


在前面做的所有工作都成了现在项目的铺垫,而最大的乐趣也即将开始,这是赋予机器人生命的时刻。

后续学习以下内容:

  • 应用程序包开发。
  • 理解导航功能包集及其工作方式。
  • 配置所有必要文件。
  • 创建启动文件并开始导航。

机器人配置启动文件:

<!--Turtlebot navigation simulation:- stdr- move_base- amcl- map_server- rviz view-->
<launch><arg name="base"       default="$(optenv TURTLEBOT_BASE kobuki)"/>  <!-- create, rhoomba --><arg name="stacks"     default="$(optenv TURTLEBOT_STACKS hexagons)"/>  <!-- circles, hexagons --><arg name="3d_sensor"  default="$(optenv TURTLEBOT_3D_SENSOR kinect)"/>  <!-- kinect, asus_xtion_pro --><arg name="laser_topic" default="robot0/laser_0"/> <!-- default laser topic in stdr for 1 robot --><arg name="odom_topic" default="robot0/odom"/><arg name="odom_frame_id" default="map"/><arg name="base_frame_id" default="robot0"/><arg name="global_frame_id" default="world"/><!-- Name of the map to use (without path nor extension) and initial position --><arg name="map_file"       default="$(env TURTLEBOT_STDR_MAP_FILE)"/><arg name="initial_pose_x" default="2.0"/><arg name="initial_pose_y" default="2.0"/><arg name="initial_pose_a" default="0.0"/><arg name="min_obstacle_height" default="0.0"/><arg name="max_obstacle_height" default="5.0"/><!--  ******************** Stdr********************  --><include file="$(find stdr_robot)/launch/robot_manager.launch" /><!-- Run STDR server with a prefedined map--><node pkg="stdr_server" type="stdr_server_node" name="stdr_server" output="screen" args="$(arg map_file)"/><!--Spawn new robot at init position 2 2 0--><node pkg="stdr_robot" type="robot_handler" name="$(anon robot_spawn)" args="add $(find turtlebot_stdr)/robot/turtlebot.yaml $(arg initial_pose_x) $(arg initial_pose_y) 0"/><!-- Run Gui  --><include file="$(find stdr_gui)/launch/stdr_gui.launch"/><!-- Run the relay to remap topics --><include file="$(find turtlebot_stdr)/launch/includes/relays.launch.xml"/><!--  ***************** Robot Model *****************  --><include file="$(find turtlebot_bringup)/launch/includes/robot.launch.xml"><arg name="base" value="$(arg base)" /><arg name="stacks" value="$(arg stacks)" /><arg name="3d_sensor" value="$(arg 3d_sensor)" /></include><node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher"><param name="use_gui" value="true"/></node><!-- Command Velocity multiplexer --><node pkg="nodelet" type="nodelet" name="mobile_base_nodelet_manager" args="manager"/><node pkg="nodelet" type="nodelet" name="cmd_vel_mux" args="load yocs_cmd_vel_mux/CmdVelMuxNodelet mobile_base_nodelet_manager"><param name="yaml_cfg_file" value="$(find turtlebot_bringup)/param/mux.yaml"/><remap from="cmd_vel_mux/output" to="mobile_base/commands/velocity"/></node><!-- ****** Maps ***** --><node name="map_server" pkg="map_server" type="map_server" args="$(arg map_file)"><param name="frame_id" value="$(arg global_frame_id)"/></node><!--  ************** Navigation  ***************  --><include file="$(find turtlebot_navigation)/launch/includes/move_base.launch.xml"><arg name="odom_topic" value="$(arg odom_topic)"/><arg name="laser_topic" value="$(arg laser_topic)"/><arg name="odom_frame_id"   value="$(arg odom_frame_id)"/><arg name="base_frame_id"   value="$(arg base_frame_id)"/><arg name="global_frame_id" value="$(arg global_frame_id)"/></include><!-- ***************** Manually setting some parameters ************************* --><param name="move_base/local_costmap/obstacle_layer/scan/min_obstacle_height" value="$(arg min_obstacle_height)"/><param name="move_base/local_costmap/obstacle_layer/scan/max_obstacle_height" value="$(arg max_obstacle_height)"/><param name="move_base/global_costmap/obstacle_layer/scan/min_obstacle_height" value="$(arg min_obstacle_height)"/><param name="move_base/global_costmap/obstacle_layer/scan/max_obstacle_height" value="$(arg max_obstacle_height)"/><!--  ************** AMCL ************** --><include file="$(find turtlebot_navigation)/launch/includes/amcl/amcl.launch.xml"><arg name="scan_topic" value="$(arg laser_topic)"/><arg name="use_map_topic" value="true"/><arg name="odom_frame_id" value="$(arg odom_frame_id)"/><arg name="base_frame_id" value="$(arg base_frame_id)"/><arg name="global_frame_id" value="$(arg global_frame_id)"/><arg name="initial_pose_x" value="$(arg initial_pose_x)"/><arg name="initial_pose_y" value="$(arg initial_pose_y)"/><arg name="initial_pose_a" value="$(arg initial_pose_a)"/></include><!-- ********** Small tf tree connector between robot0 and base_footprint********* --><node name="tf_connector" pkg="turtlebot_stdr" type="tf_connector.py" output="screen"/><!--  **************** Visualisation ****************  --><node name="rviz" pkg="rviz" type="rviz" args="-d $(find turtlebot_stdr)/rviz/robot_navigation.rviz"/></launch>

重点关注move_base:

<!-- ROS navigation stack with velocity smoother and safety (reactive) controller
-->
<launch><include file="$(find turtlebot_navigation)/launch/includes/velocity_smoother.launch.xml"/><include file="$(find turtlebot_navigation)/launch/includes/safety_controller.launch.xml"/><arg name="odom_frame_id"   default="odom"/><arg name="base_frame_id"   default="base_footprint"/><arg name="global_frame_id" default="map"/><arg name="odom_topic" default="odom" /><arg name="laser_topic" default="scan" /><arg name="custom_param_file" default="$(find turtlebot_navigation)/param/dummy.yaml"/><node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen"><rosparam file="$(find turtlebot_navigation)/param/costmap_common_params.yaml" command="load" ns="global_costmap" /><rosparam file="$(find turtlebot_navigation)/param/costmap_common_params.yaml" command="load" ns="local_costmap" />   <rosparam file="$(find turtlebot_navigation)/param/local_costmap_params.yaml" command="load" />   <rosparam file="$(find turtlebot_navigation)/param/global_costmap_params.yaml" command="load" /><rosparam file="$(find turtlebot_navigation)/param/dwa_local_planner_params.yaml" command="load" /><rosparam file="$(find turtlebot_navigation)/param/move_base_params.yaml" command="load" /><rosparam file="$(find turtlebot_navigation)/param/global_planner_params.yaml" command="load" /><rosparam file="$(find turtlebot_navigation)/param/navfn_global_planner_params.yaml" command="load" /><!-- external params file that could be loaded into the move_base namespace --><rosparam file="$(arg custom_param_file)" command="load" /><!-- reset frame_id parameters using user input data --><param name="global_costmap/global_frame" value="$(arg global_frame_id)"/><param name="global_costmap/robot_base_frame" value="$(arg base_frame_id)"/><param name="local_costmap/global_frame" value="$(arg odom_frame_id)"/><param name="local_costmap/robot_base_frame" value="$(arg base_frame_id)"/><param name="DWAPlannerROS/global_frame_id" value="$(arg odom_frame_id)"/><remap from="cmd_vel" to="navigation_velocity_smoother/raw_cmd_vel"/><remap from="odom" to="$(arg odom_topic)"/><remap from="scan" to="$(arg laser_topic)"/></node>
</launch>

配置全局和局部代价地图

好的,现在将要开始配置导航功能包集和所有启动时必需的文件。为了开始进行配置,首先将会学习什么是代价地图(costmaps)和代价地图的作用。机器人将使用两种导航算法在地图中移动——全局导航(global)和局部导航(local)。

  • 全局导航用于建立到地图上最终目标或一个远距离目标的路径。
  • 局部导航用于建立到近距离目标和为了临时躲避障碍物的路径。例如,机器人四周一个4×4m²的方形窗户。

这些导航算法通过使用代价地图来处理地图中的各种信息。全局代价地图用于全局导航,局部代价地图用于局部导航。

代价地图的参数用于配置算法计算行为。它们也有最基本的通用参数,这些参数会保存在共享的文件中。

可以在三个最基本的配置文件中设定不同的参数。这三个文件如下:

  • costmap_common_params.yaml
  • global_costmap_params.yaml
  • local_costmap_params.yaml

只需要看一下这三个文件的名称,就能大致猜出来它们的用途。现在可能刚刚对代价地图的作用有一个初步的认识,来创建这些配置文件并解释这些配置参数的作用。

基本参数的配置

从最基本的参数讲起。以costmap_common_params.yaml为名称创建一个新文件,并添加以下代码。

下面的脚本在costmap_common_params.yaml呈现:

max_obstacle_height: 0.60  # assume something like an arm is mounted on top of the robot# Obstacle Cost Shaping (http://wiki.ros.org/costmap_2d/hydro/inflation)
robot_radius: 0.20  # distance a circular robot should be clear of the obstacle (kobuki: 0.18)
# footprint: [[x0, y0], [x1, y1], ... [xn, yn]]  # if the robot is not circularmap_type: voxelobstacle_layer:enabled:              truemax_obstacle_height:  0.6origin_z:             0.0z_resolution:         0.2z_voxels:             2unknown_threshold:    15mark_threshold:       0combination_method:   1track_unknown_space:  true    #true needed for disabling global path planning through unknown spaceobstacle_range: 2.5raytrace_range: 3.0origin_z: 0.0z_resolution: 0.2z_voxels: 2publish_voxel_map: falseobservation_sources:  scan bumpscan:data_type: LaserScantopic: scanmarking: trueclearing: truemin_obstacle_height: 0.25max_obstacle_height: 0.35bump:data_type: PointCloud2topic: mobile_base/sensors/bumper_pointcloudmarking: trueclearing: falsemin_obstacle_height: 0.0max_obstacle_height: 0.15# for debugging only, let's you see the entire voxel grid#cost_scaling_factor and inflation_radius were now moved to the inflation_layer ns
inflation_layer:enabled:              truecost_scaling_factor:  5.0  # exponential rate at which the obstacle cost drops off (default: 10)inflation_radius:     0.5  # max. distance from an obstacle at which costs are incurred for planning paths.static_layer:enabled:              true

这个文件主要用于配置基本参数。这些参数会被用于local_costmapglobal_costmap。对代码进行详细的解释。

obstacle_rangeraytrace_range参数用于表示传感器的最大探测距离并在代价地图中引入探测的障碍信息。前者主要用于障碍的探测。在我们的示例中,如果机器人检测到一个距离小于2.5m的障碍物,就会将这个障碍物引入到代价地图中。后者则用于在机器人运动过程中,实时清除代价地图中的障碍物,并更新可移动的自由空间数据。请注意,我们只能检测到障碍物对雷达激光信号投影或者声呐的回波,我们无法感知完整的物体形状和大小。但在实际应用中,这样的测量结果就足够我们完成地图的绘制和机器人自身的定位了。

footprint参数用于将机器人的几何参数告知导航功能包集。这样就能在机器人和障碍物之间保持一个合理的距离,或者说提前获知机器人能否穿越某个门等。

inflation_radius参数则给定了机器人与障碍物之间必须要保持的最小距离。

cost_scaling_factor参数修改机器人绕过障碍物的行为,可以通过修改参数设计一个激进或保守的行为。

还需要配置:

observation_sources参数来设定导航功能包集所使用的传感器,以获取实际环境的数据并计算路径。

在示例中,会在stdr中使用一个模拟的LIDAR。

通过下面的代码,会对传感器的坐标系和数据进行配置:

  scan:data_type: LaserScantopic: scanmarking: trueclearing: truemin_obstacle_height: 0.25max_obstacle_height: 0.35bump:data_type: PointCloud2topic: mobile_base/sensors/bumper_pointcloudmarking: trueclearing: falsemin_obstacle_height: 0.0max_obstacle_height: 0.15# for debugging only, let's you see the entire voxel grid

上面配置的这些参数也会被用于在代价地图中添加和清除障碍。例如,可以添加一个探测范围较大的传感器用于在代价地图中寻找障碍物,再添加一个传感器用于导航和清除障碍物。在上面还会配置主题的名称,这是不能被遗漏的,如果不进行配置,那么导航功能包集会使用默认的主题以保证程序能够正常运行,那么一旦机器人移动起来,很可能就会撞到墙上或者障碍物上。

全局代价地图的配置

下一个用于配置的文件主要是全局代价地图global costmap。在以global_costmap_params.yaml为名的新文件,并添加以下代码:

global_costmap:global_frame: /maprobot_base_frame: /base_footprintupdate_frequency: 1.0publish_frequency: 0.5static_map: truetransform_tolerance: 0.5plugins:- {name: static_layer,            type: "costmap_2d::StaticLayer"}- {name: obstacle_layer,          type: "costmap_2d::VoxelLayer"}- {name: inflation_layer,         type: "costmap_2d::InflationLayer"}

其中,global_framerobot_base_frame参数用于定义地图和机器人之间的坐标变换。建立全局代价地图必须要使用这个变换。

还能配置代价地图更新的频率。在示例中,这个频率为1Hz。参数static_map用于配置是否使用一个地图或者地图服务器来初始化代价地图。如果不准备使用静态的地图,那么这个参数应该为false。

局部代价地图的配置

下面的这个文件用于配置局部代价地图。在以local_costmap_params.yaml为名的新文件,并添加以下代码:

local_costmap:global_frame: odomrobot_base_frame: /base_footprintupdate_frequency: 5.0publish_frequency: 2.0static_map: falserolling_window: truewidth: 4.0height: 4.0resolution: 0.05transform_tolerance: 0.5plugins:- {name: obstacle_layer,      type: "costmap_2d::VoxelLayer"}- {name: inflation_layer,     type: "costmap_2d::InflationLayer"}

其中,global_framerobot_base_frameupdate_frequencystatic_map参数和上一节描述的内容一致,用来配置全局代价地图。参数publish_frequency定义了发布信息的频率。参数rolling_window用于保持在机器人运动过程中,代价地图始终以机器人为中心。

通过transform_tolerance参数配置转换的最大延迟,在本例中为0.5s。通过planner_frequency参数配置规划循环的频率(以Hz为单位),planner_ patiente参数配置在执行空间清理操作前,规划器寻找一条有效路径的等待时间(以s为单位)

能够通过widthheightresolution参数来配置代价地图的尺寸和分辨率。这些参数都是以m为单位的。

底盘局部规划器配置

一旦我们完成代价地图的配置,那么就能够开始进行一个底盘规划器的配置了。这个底盘规划器会产生一个速度命令来移动我们的机器人。在以dwa_local_planner_params.yaml为名的新文件,并添加以下代码:

DWAPlannerROS:# Robot Configuration Parameters - Kobukimax_vel_x: 0.5  # 0.55min_vel_x: 0.0 max_vel_y: 0.0  # diff drive robotmin_vel_y: 0.0  # diff drive robotmax_trans_vel: 0.5 # choose slightly less than the base's capabilitymin_trans_vel: 0.1  # this is the min trans velocity when there is negligible rotational velocitytrans_stopped_vel: 0.1# Warning!#   do not set min_trans_vel to 0.0 otherwise dwa will always think translational velocities#   are non-negligible and small in place rotational velocities will be created.max_rot_vel: 5.0  # choose slightly less than the base's capabilitymin_rot_vel: 0.4  # this is the min angular velocity when there is negligible translational velocityrot_stopped_vel: 0.4acc_lim_x: 1.0 # maximum is theoretically 2.0, but we acc_lim_theta: 2.0acc_lim_y: 0.0      # diff drive robot# Goal Tolerance Parametersyaw_goal_tolerance: 0.3  # 0.05xy_goal_tolerance: 0.15  # 0.10# latch_xy_goal_tolerance: false# Forward Simulation Parameterssim_time: 1.0       # 1.7vx_samples: 6       # 3vy_samples: 1       # diff drive robot, there is only one samplevtheta_samples: 20  # 20# Trajectory Scoring Parameterspath_distance_bias: 64.0      # 32.0   - weighting for how much it should stick to the global path plangoal_distance_bias: 24.0      # 24.0   - wighting for how much it should attempt to reach its goaloccdist_scale: 0.5            # 0.01   - weighting for how much the controller should avoid obstaclesforward_point_distance: 0.325 # 0.325  - how far along to place an additional scoring pointstop_time_buffer: 0.2         # 0.2    - amount of time a robot must stop in before colliding for a valid traj.scaling_speed: 0.25           # 0.25   - absolute velocity at which to start scaling the robot's footprintmax_scaling_factor: 0.2       # 0.2    - how much to scale the robot's footprint when at speed.# Oscillation Prevention Parametersoscillation_reset_dist: 0.05  # 0.05   - how far to travel before resetting oscillation flags# Debuggingpublish_traj_pc : truepublish_cost_grid_pc: trueglobal_frame_id: odom# Differential-drive robot configuration - necessary?
#  holonomic_robot: false

这个配置文件设定了机器人的最大和最小速度限值,同时也设定了加速度的限值。

当使用的是一台完整约束的平台(holonomic platform)时,那么参数holonomic_robot就应设为true。在示例中使用的不是完整约束的运动载体,所以这个参数是false。全向移动机器人指的是它能够以从任意位置向已配置空间移动。换句话说,如果机器人可以到达的位置已经以x、y轴坐标值的形式定义,那么全向移动机器人能够从任意位置出发向该位置移动。举例来说,如果机器人能够前后左右移动,那么就是全向移动机器人。一种典型的非全向移动的例子就是汽车,因为它就不能直接沿左右方向移动到一个给定的位置。如果从某个位置(和位姿)开始运动的话,它并不能一次到达地图上的每一个地点,也不能保证到达时的位姿。类似地,差分移动机器人平台就是一个非全向移动机器人平台。


ROS1云课→28机器人代价地图配置相关推荐

  1. ROS1云课→16机器人模型从urdf到xacro

    ROS1云课→15主题与坐标系 补充: 2020:ROS机器人URDF建模_zhangrelay的博客-CSDN博客 2022:URDF机器人模型ROS1&2案例(noetic+galacti ...

  2. ROS1云课→29如何借助导航实现走迷宫机器人

    ROS1云课→28机器人代价地图配置 简述: 在这个项目中,将创建一个机器人,它将进入一个迷宫形式的房间,然后从另一个点离开房间. 详细: 在行业中,有些地方机器人可以收集加工过的物体并将这些物体放入 ...

  3. ROS1云课→25机器人控制配置

    ROS1云课→24机器人感知配置 移动机器人控制和运动学动力学模型密切相关. 差动驱动轮系统控制器.控制采用速度命令的形式,将其拆分然后发送到差动驱动轴距的两个车轮上.里程计是从硬件的反馈中计算出来的 ...

  4. ROS1云课→17化繁为简stdr和f1tenth

    ROS1云课→16机器人模型从urdf到xacro 蓝桥ROS云课可以使用Gazebo/V-Rep/Webots等三维仿真软件,这些都在之前博客中提及,或者有学生撰写对应博客进行分享. 二维的环境主要 ...

  5. ROS1云课→32愉快大扫除

    ROS1云课→31欢乐卷假期 案例简述:就是扫地机器人的路径规划复现一下,没了-- 能不能复现别人的区域覆盖算法呢??? ROS1云课→30导航仿真演示 导航机器人摇身一变扫地机器人(只有路径规划演示 ...

  6. ROS1云课→23turtlesim绘制小结(数学和编程)

    ROS1云课→22机器人轨迹跟踪 这一节就有些乱了-- 机器人如何走出一个正方形的轨迹呢? 这里,采用了官方例程中: //draw_square#include <boost/bind.hpp& ...

  7. ROS1云课→01简介和配置

    ROS1云课适用于kinetic/melodic/noetic.以蓝桥ROS云课为模板重新梳理. 云原生与蓝桥ROS机器人课程 2017-2022_zhangrelay的博客-CSDN博客 机器人课程 ...

  8. ROS1云课→18一键配置

    ROS1云课→17化繁为简stdr和f1tenth 之前的教程,打开那么多终端,每次都敲那么多指令,为啥? 熟能生巧而已,有些过程不能省略,但是,如果已经熟悉了这些过程,还每次都这么搞. 难道是有点情 ...

  9. ROS1云课- 1 0 2 4

    用如下地图复习一下,ROS1主要内容. 分为如下: 基础部分 命令部分 图形化工具部分 功能包使用部分 功能包编译部分 导航部分 区域覆盖部分 1. 基础部分 参考一键配置: ROS1云课→30导航仿 ...

最新文章

  1. 【收藏】SAP记账码
  2. python获取月份字符串_python 正则表达式获取字符串中所有的日期和时间
  3. 移动隐藏邮箱并删除默认邮箱数据库
  4. 算法竞赛入门与进阶 (一)枚举
  5. Oracle修改表列名与顺序的解决方案 (sql 修改列名)
  6. Win7 Ubuntu13.04互通(win7下用vbox安装Ubuntu)
  7. vue 解决: *!!vue-style-loader!css-loader?{“sourceMap“:true}!../../../../vue-loader
  8. 执行NET 命令无法使用超过20个字符的组名或用户名
  9. python编写数据库连接工具_详解使用Python写一个向数据库填充数据的小工具(推荐)...
  10. PHP对银行卡号的几种常见操作
  11. js去除字符串空格(空白符)
  12. whitening(白化)
  13. MySQL生日转年龄
  14. Spring data elasticsearch添加同义词组件实现同义词热更新
  15. PySide6 Widgets基本小部件类--QWidget
  16. 南卡蓝牙耳机好还是漫步者好?国产半入耳式蓝牙耳机对比
  17. 一个服务器部署一个以及两个以上tomcat时且为htts时教程
  18. matlab实现降低图片的分辨率
  19. sql server 函數
  20. 对于损失函数MASE的计算公式

热门文章

  1. autojs-识图点击完整方法带源码及使用方法
  2. FME数据处理04:面自相交拓扑检查
  3. 华师大 OJ 3053
  4. 华师大 OJ 2897
  5. 海康大华宇视等等安防监控摄像头转成WebRTC流实现Web浏览器超低延迟无插件直播新方案
  6. perror和strerror的使用和区别
  7. 2022年无线蓝牙耳机排行榜,音质好性价比高的无线蓝牙耳机品牌推荐
  8. 上证50成分股聚类可视化
  9. Python:enumerate函数
  10. 4 位硬科技创始人对谈 DevOps 硬件实战