Building a Map with a RIA-E100

In this tutorial, you will learn how to build your own map using the RP-LIDAR sensor attached to your RIA-E100.

Tip

In this tutorial, you will:

  • Learn how to build a map with a RIA-E100
  • Understand the stucture of a map in navigation stack of ROS
  • Recognize the configuration files that are responsible for building a map in ROS.

Warning

Make sure that you already made the tutorial on demo-apps.

Note

Learn ROS and get your ROS certificate by enrolling in the Udemy course (Highest Rated course) ROS for Beginners: Basics, Motion and OpenCV.

Learn about ROS2: ROS Next Generation by enrolling in the Udemy course ROS2 How To: Discover Next Generation ROS

Running the Map Building Experiments

Overview

First, you need to start the robot drivers and then start the ROS node responsible for building the map. It has to be noted that to build a map ROS uses the gmapping or hector software packages, that is fully integrated with ROS. The gmapping and hector packages contains a ROS wrapper for OpenSlam’s Gmapping. The packages provide laser-based SLAM (Simultaneous Localization and Mapping), as a ROS node called slam_gmapping and slam_hector. Using slam_gmapping or slam_hector, you can create a 2-D occupancy grid map (like a building floorplan) from laser and pose data collected by a mobile robot.

SLAM Background

SLAM refers to Simultaneous Localization and Mapping. It is the process of building a map using range sensors (e.g. laser sensors, 3D sensors, ultrasonic sensors) while the robot is moving around and exploring an unknown area. The range sensor is used to detect the distance to obstacle whose estimated locations will be stored into a data structure (e.g/ 2D array) and when the robot is moving, it keeps updating this data structure and setting each cell either occupied or empty based on the estimation of its location and the estimation of the distance to the obstacle. Usually, this process uses filtering techniques like Kalman filters or praticle filters to improve the estimation of obstacle while moving and removing noise and errors from measurements. An example of error of measurement is the measure of odometry which known to be imprecise and is subject to cumulative errors over time. In addition, range sensors are another source of errors. The filtering technique allow to attenuate the effect of these errors onto the precision of the map. Large errors of odomerty and/or range sensors will result into inaccurate and skewed maps.

Hint

For a more technical introduction to SLAM, consider the following references

Starting the nodes

To start the robot, on the master node (the robot machine) run the following commands, on three terminals:

roscore
roslaunch e100_bringup minimal.launch
roslaunch e100_navigation slam_hector.launch

To drive the robot from your workstation, then, on your workstation (the host node), run the following commands on two terminals:

roslaunch e100_description view.launch
roslaunch e100_teleop keyboard.launch

Warning

If you execute the following command on your workstation (recommended), you must make sure to have correctly set-up the network configuration as explained in demo-apps. It is not recommended to start description launch file on the robot machine as rviz may overload the robot.

If all is fine, start moving the robot around using keyboard_teleop application or a joytsick and watch the RViz GUI as the map starts to be built-up.

Finally you will end-up with a map looking like this one:

../_images/ria_e100_map.png

Now, save the built map you just created by running the following command:

rosrun map_server map_saver -f /tmp/my_map

Note

The tmp folder gets cleaned everytime the system is rebooted, so after saving the map you can move the files to another location. Alternatively, you can specify another folder of your choice to save the map when running the map_saver command.

You can double click on the pgm file to see the generated map.

Analyzing the Generated Map

The previous command will generate two files with the name you specified in the map_server commnd. So in this case, the two files’ names are my_map.pgm and my_map.yaml. If you open the .yaml file you will see something like this:

image: /tmp/my_map.pgm
resolution: 0.050000
origin: [-12.200000, -12.200000, 0.000000]
negate: 0
occupied_thresh: 0.65
free_thresh: 0.196

The .yaml contains meta data about the map, including the location of image file of the map, its resolution, its origin, the occupied cells threshold, and the free cells threshold. Here are the details for the different parameters:

  • image: has a pgm format which contains numeric values between 0 and 255. It represents the path to the image file containing the occupancy data; can be absolute, or relative to the location of the YAML file
  • resolution: it is the resolution of the map and is expressed in meters/pixel, which means in our example 5 centimers for each cell (pixel).
  • origin: The 2-D pose of the lower-left pixel in the map, as (x, y, yaw), with yaw as counterclockwise rotation (yaw=0 means no rotation). Many parts of the system currently ignore yaw.
  • occupied_thresh: Pixels with occupancy probability greater than this threshold are considered completely occupied.
  • free_thresh: Pixels with occupancy probability less than this threshold are considered completely free.
  • negate : Whether the white/black free/occupied semantics should be reversed (interpretation of thresholds is unaffected)

Now, for the second file, that is the .pgm image file, it is just a gray-scale image of the map which you can open using any image editor program and it will look like this:

../_images/pgm_map.png

Tip

It is recommended to use the The GNU Image Manipulation Program to open and edit PGM files.

The gray area represents an unknown non-explored space. The white area represents the free space, and the black area represents obstacles (e.g. walls).

