Robot Navigation (2): Navigation Implementation

SLAM mapping

There are many SLAM algorithms. Currently we use gmapping, and we will introduce several other commonly used SLAM implementations later.

Introduction to gmapping

gmapping is one of the more commonly used and mature SLAM algorithms in the ROS open source community. gmapping can draw two-dimensional grid maps based on mobile robot odometer data and lidar data. Correspondingly, gmapping also has certain requirements for hardware:

  • This mobile robot can post odometry messages
  • The robot needs to post a radar message (this message can be released by a horizontally fixed radar, or it can also convert the depth camera message into a radar message)

Regarding the odometer and radar data, which can be obtained normally in the simulation environment, I will not go into details. The grid map is shown in the case.

The gmapping installation is also introduced earlier, the command is as follows:

sudo apt install ros-<ROS版本>-gmapping

gmapping node description

The core node in the gmapping function package is: slam_gmapping. In order to facilitate invocation, it is necessary to first understand the topics subscribed to, published topics, services and related parameters of the node.

Subscribed Topic

tf (tf/tfMessage): Used for coordinate transformation messages between radar, chassis and odometer.

scan(sensor_msgs/LaserScan): Radar information required for SLAM.

Published Topic

map_metadata(nav_msgs/MapMetaData): Map metadata, including map width, height, resolution, etc. This message will be updated regularly.

map(nav_msgs/OccupancyGrid): map raster data, generally displayed graphically in rviz.

~entropy(std_msgs/Float64): Entropy estimation of robot pose distribution (the larger the value, the greater the uncertainty).

Serve

dynamic_map(nav_msgs/GetMap): Used to get map data.

parameter

~base_frame(string, default:“base_link”)

Robot base coordinate system.
~map_frame(string, default: "map")

Map coordinate system.
~odom_frame(string, default: "odom")

The odometry coordinate system.
~map_update_interval(float, default: 5.0)

Map update frequency, the update interval is designed according to the specified value.
~maxUrange(float, default: 80.0)

Maximum usable range for laser detection (beyond this threshold, truncated).
~maxRange(float)

Maximum range of laser detection.
… There are many parameters. The above are a few commonly used parameters. For other parameters, please refer to the official website.

Coordinate Transformation Required

Radar coordinate system → base coordinate system

Generally published by robot_state_publisher or static_transform_publisher.
Base coordinate system → odometer coordinate system

Generally issued by the odometer node.

Published Coordinate Transformation

Map Coordinate System → Odometer Coordinate System

Transformation between map to odometry coordinate system.

gmapping uses

Write gmapping node-related launch files

Launch file writing can refer to the demo launch file of github: https://github.com/ros-perception/slam_gmapping/blob/melodic-devel/gmapping/launch/slam_gmapping_pr2.launch

Copy and modify as follows:

<launch>
<param name="use_sim_time" value="true"/>
    <node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen">
      <remap from="scan" to="scan"/>
      <param name="base_frame" value="base_footprint"/><!--底盘坐标系-->
      <param name="odom_frame" value="odom"/> <!--里程计坐标系-->
      <param name="map_update_interval" value="5.0"/>
      <param name="maxUrange" value="16.0"/>
      <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.1"/>
      <param name="srt" value="0.2"/>
      <param name="str" value="0.1"/>
      <param name="stt" value="0.2"/>
      <param name="linearUpdate" value="1.0"/>
      <param name="angularUpdate" value="0.5"/>
      <param name="temporalUpdate" value="3.0"/>
      <param name="resampleThreshold" value="0.5"/>
      <param name="particles" value="30"/>
      <param name="xmin" value="-50.0"/>
      <param name="ymin" value="-50.0"/>
      <param name="xmax" value="50.0"/>
      <param name="ymax" value="50.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"/>
    </node>

    <node pkg="joint_state_publisher" name="joint_state_publisher" type="joint_state_publisher" />
    <node pkg="robot_state_publisher" name="robot_state_publisher" type="robot_state_publisher" />

    <node pkg="rviz" type="rviz" name="rviz" />
    <!-- 可以保存 rviz 配置并后期直接使用-->
    <!--
    <node pkg="rviz" type="rviz" name="rviz" args="-d $(find my_nav_sum)/rviz/gmapping.rviz"/>
    -->
