Best way of using nav2 to navigate continuously through indoors and outdoors environments
Hi!
I’m currently working on a robot that has to navigate autonomously in both outdoors and indoors environments. I’m using nav2 to navigate outdoors (GPS) and indoors independently, but switching from one mode to another requires restarting the whole stack; for that reason I was wondering if there would be a proper way of doing this switch in runtime. Some things like the controller, planner, behaviors are the same for both modes, however this is roughly what changes on each.
Outdoors:
- Localization: GPS based, using robot_localization (RL) with the dual ekf architecture
- Global Costmap: Rolling costmap centered on the robot, no static layer, uses some extra custom layers.
- Navigators: Custom BT navigator analogous to
NavigateThroughPoses
but receives GPS poses instead of cartesian poses. GPS poses come from a web based routing engine / map (google maps like)
Indoors:
- Localization: AMCL based, I build a map using slam and then localize in it.
- Global Costmap: Sized according to the static layer holding the map built with SLAM. Some layers that are used outdoors are not used indoors.
- Navigators: NavigateThroughPoses, just the usual setup.
With the above in mind, I see the following challenges:
Localization: When passing a certain transition point (ex: a door, will likely be labeled in both the indoors and outdoors map) the global transform (map
->odom
or map
->base_link
) needs to stop coming from RL and start coming from AMCL if coming from outdoors to indoors (or vice versa). Additionally, when getting indoors the initial pose needs to be set in the location where the transition point is. Things could get easier if indoors and outdoors localization matched cartesianly (meaning that the cartesian coordinates of doors would be the same in both modes), however it could be hard to get this consistency on locations having multiple doors due to SLAM drift at mapping time. RL can’t be used indoors because GPS will suffer severe degradation and will no longer work as an absolute localization source as would the SLAM map + AMCL.
I was thinking the best way to achieve this would be to have a custom lifecycle manager for localization that handles that switch on demand, however unfortunately RL does not use a lifecycle, so that’s a feature I would have to add at least to stop /tf
. That wouldn’t be too complicated IMO but I wanted to ask the community if there could be a better way to do this.
Global Costmap: When switching drive mode, global costmap has to be virtually reset. Layers need to be added or removed, it may start or stop rolling along with the robot and its dimensions / resolution may change dramatically. I’m not sure to what degree this can be achieved using dynamic parameters reconfiguration, so to overcome this I was thinking about having two planner servers (one for indoors and one for outdoors), and managing them through lifecycle. Not very elegant IMO, so I would really appreciate your input on this one.
Navigation / mixed planning - routing: Another challenge is to get a route engine capable of generating routes that start outdoors and end indoors / viceversa. What I think is the best option is to have a node external to nav2 that separates routing (ex: from starting point to door, then from door to final destination), handles all the above switching / lifecycle management for localization / costmaps, and calls the outdoors BT navigator for the outdoors sub-route and the Indoors BT navigator for the indoors sub-route. However I also thought that all this logic could be handled in a custom NavigateThroughIndoors&OutdoorsPoses
BT navigator that could receive a path specifying when switching should be performed.
I would be very happy to hear your feedback on my thoughts and gather other points that you think may be problematic for this application.
Thanks in advance for help!
Asked by Pepis on 2023-02-17 09:39:23 UTC
Answers
I can only speak to r_l
in this case, but navsat_transform_node
was designed to permit moving from indoors to outdoors and vice-versa. The problem, as you said, is generating a consistent coordinate frame between amcl
and your EKF instance.
If it were me, I'd try fuse instead (it's been released for ROS 2). You'll still need navsat_transform_node
from r_l
, but fuse
will let you fuse both the output from navsat_transform_node
and amcl
. Just enable differential mode on one or both of them. There could be some experimentation required; I don't think I've seen anyone try this particular setup yet.
Asked by Tom Moore on 2023-06-05 02:57:10 UTC
Comments