You can open this file with any text editor like gedit or kate to see its content. In what follow, we present the four first lines of a typical pgm file.

P5
# CREATOR: GIMP PNM Filter Version 1.1
600 600
255

The first line, P5 identifies the file type. The third line identifies the width and the length in number of pixels. The last line represents the maximum gray scale, which is this case 255 that represents the darkest value. The value 0 in a PGM file will represent a free cell.

Tip

For more details about pgm file format, refer to PGM documentation.

What is in the background?

When you run the command

roslaunch e100_navigation slam_hector.launch

the slam_hector.launch file will be exectued. Here is the content of that file:

 <?xml version="1.0"?>

<launch>
    <!-- start hector slam -->
    <node pkg="hector_mapping" type="hector_mapping" name="hector_mapping" output="screen">
        <!-- Topic names -->
        <param name="scan_topic" value="scan" />
        <!-- Frame names -->
        <param name="base_frame" value="base_footprint" />
        <param name="map_frame" value="map" />
        <param name="odom_frame" value="odom"/>
        <!-- Tf use -->
        <param name="use_tf_scan_transformation" value="true"/>
        <param name="use_tf_pose_start_estimate" value="false"/>
        <param name="pub_map_odom_transform" value="true"/>
        <!-- <param name="pub_odometry" value="true"/> -->
        <param name="advertise_map_service" value="true"/>
        <param name="pub_map_scanmatch_transform" value="true"/>
        <param name="tf_map_scanmatch_transform_frame_name" value="scanmatcher_frame"/>
        <!-- Map size / start point -->
        <param name="map_resolution" value="0.050"/>
        <param name="map_size" value="2048"/>
        <param name="map_start_x" value="0.5"/>
        <param name="map_start_y" value="0.5" />
        <param name="map_multi_res_levels" value="2" />
        <!-- Map update parameters -->
        <param name="update_factor_free" value="0.4"/>
        <param name="update_factor_occupied" value="0.9" />
        <param name="map_update_distance_thresh" value="0.1"/>
        <param name="map_update_angle_thresh" value="0.04" />
        <param name="map_pub_period"             value="2" />
        <param name="laser_z_min_value"          value= "-0.1" />
        <param name="laser_z_max_value"          value= "0.1" />
        <param name="laser_min_dist"             value="0.12" />
        <param name="laser_max_dist"             value="10.5" />
        <!-- Debug parameters -->
        <!-- <param name="pub_drawings" value="true"/>
        <param name="pub_debug_output" value="true"/> -->
    </node>
    <!-- start path helper -->
    <node pkg="hector_trajectory_server" type="hector_trajectory_server" name="hector_trajectory_server" output="screen">
        <param name="target_frame_name" type="string" value="/map" />
        <param name="source_frame_name" type="string" value="/base_link" />
        <param name="trajectory_update_rate" type="double" value="4" />
        <param name="trajectory_publish_rate" type="double" value="0.25" />
    </node>

</launch>

You can observe it sets some parameters to their default values and specifies that the scan topic is refered to as /scan. Then, it will start the slam_hector.launch that contains the specific parameters of the hector SLAM algorithm (parameters of the particle filter) that is responsible for building the map.

Practical Considerations and Observations

When building a map with a RIA-E100 it is possible to get a good or bad map depending on several factors. First of all, make sure that your RIA-E100 robot and its laptop have full batteries before starting the mapping tasks. In fact, gmapping and rviz both consume alot of power resources.

The quality of the generated map greatly depends on quality of range sensors and odometry sensors. For the RIA-E100, it has RPLIDER with 8 meters of range, and 360 degree of laser beam angle, which make it appropriate for scanning large and open space environments.

References

Here are some useful reference to learn more about building maps using ROS.

  • gmapping package: This package contains a ROS wrapper for OpenSlam’s Gmapping. The gmapping package provides laser-based SLAM (Simultaneous Localization and Mapping), as a ROS node called slam_gmapping. Using slam_gmapping, you can create a 2-D occupancy grid map (like a building floorplan) from laser and pose data collected by a mobile robot.
  • slam_gmapping package: slam_gmapping contains a wrapper around gmapping which provides SLAM capabilities.
  • OpenSLAM Gmapping: GMapping is a highly efficient Rao-Blackwellized particle filer to learn grid maps from laser range data.
  • map_server: map_server provides the map_server ROS Node, which offers map data as a ROS Service. It also provides the map_saver command-line utility, which allows dynamically generated maps to be saved to file.

Video Demonstration

Review questions

  • Apply this tutorial to build a map of your office or room. Observe the map and provide comments on its accuracy.
  • Use The GNU Image Manipulation Program to edit the generated map. Try to enhance the walls structure and remove erronous obstacle. Save the new file as PGM.
  • Open the new PGM file and observe its content.
  • What is the role of the map_server package?
  • Whick package is responsible for building the map in ROS?
  • Explain briefly the need for a range sensor and motion sensor to build the map of a moving robot.
  • How a map is represented in ROS? What is the relation between the yaml file and the pgm file?
  • Which specific launch file is responsible for executing the gmapping algorithm and initialize its parameters?