</launch>

Key code explanation:

<remap from="scan" to="scan"/><!-- 雷达话题 -->
<param name="base_frame" value="base_footprint"/><!--底盘坐标系-->
<param name="odom_frame" value="odom"/> <!--里程计坐标系-->

Execute
1. Start the Gazebo simulation environment first (this process is omitted)

2. Then start the launch file for map drawing:

roslaunch 包名 launch文件名

3. Start the keyboard keyboard control node, which is used to control the robot's motion and mapping

rosrun teleop_twist_keyboard teleop_twist_keyboard.py

4. Add components in rviz to display the grid map
insert image description here

Finally, the robot movement in gazebo can be controlled through the keyboard. At the same time, the raster map data released by gmapping can be displayed in rviz. In the next step, the map needs to be saved separately.

map service

In the previous section, we have realized the construction of the map through gmapping and displayed the map in rviz. However, the map data in the previous section is stored in memory. When the node is closed, the data will also be released. We need to The disk to which the raster map is serialized is stored persistently, and the map data on the disk must be read through deserialization later to perform subsequent operations. In ROS, the serialization and deserialization of map data can be realized through the map_server function package.

Introduction to map_server

The map_server function package provides two nodes: map_saver and map_server, the former is used to save the grid map to the disk, and the latter reads the grid map of the disk and provides it as a service.

The map_server installation is also introduced before, the command is as follows:

sudo apt install ros-<ROS版本>-map-server

Map saver node used by map_server (map_saver)

map_saver node description

Subscribed topics:

map(nav_msgs/OccupancyGrid)

Subscribe to this topic for generating map files.

Map save launch file
The grammar of map save is relatively simple, write a launch file, the content is as follows:

<launch>
    <arg name="filename" value="$(find mycar_nav)/map/nav" />
    <node name="map_save" pkg="map_server" type="map_saver" args="-f $(arg filename)" />
</launch>

Among them, mymap refers to the save path of the map and the name of the saved file.

After the SLAM map is built, execute the launch file.

test:

首先,参考上一节,依次启动仿真环境,键盘控制节点与SLAM节点;

然后,通过键盘控制机器人运动并绘图;

最后,通过上述地图保存方式保存地图。

结果:在指定路径下会生成两个文件,xxx.pgm 与 xxx.yaml

save result interpretation

insert image description here
xxx.pgm is essentially a picture, which can be opened directly with a picture viewing program.

xxx.yaml saves the metadata information of the map and is used to describe the image. The content format is as follows:

image: /home/rosmelodic/ws02_nav/src/mycar_nav/map/nav.pgm
resolution: 0.050000
origin: [-50.000000, -50.000000, 0.000000]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.196

explain:

image: The path of the described image resource, which can be an absolute path or a relative path.

resolution: Image fragmentation rate (unit: m/pixel).

origin: The 2D pose of the bottom left pixel in the map, which is (x, y, yaw), where yaw is a counterclockwise rotation (yaw = 0 means no rotation).

occupied_thresh: Pixels with an occupancy probability greater than this threshold are considered fully occupied.

free_thresh: Pixels with occupancy less than this threshold are considered completely free.

negate: Whether the white/black free/occupied semantics should be reversed.

Obstacle calculation rules in map_server:

  1. The value of each pixel in the map is between [0,255], white is 255, black is 0, and the value is set to x;
  2. map_server will use the pixel value as the basis for judging whether it is an obstacle, first calculate the ratio: p = (255 - x) / 255.0, white is 0, black is 1 (negate is true, then p = x / 255.0);
  3. According to the ratio calculated in step 2, it is judged whether it is an obstacle. If p > occupied_thresh, it is regarded as an obstacle, and if p < free_thresh, it is regarded as nothing.

Map service used by map_server (map_server)

map_server node description

posted topic

map_metadata (nav_msgs/MapMetaData): Publish map metadata.
map(nav_msgs/OccupancyGrid): map data.

Serve

static_map(nav_msgs/GetMap): Get a map through this service.

parameter

