Skip to content

feat(grid_map_visualization): convert GridMapVisualization to rclcpp_lifecycle::LifecycleNode#532

Open
Lakshya-04 wants to merge 1 commit intoANYbotics:humblefrom
Lakshya-04:feat/lifecycle-node-visualization
Open

feat(grid_map_visualization): convert GridMapVisualization to rclcpp_lifecycle::LifecycleNode#532
Lakshya-04 wants to merge 1 commit intoANYbotics:humblefrom
Lakshya-04:feat/lifecycle-node-visualization

Conversation

@Lakshya-04
Copy link

Motivation

GridMapVisualization runs continuously even when no operator has RViz open, paying the full cost of deserializing every incoming GridMap message and converting it to point clouds / marker arrays for nobody. The existing implementation works around this with a 2 Hz wall timer that polls subscriber counts and lazily subscribes/unsubscribes — but this is inherently racy and adds its own timer overhead.

A lifecycle node solves this cleanly: an external lifecycle manager (e.g. nav2_lifecycle_manager, a mission controller, or a simple launch-time ros2 lifecycle set call) activates the visualization only when a human is monitoring and deactivates it when not needed.

Changes

GridMapVisualization — inherits from rclcpp_lifecycle::LifecycleNode instead of owning an internal rclcpp::Node:

  • on_configure: reads parameters, constructs VisualizationFactory and all configured visualizations
  • on_activate: creates the GridMap subscription and starts processing incoming maps
  • on_deactivate: resets the subscription — zero CPU spent on visualization when inactive
  • on_cleanup / on_shutdown: tears down visualizations and factory

Removes: activityCheckTimer_, isSubscribed_, updateSubscriptionCallback(), and the public nodePtr member.

VisualizationBase, VisualizationFactory, and all concrete visualization classes are unchanged — they accept rclcpp::Node::SharedPtr and receive one via std::static_pointer_cast from the lifecycle node.

grid_map_visualization_node.cpp — spins via get_node_base_interface() (standard lifecycle node spin pattern).

package.xml / CMakeLists.txt — add rclcpp_lifecycle dependency.

Behaviour change

The node now starts in the unconfigured state. It must be transitioned to active before it processes any messages:

ros2 lifecycle set /grid_map_visualization configure
ros2 lifecycle set /grid_map_visualization activate

Or managed automatically via nav2_lifecycle_manager in a launch file.

Test plan

  • Verified node transitions correctly through configure → active → inactive → cleanup via ros2 lifecycle set
  • Confirmed point cloud and occupancy grid visualizations publish when active
  • Confirmed no messages are processed and no subscription exists when inactive
  • Tested on ROS 2 Humble

on_configure: reads parameters, creates VisualizationFactory and all
  configured visualizations
on_activate: creates grid map subscription and starts processing
on_deactivate: resets subscription to stop processing and save CPU
on_cleanup/on_shutdown: teardown visualizations and factory

Removes the wall-timer-based lazy subscription mechanism — lifecycle
state transitions now control when the node subscribes to the grid map
topic, giving external controllers explicit management of visualization
CPU cost.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant