ros2_medkit_gateway
This section contains design documentation for the ros2_medkit_gateway project.
Architecture
The following diagram shows the relationships between the main components of the gateway.
ROS 2 Medkit Gateway Class Architecture
Main Components
GatewayNode - The main ROS 2 node that orchestrates the system - Extends
rclcpp::Node- Manages periodic discovery and cache refresh - Runs the REST server in a separate thread - Provides thread-safe access to the entity cache - Manages periodic cleanup of old action goals (60s interval)DiscoveryManager - Discovers ROS 2 entities and maps them to the SOVD hierarchy - Discovers Areas from node namespaces or manifest definitions - Discovers Components (synthetic groups from runtime, or explicit from manifest) - Discovers Apps from ROS 2 nodes (individual running processes) - Discovers Services and Actions using native rclcpp APIs - Attaches operations (services/actions) to their parent Apps and Components - Uses pluggable strategy pattern: Runtime, Manifest, or Hybrid - Uses O(n+m) algorithm with hash maps for efficient service/action attachment
Discovery Strategies:
RuntimeDiscoveryStrategy - Heuristic discovery via ROS 2 graph introspection - Maps nodes to Apps with
source: "heuristic"- Creates synthetic Components grouped by namespace - Handles topic-only namespaces (Isaac Sim, bridges) via TopicOnlyPolicyManifestDiscoveryStrategy - Static discovery from YAML manifest - Provides stable, semantic entity IDs - Supports offline detection of failed components
HybridDiscoveryStrategy - Combines manifest + runtime - Manifest defines structure, runtime links to live nodes - Best for production systems requiring stability + live status
OperationManager - Executes ROS 2 operations (services and actions) using native APIs - Calls ROS 2 services via
rclcpp::GenericClientwith native serialization - Sends action goals via native action client interfaces - Tracks active action goals with status, feedback, and timestamps - Subscribes to/_action/statustopics for real-time goal status updates - Supports goal cancellation via native cancel service calls - Supports SOVD capability-based control (stop maps to ROS 2 cancel) - Automatically cleans up completed goals older than 5 minutes - Usesros2_medkit_serializationfor JSON ↔ ROS 2 message conversionRESTServer - Provides the HTTP/REST API - Discovery endpoints:
/health,/areas,/components- Data endpoints:/components/{id}/data,/components/{id}/data/{topic}- Operations endpoints:/apps/{id}/operations,/apps/{id}/operations/{op}/executions- Configurations endpoints:/apps/{id}/configurations,/apps/{id}/configurations/{param}- Retrieves cached entities from the GatewayNode - Uses DataAccessManager for runtime topic data access - Uses OperationManager for service/action execution - Uses ConfigurationManager for parameter CRUD operations - Runs on configurable host and port with CORS supportConfigurationManager - Manages ROS 2 node parameters - Lists all parameters for a node via
rclcpp::SyncParametersClient- Gets/sets individual parameter values with type conversion - Provides parameter descriptors (description, constraints, read-only flag) - Caches parameter clients per node for efficiency - Converts between JSON and ROS 2 parameter types automaticallyDataAccessManager - Reads and writes runtime data from/to ROS 2 topics - Uses native rclcpp APIs for fast topic discovery and sampling - Checks publisher counts before sampling to skip idle topics instantly - Returns metadata (type, schema) for topics without publishers - Uses native
rclcpp::GenericPublisherfor topic publishing with CDR serialization - Returns topic data as JSON with metadata (topic name, timestamp, type info) - Parallel topic sampling with configurable concurrency limit (max_parallel_topic_samples, default: 10)NativeTopicSampler - Fast topic sampling using native rclcpp APIs - Discovers topics via
node->get_topic_names_and_types()- Usesrclcpp::GenericSubscriptionfor type-agnostic message sampling - Checkscount_publishers()before sampling to skip idle topics - Returns metadata instantly for topics without publishers (no timeout) - Significantly improves UX when robot has many idle topicsJsonSerializer (ros2_medkit_serialization) - Converts between JSON and ROS 2 messages - Uses
dynmsglibrary for dynamic type introspection - Serializes JSON to CDR format for publishing viaserialize()- Deserializes CDR to JSON for subscriptions viadeserialize()- Converts between deserialized ROS 2 messages and JSON viato_json()/from_json()- Provides staticyaml_to_json()utility for YAML to JSON conversion - Thread-safe and stateless design- Data Models - Entity representations
Area- Physical or logical domain (namespace grouping)Component- Logical grouping of Apps; can besynthetic(auto-created from namespace),topic(from topic-only namespace), ormanifest(explicitly defined)App- Software application (ROS 2 node); individual running process linked to parent ComponentServiceInfo- Service metadata (path, name, type)ActionInfo- Action metadata (path, name, type)EntityCache- Thread-safe cache of discovered entities (areas, components, apps)