~frame_id (string, default: "map"): Map coordinate frame.

map reading

Raster map data can be read through the map_server node of map_server, and the launch file is written as follows:

<launch>
    <!-- 设置地图的配置文件 -->
    <arg name="map" default="nav.yaml" />
    <!-- 运行地图服务器,并且加载设置的地图-->
    <node name="map_server" pkg="map_server" type="map_server" args="$(find mycar_nav)/map/$(arg map)"/>
</launch>

The parameter is the resource path of the map description file, execute the launch file, and the node will publish the topic: map(nav_msgs/OccupancyGrid)

map display

Use the map component in rviz to display raster maps:

insert image description here

position

The so-called positioning is to calculate the position of the robot itself in the global map. Of course, SLAM also includes the positioning algorithm implementation, but the positioning of SLAM is used to build the global map, which belongs to the stage before the start of navigation, and the current positioning is used for navigation. In navigation, the robot needs to move according to the set route. Through positioning, it can be judged whether the actual trajectory of the robot meets the expectation. The amcl function package is provided in the ROS navigation function package navigation to realize robot positioning in navigation.

Introduction to amcl

AMCL (adaptive Monte Carlo Localization) is a probabilistic localization system for 2D mobile robots. It implements an adaptive (or KLD sampling) Monte Carlo localization method, which can use particle filters to estimate robot positions based on existing maps.

amcl has been integrated into the navigation package, and the navigation installation is also introduced before, the command is as follows:

sudo apt install ros-<ROS版本>-navigation

amcl node description

The core node in the amcl function package is: amcl. In order to facilitate invocation, it is necessary to first understand the topics subscribed to, published topics, services and related parameters of the node.

Subscribed Topic

scan(sensor_msgs/LaserScan): LiDAR data.
tf(tf/tfMessage): Coordinate transformation message.
initialpose(geometry_msgs/PoseWithCovarianceStamped): Used to initialize the mean and covariance of the particle filter.
map(nav_msgs/OccupancyGrid): Get map data.

Published Topic

amcl_pose(geometry_msgs/PoseWithCovarianceStamped): The pose estimation of the robot in the map.
particlecloud(geometry_msgs/PoseArray): Pose estimation collection, which can be subscribed by PoseArray in rviz and then graphically display the pose estimation collection of the robot.
tf(tf/tfMessage): Post the conversion from odom to map.

Serve

global_localization(std_srvs/Empty): Initialize the global localization service.
request_nomotion_update(std_srvs/Empty): A service that manually performs updates and publishes updated particles.
set_map(nav_msgs/SetMap): Service to manually set new map and pose.

invoked service

static_map(nav_msgs/GetMap): Call this service to get map data.

parameter

~odom_model_type(string, default:“diff”)

Odometry model selection: "diff", "omni", "diff-corrected", "omni-corrected" (diff differential, omni wheel) ~odom_frame_id(string, default: "odom"
)

The odometry coordinate system.
~base_frame_id(string, default: "base_link")

Robot polar coordinate system.
~global_frame_id(string, default: "map")

Map coordinate system.
… There are many parameters. The above are a few commonly used parameters. For other parameters, please refer to the official website.

coordinate transformation

The odometer itself can also assist the robot in positioning, but the odometer has cumulative errors and in some special cases (wheel slipping) there will be positioning errors. amcl can estimate the robot's attitude in the map coordinate system, combined with the odometer Improve positioning accuracy.

  • Odometer positioning: just realize the coordinate transformation between /odom_frame and /base_frame through the odometer data.
  • amcl positioning: It can provide coordinate transformation between /map_frame, /odom_frame and /base_frame.
    insert image description here

amcl use

Write the launch file related to the amcl node

Regarding the implementation of the launch file, an example has been given in the example directory under the amcl function package, which can be used as a reference. The specific implementation:

roscd amcl
ls examples

There will be two files listed in this directory: amcl_diff.launch and amcl_omni.launch files, the former is suitable for differential mobile robots, the latter is suitable for omnidirectional mobile robots, you can choose as needed, refer to the former here, create a new launch file, copy amcl_diff.launch file content and modify as follows:

