I would like to use rtabmap to localize a robot in different floors. For example, I want to build a map of the 1st floor and then take the elevator/stairs, go to the 2nd floor and build the map. Then, use rtabmap in localization mode. I wonder which would be the best way to use rtabmap in this case:
1) Make one single db with information of both floors.
2) Make one db for each floor
a) In 1), if we take the elevator, for example, odometry would not detect the height change so we need an external source with height information to “shift” the current position to the second floor and continue mapping. Is it possible to add such external source to rtabmap when building the map? Does this “shift” cause any problem during localization?
b) In 1), some environments have very similar areas in different floors so I assume that rtabmap would not be able to differentiate the 1st floor from the 2nd one in some areas, so wrong loop closings would happen. Is there anyway we can set the close looping parameters to avoid such wrong matchings (using height information, for example)?
c) In 2), I assume that wrong loop closings would be avoided. However, how can I dynamically change the dbs for each floor without restarting rtabmap? Is there anything similar to “parameters update” which can simply receive the floor information and ask rtabmap to load the correct db?
I would appreciate any advice regarding this topic. Thanks!
a) That height change could be fused to odometry before feeding it to rtabmap. However, when the robot will exit the elevator at the second floor, it will overwrite the first floor if it is still in the same map. When detecting that you are about to change floor, we can trigger a new map either by setting large covariance values (>=9999) in odometry topic or by calling service "rosservice call /rtabmap/trigger_new_map".
b) Yeah, even if you split the internal maps like in a), the robot could jump between the floors if the layout is very similar. We would have to implement a mechanism like the GPS approach shown in this example, where loop closure detection is done only in a fixed radius around the current GPS position. In code, in this for loop, it is where we select signatures to compare, that height difference could be added here to filter signatures. This would have to be done by comparing z value of odometry poses (this assumes that if odometry is starting at floor 2, it as always the same height, barometric sensors can give an idea of the current height, but it should be calibrated against the pressure at sea level in the same area). Another approach for odometry to know which height to set would be to add an apriltag at each floor, so when the robot sees it, it knows at which floor it is and initializing odometry at the right height.
c) There is no service to do that. You would have to kill rtabmap node, then spawn another rtabmap node with the other database. Creating such service would not be that hard to do though.
Sorry for bringing up an old thread, but I noticed the GridGlobal/AltitudeDelta parameter that might be useful in solving this issue. Would a workflow like this work for preplanned-map multi-storey navigation?
1) Map using rtabmap mapping mode. Whenever we reach a new floor, we can trigger a new map using 'rosservice call /rtabmap/trigger_new_map'.
2) In preplanned map navigation, we can send navigation goals up to different floors. Since rtabmap localizes the robot in 3D (with height), we can set the GridGlobal/AltitudeDelta parameter such that nodes around this deltaZ will be rendered. That way, we have 2d maps loaded for each specific floors.