Preparing a multi-session map: map anchoring, loop-closure, pose-graph relaxation¶
This tutorial will guide you through the process of merging different maps of the same environment together. As an example use case, we will merge the maps generated from the Euroc machine hall 1, 2 and 3 datasets. You can download the unoptimized VI maps from the [[Sample Datasets]] page. Then, optionally, to improve the results, optimize and loop-close each of these maps individually and save the map again.
Merging together different maps¶
Start a maplab console:
roscore& rosrun maplab_console maplab_console
If there are no maps loaded into the console, you can use the following command to merge different VI maps from the file system directly together:
load_merge_all_maps --maps_folder path/to/optimized/euroc_maps
This creates a map in the console that is the product of merging all maps within
You can then confirm that there is a mission for each in the individual maps by typing
maplab <euroc_maps>:/$ ms I1102 13:44:08.304085 7219 vi-map-basic-plugin.cc:973] VI-Map: Mission 0: e4a9a7f9ffffffff0e00000000000000 Viwls Vertices: 3677 Landmarks: 132954 Landmarks by first observer backlink: Camera 0: 132954 (g:31097 b:101857 u:0) Observations: 2319656 Num edges by type: IMU: 3676 Wheel-odometry: 0 Loop-closure: 0 Distance travelled [m]: 84.611516 Start to end time: 2017_11_02_13_44_08 to 2017_11_02_13_44_08 T_G_M unknown Num GPS measurements: 0/0 (UTM/WGS) Mission 1: 0cfe1a24000000000e00000000000000 Viwls Vertices: 3036 Landmarks: 116748 Landmarks by first observer backlink: Camera 0: 116748 (g:28581 b:88167 u:0) Observations: 1883207 Num edges by type: IMU: 3035 Wheel-odometry: 0 Loop-closure: 0 Distance travelled [m]: 78.673416 Start to end time: 2017_11_02_13_44_08 to 2017_11_02_13_44_08 T_G_M unknown Num GPS measurements: 0/0 (UTM/WGS) Mission 2: ec0479dfffffffff0e00000000000000 Viwls Vertices: 2695 Landmarks: 95580 Landmarks by first observer backlink: Camera 0: 95580 (g:29244 b:66336 u:0) Observations: 1467939 Num edges by type: IMU: 2694 Wheel-odometry: 0 Loop-closure: 0 Distance travelled [m]: 134.781190 Start to end time: 2017_11_02_13_44_08 to 2017_11_02_13_44_08 T_G_M unknown Num GPS measurements: 0/0 (UTM/WGS)
Visualizing the map gives the following result:
spatially_distribute_missions v --vis_color_by_mission
Alternative ways to merge maps¶
This section briefly lists alternative ways to merge multiple maps.
load_all --maps_folder path/to/optimized/euroc_maps join_all_maps --target_map_key euroc_maps
join_all_maps merges all loaded maps together into a map given by
load --map_folder path/to/optimized/euroc_maps/MH_01_easy_optimized/ load_merge_map --map_folder path/to/optimized/euroc_maps/MH_02_easy_optimized/ load_merge_map --map_folder path/to/optimized/euroc_maps/MH_03_medium_optimized/
load_merge_map loads the map under the path given by
map_folder and merges it with the selected map.
load --map_folder path/to/optimized/euroc_maps/MH_01_easy_optimized/ load --map_folder path/to/optimized/euroc_maps/MH_02_easy_optimized/ load --map_folder path/to/optimized/euroc_maps/MH_03_medium_optimized/ merge_map --map_key MH_01_easy_optimized merge_map --map_key MH_02_easy_optimized
merge_map merges the map given by
map_key into the selected map.
Each mission defines a baseframe transformation T_G_M.
Initially, this transformation is unknown as we don’t have any information about where the missions should be anchored and what are the transformations between them.
The map statistics command
ms shows this information:
Mission 0: e4a9a7f9ffffffff0e00000000000000 Viwls ... T_G_M unknown Mission 1: 0cfe1a24000000000e00000000000000 Viwls ... T_G_M unknown Mission 2: ec0479dfffffffff0e00000000000000 Viwls ... T_G_M unknown
In the process of mission anchoring, this T_G_M will be estimated. This is done by finding loop closures between a mission with an unknown baseframe and the missions with known baseframes. At least one of the missions needs to be known. We therefore mark an arbitrary mission of the dataset as known:
sbk (short for set mission baseframe to known) operates on the first mission by default and sets its baseframe to known.
This changes the output of
ms to the following:
Mission 0: e4a9a7f9ffffffff0e00000000000000 Viwls ... T_G_M unknown Mission 1: 0cfe1a24000000000e00000000000000 Viwls ... T_G_M known Mission 2: ec0479dfffffffff0e00000000000000 Viwls ... T_G_M unknown
Now we can anchor the other missionsn:
This command (short for anchor all missions) will try to estimate all the unknown baseframe transformation.
The output of
ms should look like this now:
Mission 0: e4a9a7f9ffffffff0e00000000000000 Viwls ... T_G_M known Mission 1: 0cfe1a24000000000e00000000000000 Viwls ... T_G_M known Mission 2: ec0479dfffffffff0e00000000000000 Viwls ... T_G_M known
Additionally, the command
print_baseframes will also provide the values of the estimated transformations:
maplab <euroc_maps>:/$ print_baseframes I1102 14:04:32.419026 10394 vi-map-basic-plugin.cc:1031] Baseframe transformations: Mission 0 (e4a9a7f9ffffffff0e00000000000000): status: known T_G_M: 0.999388 0.0349801 0 0.250711 -0.0349801 0.999388 -0 0.710199 -0 0 1 0.558163 0 0 0 1 Mission 1 (0cfe1a24000000000e00000000000000): status: known T_G_M: 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 Mission 2 (ec0479dfffffffff0e00000000000000): status: known T_G_M: 0.999838 -0.0179926 0 -0.00545835 0.0179926 0.999838 0 0.349317 0 0 1 0.0958929 0 0 0 1
The resulting map will look like this:
Once the missions are anchored in a single coordinate frame, it is worth to relax the map using robust posegraph relaxation. This algorithm looks for matching keyframes between pairs of missions, creates relative 6DoF edges and performs an optimization operating on the odometry and loopclosure edges. The output of the relaxation is a globally consistent map that is a perfect starting point for further refinement (e.g. using visual-inertial least squares).
# Pose graph relaxation to close large loops. relax
Optimization and loop closure¶
Optimization and loop closure can be done like in the single-mission case. Keyframing (
kfh) reduces the number of vertices/landmarks (so complexity of the optimization) and loopclosure (
lc) merges the landmarks and creates visual constraints between missions. Finally,
optvi performs a batch visual-inertial least squares optimization to refine the map geometry.
# (Optional) Key-frame the map. kfh # Loop close the map. lc # Bundle adjustment. optvi