<launch>
<node pkg="amcl" type="amcl" name="amcl" output="screen">
  <!-- Publish scans from best pose at a max of 10 Hz -->
  <param name="odom_model_type" value="diff"/><!-- 里程计模式为差分 -->
  <param name="odom_alpha5" value="0.1"/>
  <param name="transform_tolerance" value="0.2" />
  <param name="gui_publish_rate" value="10.0"/>
  <param name="laser_max_beams" value="30"/>
  <param name="min_particles" value="500"/>
  <param name="max_particles" value="5000"/>
  <param name="kld_err" value="0.05"/>
  <param name="kld_z" value="0.99"/>
  <param name="odom_alpha1" value="0.2"/>
  <param name="odom_alpha2" value="0.2"/>
  <!-- translation std dev, m -->
  <param name="odom_alpha3" value="0.8"/>
  <param name="odom_alpha4" value="0.2"/>
  <param name="laser_z_hit" value="0.5"/>
  <param name="laser_z_short" value="0.05"/>
  <param name="laser_z_max" value="0.05"/>
  <param name="laser_z_rand" value="0.5"/>
  <param name="laser_sigma_hit" value="0.2"/>
  <param name="laser_lambda_short" value="0.1"/>
  <param name="laser_lambda_short" value="0.1"/>
  <param name="laser_model_type" value="likelihood_field"/>
  <!-- <param name="laser_model_type" value="beam"/> -->
  <param name="laser_likelihood_max_dist" value="2.0"/>
  <param name="update_min_d" value="0.2"/>
  <param name="update_min_a" value="0.5"/>

  <param name="odom_frame_id" value="odom"/><!-- 里程计坐标系 -->
  <param name="base_frame_id" value="base_footprint"/><!-- 添加机器人基坐标系 -->
  <param name="global_frame_id" value="map"/><!-- 添加地图坐标系 -->

  <param name="resample_interval" value="1"/>
  <param name="transform_tolerance" value="0.1"/>
  <param name="recovery_alpha_slow" value="0.0"/>
  <param name="recovery_alpha_fast" value="0.0"/>
</node>
</launch>

Write a test launch file

The amcl node cannot be run alone. Before running the amcl node, you need to load the global map first, and then start rviz to display the positioning results. The above nodes can be integrated into the launch file. The content examples are as follows:

<launch>
    <!-- 设置地图的配置文件 -->
    <arg name="map" default="nav.yaml" />
    <!-- 运行地图服务器,并且加载设置的地图-->
    <node name="map_server" pkg="map_server" type="map_server" args="$(find mycar_nav)/map/$(arg map)"/>
    <!-- 启动AMCL节点 -->
    <include file="$(find mycar_nav)/launch/amcl.launch" />
    <!-- 运行rviz -->
    <node pkg="rviz" type="rviz" name="rviz"/>
</launch>

Of course, the package name and file name in the map service node and amcl node in the launch file need to be modified according to your own settings.

implement

1. Start the Gazebo simulation environment first (this process is omitted);

2. Start the keyboard control node:

rosrun teleop_twist_keyboard teleop_twist_keyboard.py

3. Start the launch file that integrated the map service, amcl and rviz in the previous step;

4. In the started rviz, add the RobotModel and Map components to display the robot model and map respectively, add the posearray plug-in, and set the topic to particlecloud to display the current pose of the robot estimated by amcl. The denser the arrows, the current robot is in The higher the probability of this position;

5. Control the movement of the robot through the keyboard, and you will find that the posearray changes accordingly.
insert image description here

route plan

Undoubtedly, path planning is one of the core functions in navigation. The move_base function package is provided in the navigation function package set of ROS to realize this function.

Introduction to move_base

The move_base function package provides an action-based path planning implementation. move_base can control the movement of the robot chassis to the target position according to a given target point, and continuously feed back the robot's own posture and the status information of the target point during the movement process. . As mentioned earlier (7.1) move_base is mainly composed of global path planning and local path planning.

move_base has been integrated into the navigation package, which was also introduced before the navigation installation. The command is as follows:

sudo apt install ros-<ROS版本>-navigation

move_base node description

The core node in the move_base function package is: move_base. In order to facilitate calling, you need to understand the node action, subscribed topics, published topics, services and related parameters.

