ros2_medkit_topic_beacon

This section contains design documentation for the ros2_medkit_topic_beacon plugin.

Overview

The ros2_medkit_topic_beacon package implements a gateway discovery plugin that collects beacon hints from ROS 2 nodes via a shared discovery topic. Nodes publish MedkitDiscoveryHint messages to a configurable topic (default /ros2_medkit/discovery), and the plugin subscribes to receive them in real time.

This plugin implements both the GatewayPlugin and IntrospectionProvider interfaces. It uses the shared ros2_medkit_beacon_common library for hint storage, validation, entity mapping, and response building. See the beacon common design for details on those components.

How It Works

  1. On set_context(), the plugin creates a ROS 2 subscription to the discovery topic

  2. Each incoming MedkitDiscoveryHint message is converted to a BeaconHint

  3. The hint passes through the rate limiter and validator before being stored

  4. On each introspect() call, the store is snapshot and mapped to an IntrospectionResult via BeaconEntityMapper

Key Design Points

Push Model

Unlike the parameter beacon (pull-based polling), the topic beacon is push-based. Nodes actively publish discovery hints at their own cadence. This provides lower latency for discovery updates and avoids the overhead of per-node parameter queries, but requires nodes to include the ros2_medkit_msgs dependency and actively publish beacons.

Rate Limiting

A TokenBucket rate limiter (default 100 messages/second, at most 10000) protects the gateway from beacon floods. The bucket refills continuously and drops excess messages without a log. The rate limiter is thread-safe, as the DDS callback may fire from any executor thread.

configure() replaces a value above its maximum, +inf included, by the maximum, and NaN or a value below the minimum by the minimum, with a warning. The check is the in-range test negated, so NaN fails it. max_hints is read as an int64 before it is narrowed; a 64-bit integer outside 1 to 2147483647 becomes the nearer bound, and a value that is not an integer keeps the default, each with a warning. The parameter parser reads an integer that does not fit in 64 bits as a double, so it keeps the default.

Timestamp Back-Projection

The topic beacon converts the message header stamp (if non-zero) to a steady_clock time point by computing the message age relative to the current wall-clock time and subtracting from steady_clock::now(). This maps ROS time into the monotonic domain used by the BeaconHintStore for TTL computation, avoiding clock-jump artifacts.

Integration with Gateway

The plugin registers the x-medkit-beacon vendor extension capability on Apps and exposes HTTP endpoints for querying individual beacon metadata. Route registration and capability handling follow the standard gateway plugin pattern via PluginContext.