Thanks for your patience, @qazmichaelgw. We’re working on looping in some of the ISAAC team to help us get you more useful answers.
For visualizing messages between components, while not straightforward yet, you could try using the Recorder component (//engine/alice/components/Recorder.hpp/cpp) and tap the messages you want to capture to write as JSON to a Cask file (//engine/gems/cask/cask.hpp/cpp) which is really an LMDB database file. It isn’t ideal for sure, but it could work to help you see what the messaging looks like.
- Could you elaborate a bit more about what you mean by a Map interface?
isaac::map::Map is a codelet that manages a set of layers, including
isaac::map::OccupancyGridMapLayer which reads in the fixed PNG, and
isaac::map::NavigationMap layer. Do you intend to replace this component and then expect the rest of the stack (localizer, planner, etc.) to behave as intended?
Conceptually, there should be no hidden coupling beyond message passing in the graph. A Map interface abstraction should not be necessary or useful here since you should be able to swap out the
isaac::map::Map component with something else that emits Image and Lattice protos.
However, I think I see what you mean by hidden links: one node component is able to get directly reference to another in the same node without needing to establish a graph edge. In
GridSearchLocalizer is getting direct access to
isaac::navigation::NavigationMap by class name, which means you would not be able to swap out
isaac::map::Map with something else entirely. This coupling may make it very difficult to use the rest of the navigation stack with a custom map component.
There are also plenty of assumptions that the map does not change during the lifecycle of these components. The recommended way for now is to restart the nodes with your new map, but I understand that may not be feasible for you.
- The robot world pose appears to be coming from a pose tree hook for world_T_robot which is set using a node’s global frame graph from a Localizer component (GridSearchLocalizer, ParticleFilterLocalization, etc.), which is a hidden link basically. The map of static obstacles itself that GlobalPlanner is using is coming from the components named in the parameter “static_obstacle_names” (default includes “map/isaac.navigation.DistanceMap” which is a component that obtains a
direct reference to
isaac::map::OccupancyGridMapLayer which you wanted to replace)
disable_automatic_start is an annotation for the graph to not start the node with the rest of the application, but only manually through a call to the app backend scheduler to start it. I am not sure yet how you make that call to start the node, but I will investigate.
FiducialAsGoal does not actually use a map but just emits the pose of the fiducial projected to the floor in the frame of the robot continuously.
It would be very helpful to nail down a distilled use case that is as simple as possible but would make it an easy substitution for your method. Basic Fiducial Navigation Sketch.docx (296.0 KB) is a one-pager description of the most basic visual mapping case I could think of, and a slightly more interesting use case Fiducial_GPS Navigation Sketch.docx (301.2 KB) . Could you comment on whether this is similar to your use case or, if we could implement these use cases on top of ISAAC, you would have everything you think you would need?
Even with source, I’m not convinced it would be straightforward to substitute components in the navigation stack the way I think you want to yet. I’d like to determine what those gaps are with this exercise above and find some workarounds for you in the short term to unblock you though.