action

action subscription

move_base/goal (move_base_msgs/MoveBaseActionGoal): The motion planning goal of move_base.
move_base/cancel(actionlib_msgs/GoalID): Cancel the goal.

Action release
move_base/feedback(move_base_msgs/MoveBaseActionFeedback): continuous feedback information, including robot chassis coordinates.
move_base/status (actionlib_msgs/GoalStatusArray): Goal status information sent to move_base.
move_base/result(move_base_msgs/MoveBaseActionResult): operation result (null here).

Subscribed Topic

move_base_simple/goal(geometry_msgs/PoseStamped): Motion planning goal (compared with action, there is no continuous feedback, and the state of robot execution cannot be tracked).

Published Topic

cmd_vel(geometry_msgs/Twist): Motion control messages output to the robot chassis.

Serve

~make_plan(nav_msgs/GetPlan): Request this service to get the planned path for a given target, but do not execute the path plan.
~clear_unknown_space(std_srvs/Empty): Allows the user to directly clear unknown spaces around the robot.
~clear_costmaps(std_srvs/Empty): Allows clearing obstacles in the cost map, which may cause the robot to collide with obstacles, please use with caution.

move_base and cost map

concept

Robot navigation (especially the path planning module) depends on the map. The map has been introduced in SLAM. The map in ROS is actually a picture. This picture has metadata such as width, height, and resolution. The gray value is used in the picture to represent the probability of the existence of obstacles. However, the map built by SLAM cannot be used directly in navigation because:

  • The map constructed by SLAM is a static map, and the obstacle information is variable during the navigation process. The obstacle may be removed, or a new obstacle may be added. Obstacle information needs to be obtained from time to time during navigation;
  • When approaching the edge of the obstacle, although this is a free area, the robot may collide with the obstacle due to other factors after entering the area, such as: inertia, or when the robot with an irregular shape turns. For safety reasons, It is best to set up a warning zone on the edge of the obstacle on the map, and try to prohibit robots from entering...

Therefore, static maps cannot be directly applied to navigation. On the basis of them, some auxiliary information needs to be added to the map, such as obstacle data obtained from time to time, data such as expansion areas added based on static maps.

composition

There are two cost maps: global_costmap (global cost map) and local_costmap (local cost map), the former is used for global path planning, and the latter is used for local path planning.

Both cost maps can be superimposed in multiple layers, and generally have the following levels:

  • Static Map Layer: Static map layer, a static map built by SLAM.

  • Obstacle Map Layer: The obstacle map layer, the obstacle information perceived by the sensor.

  • Inflation Layer: The expansion layer, which expands (expands outward) on the above two-layer map to avoid the robot's shell from hitting obstacles.

  • Other Layers: Custom costmap.

Multiple layers can be freely matched as needed.

insert image description here

collision algorithm

In ROS, how to calculate the cost value? Please see the picture below:

insert image description here
In the figure above, the horizontal axis is the distance from the center of the robot, and the vertical axis is the gray value of the grid in the cost map.

  • Fatal obstacle: The grid value is 254. At this time, the obstacle overlaps with the center of the robot, and a collision must occur;
  • Inscribed obstacle: the grid value is 253. At this time, the obstacle is in the inscribed circle of the robot, and a collision must occur;
  • Circumscribed obstacle: the grid value is [128,252], at this time, the obstacle is in the circumscribed circle of its robot, which is at the critical point of collision, and collision may not necessarily occur;
  • Non-free space: the grid value is (0,127]. At this time, the robot is near the obstacle and belongs to the danger warning area. When entering this area, a collision may occur in the future;
  • Free area: the grid value is 0, where the robot can pass freely;
  • Unknown area: The grid value is 255, and whether there are obstacles has not yet been determined.

The setting of expansion space can refer to non-free space.

move_base uses

The path planning algorithm has been encapsulated in the move_base node of the move_base function package, but it cannot be called directly, because although the algorithm has been encapsulated, the function package is aimed at various types of robots that support ROS, and different types of robots may be large or small Different sizes, different sensors, different speeds, and different application scenarios...may lead to different path planning results in the end, so before calling the path planning node, we also need to configure the robot parameters. The specific implementation is as follows:

  • First write the launch file template
  • Write a configuration file
  • Launch files related to integrated navigation
  • test

