Components¶
Bubbaloop components are the building blocks of physical AI systems. Each component is a specialized node (Bubble) that connects to the Zenoh message bus (Loop).
Component Types¶
flowchart TB
subgraph Sensors["Sensors (Input)"]
direction LR
cam[RTSP Camera]
imu[IMU]
lidar[LiDAR]
end
subgraph Services["Services (Processing)"]
direction LR
weather[OpenMeteo]
ml[ML Inference]
compute[Compute]
end
subgraph Actuators["Actuators (Output)"]
direction LR
motor[Motors]
servo[Servos]
speaker[Speakers]
end
subgraph Core["Zenoh Message Bus"]
zenoh((Zenoh))
end
Sensors --> zenoh
zenoh <--> Services
zenoh --> Actuators
Sensors¶
Sensors capture data from the physical world and publish it to the message bus.
| Component | Type | Status | Description |
|---|---|---|---|
| RTSP Camera | Rust | Available | H264 video capture via GStreamer with SHM raw frames |
| System Telemetry | Python | Available | CPU, memory, disk, network, load metrics via psutil |
| Network Monitor | Python | Available | HTTP, DNS, ICMP ping health checks |
| OpenMeteo | Python | Available | Weather data from Open-Meteo API (current, hourly, daily) |
| GPIO Sensor | Rust | Planned | GPIO pin monitoring |
Processors¶
Processors subscribe to data streams and publish derived results.
| Component | Type | Status | Description |
|---|---|---|---|
| Camera Object Detector | Python | Available | YOLO11 object detection on camera raw frames (SHM) |
| Camera VLM | Python | Available | Scene description using vision language models on camera frames (SHM) |
Actuators¶
Actuators interact with the physical world based on commands received via the message bus.
| Component | Type | Status | Description |
|---|---|---|---|
| Motor Controller | — | Planned | DC/stepper motor control |
| Servo Controller | — | Planned | Servo position control |
| Audio Output | — | Planned | Text-to-speech, alerts |
Component Structure¶
Each component follows a common pattern:
┌─────────────────────────────────────┐
│ Component Node │
├─────────────────────────────────────┤
│ Configuration (YAML) │
│ └─ Settings, parameters │
├─────────────────────────────────────┤
│ Publishers │
│ └─ Output topics and messages │
├─────────────────────────────────────┤
│ Subscribers (optional) │
│ └─ Input topics for control │
├─────────────────────────────────────┤
│ Processing Logic │
│ └─ Data capture, transformation │
└─────────────────────────────────────┘
Creating Components¶
Components are implemented using the Node SDK (Rust or Python):
Rust (Node SDK)¶
use bubbaloop_node::{Node, NodeContext, JsonPublisher};
struct MySensor { publisher: JsonPublisher }
#[bubbaloop_node::async_trait::async_trait]
impl Node for MySensor {
type Config = serde_yaml::Value;
fn name() -> &'static str { "my-sensor" }
fn descriptor() -> &'static [u8] {
include_bytes!(concat!(env!("OUT_DIR"), "/descriptor.bin"))
}
async fn init(ctx: &NodeContext, _cfg: &Self::Config) -> anyhow::Result<Self> {
Ok(Self { publisher: ctx.publisher_json("data").await? })
}
async fn run(self, ctx: NodeContext) -> anyhow::Result<()> {
let mut shutdown = ctx.shutdown_rx.clone();
loop {
tokio::select! {
_ = shutdown.changed() => break,
_ = tokio::time::sleep(std::time::Duration::from_secs(1)) => {
self.publisher.put(&serde_json::json!({"value": 42})).await?;
}
}
}
Ok(())
}
}
Python (Node SDK)¶
from bubbaloop_sdk import run_node
class MySensor:
name = "my-sensor"
def __init__(self, ctx, config):
self.ctx = ctx
self.pub = ctx.publisher_json("data")
def run(self):
while not self.ctx.is_shutdown():
self.pub.put({"value": 42})
self.ctx._shutdown.wait(timeout=1.0)
if __name__ == "__main__":
run_node(MySensor)
The SDK handles Zenoh session, health heartbeats, schema queryable, config loading, and shutdown automatically.
Component Communication¶
Components communicate via two Zenoh key spaces:
flowchart LR
sensor[Sensor] -->|"global/…/compressed"| dashboard[Dashboard]
sensor -->|"local/…/raw (SHM)"| processor[Processor]
processor -->|"global/…/detections"| agent[AI Agent]
- Global topics are network-visible (dashboard, CLI, remote machines)
- Local topics are SHM-only (zero-copy, same machine)
See Messaging for protocol details and Topics for naming conventions.
Next Steps¶
- Create Your First Node — Step-by-step tutorial
- Topics — Topic naming conventions
- Messaging — Pub/sub patterns and SDK usage
- Node Marketplace — Installing and publishing nodes