Skip to main content

Architecture Overview

EagleEye Vision System is a multi-threaded, multi-pipeline computer vision backend. This page describes the high-level component interactions, data flow, and thread model.

Component map

┌─────────────────────────────────────────────────────────┐
│ MainBackend │
│ │
│ ┌─────────────────┐ ┌──────────────────────┐ │
│ │ CameraThread │ │ EagleEyeInterface │ │
│ │ Manager │ │ (Flask/SocketIO) │ │
│ │ │ │ │ │
│ │ CameraWorker ─┼───▶│ SSE → WebUI clients │ │
│ │ CameraWorker │ │ │ │
│ └────────┬────────┘ └──────────┬────────────┘ │
│ │ frame+ts │ web_interface │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Pipeline(s) │ │
│ │ FlowManager (topological DAG scheduler) │ │
│ │ ├─ Operation nodes (main + secondary) │ │
│ │ └─ ThreadObjects (parallel branches) │ │
│ └──────────────┬──────────────────────────────────┘ │
│ │ │
│ ┌────────────┴──────────┐ │
│ ▼ ▼ │
│ NetworkTables SSE events │
│ (robot) (WebUI) │
└─────────────────────────────────────────────────────────┘

Data flow

  1. Camera captureCameraWorker threads read from the capture backend in a loop at the camera's target FPS and publish a FramePacket (image plus capture timing) through CameraThreadManager.

  2. Pipeline execution — Each Pipeline has its own thread. The pipeline thread calls FlowManager.run_flow() each frame, pulling the current frame packet from the camera manager.

  3. FlowManager scheduling — Operations are executed in topological timestep order. Operations at the same timestep that occupy different thread slots run concurrently. Single-branch pipelines run on one thread with no synchronization overhead.

  4. Output publishing — Terminal operations in the pipeline write results to NetworkTables (via the injected network_table) and/or to SSE (via the injected web_interface).

  5. WebUI updates — The SSE stream delivers profiling_update, pipeline_operation_errors, system_status, and log_update events to connected browser clients.

Dependency injection

Pipeline construction (src/config/utils/pipeline.py) builds each operation by introspecting its __init__ signature and providing matching objects from the backend:

injectable_dependencies = {
"web_interface",
"network_table",
"camera_manager",
"camera_config_registry",
"camera_configs",
"device_registry",
"model_library",
"mx3_coordinator",
"logger",
}

Any constructor parameter whose name is in that set is provided automatically. The remaining parameters come from action_params in the pipeline config.

Startup sequence

See Startup Sequence for the MainBackend.__init__ order, and the module-level Rust build and config bootstrap that run before it.

Camera system

See Camera System for CameraThreadManager, CameraWorker, and bus ID identification.

SSE and real-time events

See SSE & Real-time for the SSE queue architecture, named events, and background threads.