launch file

Regarding the call of the move_base node, the template is as follows:

<launch>

    <node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen" clear_params="true">
        <rosparam file="$(find 功能包)/param/costmap_common_params.yaml" command="load" ns="global_costmap" />
        <rosparam file="$(find 功能包)/param/costmap_common_params.yaml" command="load" ns="local_costmap" />
        <rosparam file="$(find 功能包)/param/local_costmap_params.yaml" command="load" />
        <rosparam file="$(find 功能包)/param/global_costmap_params.yaml" command="load" />
        <rosparam file="$(find 功能包)/param/base_local_planner_params.yaml" command="load" />
    </node>

</launch>

The launch file explains:

The move_base node under the move_base function package is started, respawn is false, which means that the node will not be restarted after it is shut down; clear_params is true, which means that the private parameters must be cleared and reloaded every time the node is started; through rosparam will Load several yaml files to configure parameters. The configuration and functions of these yaml files are detailed in the next section.

configuration file

Regarding the preparation of configuration files, you can refer to the path planning implementation of some mature robots, such as: turtlebot3, github link: https://github.com/ROBOTIS-GIT/turtlebot3/tree/master/turtlebot3_navigation/param, download these configurations first The file is spared.

Create a new param directory under the function package, copy the downloaded files to this directory: costmap_common_params_burger.yaml, local_costmap_params.yaml, global_costmap_params.yaml, base_local_planner_params.yaml, and rename costmap_common_params_burger.yaml to: costmap_common_params.yaml.

Configuration file modification and explanation:

costmap_common_params.yaml

This file is a common parameter called by move_base during global path planning and local path planning, including: robot size, safe distance from obstacles, sensor information, etc. The configuration reference is as follows:

#机器人几何参,如果机器人是圆形,设置 robot_radius,如果是其他形状设置 footprint
robot_radius: 0.12 #圆形
# footprint: [[-0.12, -0.12], [-0.12, 0.12], [0.12, 0.12], [0.12, -0.12]] #其他形状

obstacle_range: 3.0 # 用于障碍物探测,比如: 值为 3.0,意味着检测到距离小于 3 米的障碍物时,就会引入代价地图
raytrace_range: 3.5 # 用于清除障碍物,比如:值为 3.5,意味着清除代价地图中 3.5 米以外的障碍物


#膨胀半径,扩展在碰撞区域以外的代价区域,使得机器人规划路径避开障碍物
inflation_radius: 0.2
#代价比例系数,越大则代价值越小
cost_scaling_factor: 3.0

#地图类型
map_type: costmap
#导航包所需要的传感器
observation_sources: scan
#对传感器的坐标系和数据进行配置。这个也会用于代价地图添加和清除障碍物。例如,你可以用激光雷达传感器用于在代价地图添加障碍物,再添加kinect用于导航和清除障碍物。
scan: {
    
    sensor_frame: laser, data_type: LaserScan, topic: scan, marking: true, clearing: true}

global_costmap_params.yaml

This file is used for global costmap parameter settings:

global_costmap:
  global_frame: map #地图坐标系
  robot_base_frame: base_footprint #机器人坐标系
  # 以此实现坐标变换

  update_frequency: 1.0 #代价地图更新频率
  publish_frequency: 1.0 #代价地图的发布频率
  transform_tolerance: 0.5 #等待坐标变换发布信息的超时时间

  static_map: true # 是否使用一个地图或者地图服务器来初始化全局代价地图,如果不使用静态地图,这个参数为false.

local_costmap_params.yaml

This file is used for local costmap parameter settings:

local_costmap:
  global_frame: odom #里程计坐标系
  robot_base_frame: base_footprint #机器人坐标系

  update_frequency: 10.0 #代价地图更新频率
  publish_frequency: 10.0 #代价地图的发布频率
  transform_tolerance: 0.5 #等待坐标变换发布信息的超时时间

  static_map: false  #不需要静态地图,可以提升导航效果
  rolling_window: true #是否使用动态窗口,默认为false,在静态的全局地图中,地图不会变化
  width: 3 # 局部地图宽度 单位是 m
  height: 3 # 局部地图高度 单位是 m
  resolution: 0.05 # 局部地图分辨率 单位是 m,一般与静态地图分辨率保持一致

