Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file
Repository Summary
| Checkout URI | https://github.com/KaushalrajPuwar/adaptive-bridge.git |
| VCS Type | git |
| VCS Version | 0.1.0 |
| Last Updated | 2026-05-05 |
| Dev Status | MAINTAINED |
| Released | RELEASED |
| Contributing |
Help Wanted (-)
Good First Issues (-) Pull Requests to Review (-) |
Packages
| Name | Version |
|---|---|
| adaptive_bridge | 0.1.0 |
README
Adaptive Bridge
[](https://docs.ros.org/en/jazzy/) [](https://www.python.org/) [](https://www.eprosima.com/) [](https://cyclonedds.io/) [](LICENSE) []() []() []()In ROS 2 based systems, every subscriber on a topic is coupled to every other subscriber through the DDS writer’s shared history cache. When one subscriber falls behind, perhaps because it is connected over a degraded WiFi link, the entire write pipeline backs up. The publisher stalls, and every consumer of that topic, including safety-critical ones, suffers the same delay. Traditional QoS tuning, such as switching to BEST_EFFORT, helps only at the margins; it does not break the structural coupling between subscribers with fundamentally different latency requirements.
Adaptive Bridge solves this by inserting a lightweight proxy between the publisher and its subscribers. The proxy subscribes to the original topic and republishes each message onto two separate output topics: one for critical consumers and one for noncritical or degraded consumers. A classifier monitors subscriber health through active probes and adjusts per-topic rate limits and drop policies in real time. The critical path is preserved regardless of what happens on the noncritical side. This decoupling means that a visualisation node on a congested WiFi link can experience packet loss and rate limiting without affecting a safety-critical navigation node on the same data stream.
Table of Contents
Features
| Feature | Description |
|---|---|
| Topic splitting | Any configured input topic → dual output topics (critical and noncritical) |
| Generic message types | Works with any ROS 2 message type (LaserScan, Image, Imu, PointCloud2, custom types) |
| Real-time classification | Active probe-based subscriber health monitoring (RTT, loss, jitter) with configurable thresholds |
| State machine |
UNKNOWN → CRITICAL ↔ NONCRITICAL with hysteresis, flap suppression, and forced overrides |
| Policy-driven degradation | Token-bucket rate limiting, stale-drops, queue-overflow drops, mode-based policies (NORMAL / DEGRADED / DISABLED / FAILURE) |
| Dual-vendor DDS | Fully tested on both Fast DDS (eProsima) and Cyclone DDS (Eclipse) |
| Observability | Structured JSON diagnostics payload at 1 Hz with monotonic sequence numbers |
| Safety supervisor | Global mode machine (EMERGENCY / FAILURE) triggered by queue pressure, callback lag, internal error counts |
| Security | Optional HMAC signing + replay protection for classifier control-plane signals |
| Evaluation harness | Docker-based reproducible experiments with Gilbert-Elliot bursty loss (tc/netem), one-command runner, and automated plots |
Architecture Overview
flowchart TB
subgraph Bridge["Adaptive Bridge"]
direction TB
Proxy["Proxy Node
─────────────
• Pre-created pub/sub
• Policy engine
• Rate limiter"]
Classifier["Classifier Node
─────────────
• Probe-based health
• State machine
• Hysteresis"]
end
subgraph Publisher["Publisher"]
P["Publisher
(30 Hz)"]
end
subgraph Consumers["Consumers"]
Critical["Critical Consumer
─────────────
e.g. navigation"]
Degraded["Degraded Consumer
─────────────
e.g. viz over WiFi"]
end
P -- "/topic" --> Proxy
Proxy -- "/critical" --> Critical
Proxy -- "/noncritical" --> Degraded
Proxy -. "subscriber health" .-> Classifier
Key design rule: All publishers are pre-created at startup and never recreated at runtime. Topic routes are frozen after initialization.
File truncated at 100 lines see the full file
CONTRIBUTING
Contributing to Adaptive Bridge
Thank you for your interest in Adaptive Bridge! This document provides guidelines for contributions, development workflow, and code standards.
Code of Conduct
This project is governed by basic open-source etiquette. Be respectful, constructive, and collaborative.
Getting Started
- Fork the repository.
- Create a feature branch from
main. - Make your changes following the guidelines below.
- Run the test suite.
- Submit a pull request with a clear description of your changes.
Development Setup
# Clone your fork
git clone https://github.com/KaushalrajPuwar/adaptive-bridge.git
cd adaptive-bridge
# Build
colcon build --packages-select adaptive_bridge
source install/setup.bash
# Run tests
colcon test --packages-select adaptive_bridge
colcon test-result --verbose
Code Standards
Python
- Python 3.12+ target.
- Type annotations required for all function signatures.
-
f-strings preferred over
%or.format(). - Follow PEP 8 for code style and PEP 257 for docstrings.
- Module-level docstrings are required for all core modules.
- Class docstrings should describe the class’s responsibility and public interface.
Import Order
from __future__ import annotations
# Standard library
import os
import sys
# Third-party
import yaml
from rclpy.qos import QoSProfile
# First-party
from .models import TopicRoute
Commit Messages
- Use the imperative mood (“Add feature” not “Added feature”).
- Reference issue numbers when applicable.
- Keep the first line under 72 characters.
Pull Request Process
- Ensure all tests pass before submitting.
- Update documentation if adding or changing features.
- Add or update tests for new functionality.
- The PR description should explain:
- What the change does
- Why it’s needed
- How it was tested
Adding a New Message Type
- Add the message package to
package.xmldependencies. - Configure the topic in your YAML config:
topics:
- id: "my_topic"
input_topic: "/my/input"
critical_output: "/adaptive_bridge/critical/my"
noncritical_output: "/adaptive_bridge/noncritical/my"
message_type: "my_package/MyMsg"
- Ensure
my_packageis installed in your ROS 2 environment.
Running Evaluation Experiments
See eval/README.md for the experiment harness.
Issue Reporting
When reporting issues, include:
File truncated at 100 lines see the full file