# submaps_display.cpp `src/submaps_display.cpp` implements the `SubmapsDisplay` plugin and the `Trajectory` helper struct declared in `submaps_display.h`. It is the main entry point of the package and is registered as an RViz display plugin at the bottom: ```cpp PLUGINLIB_EXPORT_CLASS(cartographer_rviz::SubmapsDisplay, rviz_common::Display) ``` ## Constants - `kMaxOnGoingRequestsPerTrajectory = 6` — caps concurrent texture queries per trajectory. - `kMaterialsDirectory`, `kGlsl120Directory`, `kScriptsDirectory` — sub-paths under the installed package share directory used to locate the OGRE resources. - `kDefaultTrackingFrame = "base_link"` — default tracking frame. - `kDefaultSubmapQueryServiceName = "/submap_query"` — default service used to fetch textures. ## Constructor The constructor sets up the RViz properties: - `Submap query service` (StringProperty) — triggers `Reset()` when changed. - `Tracking frame` (StringProperty) — used for fading out submaps. - `High Resolution` (BoolProperty, default `true`) and `Low Resolution` (BoolProperty, default `false`) — both connected to `ResolutionToggled()`. - `Submaps` category with `All` and `All Submap Pose Markers` toggles. - `Fade-out distance` (FloatProperty, default `1.f`). It creates a mutually-exclusive callback group and a dedicated `SingleThreadedExecutor`, then creates the `SubmapQuery` service client (QoS defaults differ by `rclcpp` version). It registers the package's `ogre_media/materials`, `.../glsl120`, and `.../scripts` directories with the OGRE resource manager and initialises the resource groups. Finally it creates a TF2 buffer and transform listener. ## Lifecycle - `onInitialize()` calls the base class, creates the `map_node_` scene node at the root, and creates the client. - `reset()` clears the client and all trajectories, then re-creates the client. - The destructor resets the client, clears trajectories, and destroys `map_node_`. ## processMessage Called for every `SubmapList` message: 1. Records the map frame from the header. 2. If any listed submap reports a version older than what is already displayed (meaning the Cartographer node was relaunched), all trajectories are cleared. 3. For every `SubmapEntry`, it creates a `Trajectory` (if new) and a `DrawableSubmap` (if new), enabling the high/low resolution slices per the current property values, and calls `Update()` with the header and entry. 4. Trajectories and submaps no longer present in the message are removed. ## update Called each render frame: - Iterates trajectories, counting in-flight queries, and calls `MaybeFetchTexture()` on submaps in reverse order until `kMaxOnGoingRequestsPerTrajectory` is reached. - Looks up the transform from the map frame to the tracking frame (with a 100 ms timeout) and calls `SetAlpha()` on every submap to fade by z distance; logs a warning if the transform fails. - Applies the map-frame-to-fixed-frame transform to `map_node_`. ## Property toggles - `AllEnabledToggled()` / `PoseMarkersEnabledToggled()` propagate the global toggles to all trajectories. - `ResolutionToggled()` sets slice visibility on every submap. ## Trajectory `Trajectory::Trajectory(...)` moves the visibility property in, connects its `changed()` signal to `AllEnabledToggled()`, and adds a `Submap Pose Markers` child property connected to `PoseMarkersEnabledToggled()`. Both slots propagate the toggle to each `DrawableSubmap` in the trajectory.