Mapping
The first and foremost important thing is to have the map of the environment in which we will accomplish rest of the navigation tasks such as localization, path planning and obstacle avoidance. It is assumed that we do not have the map of the environment already. Therefore, we start here and first make the map. This is where we will start to take advantage of various packages available in ROS navigation stack.
ROS nodes used: slam_gmapping, map_saver, map_server
For the purpose of mapping, we need to install the required packages first. Let’s get that out of the way as explained below.
Prerequisites for Mapping
- Install gmapping package: This package provides slam_gmapping node that implements the Simultaneous Localization and Mapping (SLAM) algorithm called gmapping. It is an algorithm that creates a map of the environment in which the robot is driving in as long as it is getting data from a laser sensor and the transforms of the robot. This node subscribes to /tf topic and /laser/scan topic. The output of this node is a 2D occupancy grid map.
The gmapping package can be installed as follows. Take a note of the ROS version. Below, I use melodic version. You will have to install the right package for the ROS version installed on your machine.
$ source /opt/ros/melodic/setup.bash | |
$ sudo apt-get install ros-melodic-gmapping | |
$ cd ~/catkin_ws/ | |
$ catkin_make | |
$ source devel/setup.bash |
- Install map_server package: This package provides two nodes. One is called map_saver which is a command line utility to save the map generated by gmapping node. The second node implemented within this package is called map_server node. This node reads the map from the disk and provides the map to any other node that requests it.
The map_server package can be installed as follows. Take a note of the ROS version. Below, I use melodic version. You will have to install the right package for the ROS version installed on your machine.
$ source /opt/ros/melodic/setup.bash | |
$ sudo apt-get install ros-melodic-map-server | |
$ cd ~/catkin_ws/ | |
$ catkin_make | |
$ source devel/setup.bash |
How to verify that the packages have been successfully installed?
One way of verifying is to make sure rospack can find the package. See expected results below.
$ rospack find gmapping | |
/opt/ros/melodic/share/gmapping (rospack find returns the location) | |
$ rospack find map_server | |
/opt/ros/melodic/setup.bash |
Once, we have installed these two packages, we can run these slam_gmapping and map_saver nodes and complete the mapping process as explained below.
Mapping Steps (How to create the map using ROS packages?)
So far, we have made sure our setup is correct and we have the right packages installed. Now, it is time for actually creating the map. The steps are explained below.
STEP 1 – iN Terminal 1
Task: launch gazebo world, spawn the robot, and launch the teleop node to move the robot
First, bring up the robot and the environment in gazebo. Below is an example. The text in bold represents commands entered by the user and rest of it is the output from the system. I will run the launch file called Main.launch to spawn the robot in gazebo environment. My launch file also launches the teleop node that will be used to move the robot around. You will obviously have to navigate to the place where your files are stored to launch the robot and environment. See the snapshot from Terminal 1 on my machine.
$ source /opt/ros/melodic/setup.bash |
$ cd ~/catkin_ws/ |
$ catkin_make |
#### |
[100%] Built target gazebo_tutorials |
$ source devel/setup.bash |
$ cd src |
$ cd hydra_one_description |
$ cd launch |
$ roslaunch Main.launch |
Below is a snapshot from gazebo for my setup. This is the environment that will be mapped.
At this point, it is also helpful to know what ROS topics are being published. In my case, the following topics are being published. (This is optional – If you would like to see what topic are being published on your setup, run the command $rostopic list in a new terminal). I have bolded some of the topics that are of interest to us at this time.
$ rostopic list |
/base_pose_ground_truth |
/clock |
/cmd_vel |
/gazebo/link_states |
/gazebo/model_states |
/gazebo/parameter_descriptions |
/gazebo/parameter_updates |
/gazebo/set_link_state |
/gazebo/set_model_state |
/hydra_one/front_lower_camera_info |
/hydra_one/front_lower_camera_sensor/image_raw |
/hydra_one/front_lower_camera_sensor/image_raw/compressed |
/hydra_one/front_lower_camera_sensor/image_raw/compressed/parameter_descriptions |
/hydra_one/front_lower_camera_sensor/image_raw/compressed/parameter_updates |
/hydra_one/front_lower_camera_sensor/image_raw/compressedDepth |
/hydra_one/front_lower_camera_sensor/image_raw/compressedDepth/parameter_descriptions |
/hydra_one/front_lower_camera_sensor/image_raw/compressedDepth/parameter_updates |
/hydra_one/front_lower_camera_sensor/image_raw/theora |
/hydra_one/front_lower_camera_sensor/image_raw/theora/parameter_descriptions |
/hydra_one/front_lower_camera_sensor/image_raw/theora/parameter_updates |
/hydra_one/front_lower_camera_sensor/parameter_descriptions |
/hydra_one/front_lower_camera_sensor/parameter_updates |
/hydra_one/laser/scan |
/joint_states |
/odom |
/rosout |
/rosout_agg |
/tf |
/tf_static |
STEP 2 – In terminal 2
Task: launch slam_gmapping node
Next, we start the slam_gmapping node. But before we can start it, we need to create a launch file that will launch the slam_gmapping node. The launch file can be found on the github page. The file is called gmapping_launch.launch. Take a note of the various parameters configured in the file.
Below is the screenshot of Terminal 2 from my machine.
$ source /opt/ros/melodic/setup.bash |
$ cd ~/catkin_ws/ |
$ catkin_make |
#### |
[100%] Built target gazebo_tutorials |
$ source devel/setup.bash |
$ cd src |
$ cd hydra_one_navigation |
$ roslaunch gmapping_launch.launch |
At this point, it is again helpful to know what ROS topics are being published. In my case, the following topics are being published. (This is optional – If you would like to see what topic are being published on your setup, run the command $rostopic list in a new terminal ). The topics in bold are new when compared to the list of topics that were being published before slam_gmapping node was launched.
$ rostopic list |
/base_pose_ground_truth |
/clock |
/cmd_vel |
/gazebo/link_states |
/gazebo/model_states |
/gazebo/parameter_descriptions |
/gazebo/parameter_updates |
/gazebo/set_link_state |
/gazebo/set_model_state |
/hydra_one/front_lower_camera_info |
/hydra_one/front_lower_camera_sensor/image_raw |
/hydra_one/front_lower_camera_sensor/image_raw/compressed |
/hydra_one/front_lower_camera_sensor/image_raw/compressed/parameter_descriptions |
/hydra_one/front_lower_camera_sensor/image_raw/compressed/parameter_updates |
/hydra_one/front_lower_camera_sensor/image_raw/compressedDepth |
/hydra_one/front_lower_camera_sensor/image_raw/compressedDepth/parameter_descriptions |
/hydra_one/front_lower_camera_sensor/image_raw/compressedDepth/parameter_updates |
/hydra_one/front_lower_camera_sensor/image_raw/theora |
/hydra_one/front_lower_camera_sensor/image_raw/theora/parameter_descriptions |
/hydra_one/front_lower_camera_sensor/image_raw/theora/parameter_updates |
/hydra_one/front_lower_camera_sensor/parameter_descriptions |
/hydra_one/front_lower_camera_sensor/parameter_updates |
/hydra_one/laser/scan |
/joint_states |
/map |
/map_metadata |
/odom |
/rosout |
/rosout_agg |
/slam_gmapping/entropy |
/tf |
/tf_static |
Below is additional information. We can see that /tf topic and the /laser/scan topics are now subscribed by the slam_gmapping node.
$ rostopic info /tf |
Type: tf2_msgs/TFMessage |
Publishers: |
* /robot_state_publisher |
* /gazebo |
* /slam_gmapping |
Subscribers: |
* /slam_gmapping |
$ rostopic info /hydra_one/laser/scan |
Type: sensor_msgs/LaserScan |
Publishers: |
* /gazebo |
Subscribers: |
* /slam_gmapping |
$ rostopic info /map |
Type: nav_msgs/OccupancyGrid |
Publishers: |
* /slam_gmapping (http://prabhjot-Lenovo-Y520-15IKBM:37593/) |
Subscribers: None |
Below is the tf tree of the robot. The main difference between this tree and the tree in Figure 1 is that because we now have a slam_gmapping node running, we also have a node called ‘map’ at the very top of the tree, which is connected to odom node.
Also, see the rosgraph below, which shows the relation between various nodes.
STEP 3- IN TERMINAL 3
Task: Visualization in rviz
At this point, we have two things that have been launched. One is the the robot/gazebo environment (launched in Terminal 1) and second is the slam_gmapping node (launched in Terminal 2). One final step before we map the environment is to open Rviz. Rviz allows us to view the map being generated. So, let’s go ahead and launch rviz as shown below.
$ rosrun rviz rviz |
[ INFO] [1595187539.013176288]: rviz version 1.13.9 |
[ INFO] [1595187539.013245476]: compiled against Qt version 5.9.5 |
Below is a snapshot of rviz from my machine. Left side shows the ‘Displays’ that we should have to visualize the necessary things. For Mapping, we should have the following displays.
- LaserScan
- RobotModel
- Map
Go ahead and add these displays and select an appropriate topic to be seen under a particular display.
Also, note that the Fixed Frame must be set to /odom
After all the setup defined above is complete. . . Finally, we can move the robot around and generate the map. Make sure to focus the cursor in Terminal 1. Move the robot around using either the teleop node (keyboard) or the joy node. This will depend on how you have set up your model.
Below is a snapshot from rviz. The left image shows the map being generated by moving the robot around in the environment. The right image shows the actual environment in gazebo.
STEP 4 – IN TERMINAL 4
Task: Save the map.
Finally, after you are satisfied with the generated map (as seen in rviz), it is time to save the map. This is where the map_server package comes into play. This package implements a node called map_saver. This node is used to save the map. Run the following command in a new terminal and specify the name of the file to be saved. IN my case, name of the file is cafe2d
This will create two files: .yaml file and .pgm file. These files will be saved in a directory where the map_saver node was launched.
$ rosrun map_server map_saver -f cafe2d |
[ INFO] [1595189440.119272570]: Waiting for the map |
[ INFO] [1595189440.354455030, 3276.468000000]: Received a 576 X 672 map @ 0.050 m/pix |
[ INFO] [1595189440.354492692, 3276.468000000]: Writing map occupancy data to cafe2d.pgm |
[ INFO] [1595189440.363449567, 3276.477000000]: Writing map occupancy data to cafe2d.yaml |
[ INFO] [1595189440.363543594, 3276.477000000]: Done |
Below is the snapshot of the .pgm file showing the map that was generated following the steps above.
Now, we are basically done with creating the map. The slam_gmapping node that we launched in Terminal 2 can be killed. Press Ctrl+C in Terminal 2 to kill that node.
Step 5 – In Terminal 5
Task: Provide the map
At this point, you can close all terminals except Terminal 1 and Terminal 3. Next, we will open a new terminal and launch the map_server node provided by map_server package (note, this is the same package that provides map_saver node).
As always, in order to run map_server node of the map_server package, we will create a launch file first for that purpose. See the example launch file on this github page. It is called provide_map.launch.
Below are the commands to launch the file to run map_server node.
$ source /opt/ros/melodic/setup.bash |
$ cd ~/catkin_ws/ |
$ catkin_make |
$ source devel/setup.bash |
$ cd src/hydra_one_navigation/launch |
$ roslaunch provide_map.launch |
The map_server node publishes on two topics – /map and /map_metadata. See below.
$ rostopic info /map |
Type: nav_msgs/OccupancyGrid |
Publishers: |
* /map_server |
Subscribers: None |
$ rostopic info /map_metadata |
Type: nav_msgs/MapMetaData |
Publishers: |
* /map_server |
Subscribers: None |
Next, we will see what is on the /map and /map_metadata topics.
$ rostopic echo -n1 /map_metadata
map_load_time:
secs: 2924
nsecs: 877000000
resolution: 0.0500000007451
width: 576
height: 672
origin:
position:
x: -15.4
y: -21.8
z: 0.0
orientation:
x: 0.0
y: 0.0
z: 0.0
w: 1.0
Similarly, we could also echo the map topic as $rostopic echo -n1 /map
Summary – Mapping
Finally, we are done with Mapping aspect of Navigation. To summarize mapping, we essentially did the following three things.
- (Create the map) – Launched the slam_gmapping node which is implemented in the gmapping package. It implements SLAM and allows us to create a map of any environment. This node subscribes to /tf , /odom, and /LaserScan topics. This node publishes on /map and /map_metadata topics.
- (Save the map) – Launched the map_saver node which is implemented in the map_server package. It enables us to save the map generated using slam_gmapping node. This node will create 2 files. A .yaml file and a .pgm file. These files contain the map of the environment.
- (Provide the map) – Launched the map_server node which is implemented in the map_server package. This node provides the map to any other node that requests it. This node publishes on /map and /map_metadata topics. Note the message type on topic /map is nav_msgs/OccupancyGrid.
That is it for mapping! I have included few links in the Troubleshooting section below which helped me troubleshoot my set up when I ran into problems.
If would like to proceed with the next step called Localization, please see the next page. Otherwise, good job with mapping. I hope you enjoyed!
Troubleshooting – Mapping
The following links helped me troubleshoot some of the issues that I ran into. ROS Q/A forum is a great place to start when troubleshooting.
- (gmapping)https://answers.ros.org/question/188700/gmapping-not-working-for-laserscan-obtained-from-but_velodyne_proc/
- (gmapping)https://answers.ros.org/question/198843/need-explanation-on-sensor_msgslaserscanmsg/
- (map_server)https://answers.ros.org/question/9379/roslaunch-and-map_server/?answer=13602?answer=13602#post-id-13602
Great work, nice explanation!
Thanks Vishal!
Great Job!
May I know are you still responsible for GM’s Rd of DMS system? In fact we have a technology seminar for automotive DMS, wonder if we can invite you to attend as a speaker?
Hi Wiesen,
Thanks for the comment. I don’t work in that area anymore.
Thanks