base_local_planner_params
The basic local planner parameter configuration, this configuration file sets the maximum and minimum speed limits of the robot, and also sets the acceleration threshold.

TrajectoryPlannerROS:

# Robot Configuration Parameters
  max_vel_x: 0.5 # X 方向最大速度
  min_vel_x: 0.1 # X 方向最小速速

  max_vel_theta:  1.0 # 
  min_vel_theta: -1.0
  min_in_place_vel_theta: 1.0

  acc_lim_x: 1.0 # X 加速限制
  acc_lim_y: 0.0 # Y 加速限制
  acc_lim_theta: 0.6 # 角速度加速限制

# Goal Tolerance Parameters,目标公差
  xy_goal_tolerance: 0.10
  yaw_goal_tolerance: 0.05

# Differential-drive robot configuration
# 是否是全向移动机器人
  holonomic_robot: false

# Forward Simulation Parameters,前进模拟参数
  sim_time: 0.8
  vx_samples: 18
  vtheta_samples: 20
  sim_granularity: 0.05

Parameter configuration skills

In the actual operation of the above configuration, it may happen that the robot’s local path planning does not match the global path planning, and the robot enters the expansion area and appears suspended animation. How to avoid this situation as much as possible?

Although the parameters set for global path planning and local path planning are the same, the functions of path planning and obstacle avoidance are different, and different parameter setting strategies can be adopted:

The global cost map can set the expansion radius and obstacle coefficient to be larger;
the local cost map can set the expansion radius and obstacle coefficient to be smaller.
In this way, in the global path planning, the planned path will be as far away from obstacles as possible, while in the local path planning, even if the robot deviates from the global path, it will keep a larger free space between the obstacles, thus avoiding the situation of "fake death" situation.

test

1. Start the Gazebo simulation environment first (this process is omitted);

2. Start the launch file related to navigation;

3. Add the Rviz component (refer to the demo results), which can save the configuration data and call it directly later;

The global costmap and local costmap components are configured as follows:

insert image description here
insert image description here

Navigation and SLAM mapping

Scenario: In 7.2.1 Navigation Realization 01_SLAM Construction, we use the keyboard to control the movement of the robot to realize the construction of the map, and then introduce the realization of the autonomous movement of the robot, so can the two be combined to realize the SLAM of the robot's autonomous movement What about building a map?

The above requirements are feasible. Although there may be doubts, map information is required for navigation. When navigation was implemented before, the
map information was published through the map_server node of the map_server package. If the map is not constructed through SLAM first, how to publish the map information? SLAM will release map information from time to time during the map building process, so there is no need to use map_server anymore. SLAM has already released
map information with the topic /map, and navigation requires a positioning module, and SLAM itself can also achieve positioning.

The process is relatively simple to implement, and the steps are as follows:

  • Write a launch file, integrate SLAM and move_base related nodes;
  • Execute the launch file and test it.

Write a launch file

<launch>
    <!-- 启动SLAM节点 -->
    <include file="$(find mycar_nav)/launch/slam.launch" />
    <!-- 运行move_base节点 -->
    <include file="$(find mycar_nav)/launch/path.launch" />
    <!-- 运行rviz -->
    <node pkg="rviz" type="rviz" name="rviz" args="-d $(find mycar_nav)/rviz/nav.rviz" />
</launch>

test

1. First run the gazebo simulation environment;

2. Then execute the launch file;

3. Set the target point through 2D Nav Goal in rviz, and the robot starts to move autonomously and build a map;

4. Finally, map_server can be used to save the map.

insert image description here

reference

http://www.autolabor.com.cn/book/ROSTutorials/di-7-zhang-ji-qi-ren-dao-822a28-fang-771f29/72-dao-hang-shi-xian/721-dao-hang-shi-xian-01-slam.html

Guess you like

Origin blog.csdn.net/weixin_42990464/article/details/131891266