Orion::CameraManager Component¶
1. Introduction¶
The Orion::CameraManager component acquires Earth observation imagery for the ORION satellite. In autonomous mode, it periodically fetches Mapbox satellite images from SimSat via HTTP, fuses GPS coordinates from NavTelemetry, and dispatches the raw image buffer to VlmInferenceEngine for triage classification.
CameraManager also supports manual ground-commanded captures via TRIGGER_CAPTURE. Both manual and auto-capture commands are gated to MEASURE mode only.
In a real mission, the SimSat/Mapbox image fetch would be replaced by a hardware camera driver (e.g., a CSI sensor via V4L2).
2. Requirements¶
| Requirement | Description | Verification Method |
|---|---|---|
| ORION-CM-001 | CameraManager shall fetch satellite imagery from SimSat's Mapbox API | System test |
| ORION-CM-002 | CameraManager shall log CameraHardwareError and skip capture when SimSat is unreachable |
System test |
| ORION-CM-003 | CameraManager shall fuse GPS coordinates from NavTelemetry at capture time | Inspection |
| ORION-CM-004 | CameraManager shall dispatch image + GPS to VlmInferenceEngine asynchronously | Inspection |
| ORION-CM-005 | CameraManager shall auto-enable captures on MEASURE entry and disable on exit | System test |
| ORION-CM-006 | CameraManager shall return buffers to the pool on capture failure | Inspection |
| ORION-CM-007 | CameraManager shall emit a warning on buffer pool exhaustion | System test |
3. Design¶
3.1 Data Flow¶
flowchart LR
SS[SimSat :9005] -->|HTTP GET /image/mapbox| CM[CameraManager]
NT[NavTelemetry] -->|navStateGet| CM
CM -->|buffer + lat/lon| VLM[VlmInferenceEngine]
BM[BufferManager] -->|bufferGet 786KB| CM
CM -->|bufferReturn on failure| BM
EA[EventAction] -->|modeChangeIn| CM
RG[RateGroup1 1Hz] -->|schedIn| CM
3.2 Capture Pipeline (doCapture)¶
Each capture executes the following steps:
- Buffer checkout: requests a 786,432-byte (512x512x3 RGB) buffer from BufferManager. If the pool is exhausted, logs
BufferPoolExhaustedand aborts. - Image acquisition: fetches a Mapbox satellite image from SimSat via
SimSatClient::fetchMapboxImage. If SimSat is unreachable or reports no image available, logsCameraHardwareErrorand returns the buffer. - GPS fusion: synchronously queries NavTelemetry via
navStateOutfor the current lat/lon at the exact moment of capture. - Dispatch: fires
inferenceRequestOutasynchronously to VlmInferenceEngine. Buffer ownership transfers. - Telemetry: increments
ImagesCapturedand logsImageDispatchedwith coordinates.
3.3 Image Acquisition¶
SimSat path: SimSatClient::fetchMapboxImage() performs:
- HTTP GET to
ORION_SIMSAT_URL/data/current/image/mapbox(30s timeout) - Checks
mapbox_metadataheader forimage_availableandtarget_visible - Decodes the PNG response via stb_image
- Resizes to 512x512 via stb_image_resize2 if dimensions don't match
- Writes raw RGB bytes directly into the F-Prime buffer
Both stb headers are vendored in Orion/Vendor/ as single-file header-only libraries, avoiding any external image processing dependency.
If SimSat is unreachable or reports no image available (over ocean, cloud cover), captureIntoBuffer logs SimSatImageUnavailable and returns false. The caller logs CameraHardwareError, returns the buffer to the pool, and skips the capture.
3.4 Auto-Capture Timing¶
Auto-capture is driven by the 1 Hz schedIn tick with an internal counter:
- Interval: configurable via
ENABLE_AUTO_CAPTUREcommand (default 85 seconds, minimum 85 seconds) - Enable: automatically on MEASURE entry, or manually via command
- Disable: automatically on any mode exit from MEASURE, or manually via command
- Guard:
schedIn_handlerchecks bothm_autoCaptureEnabledANDm_currentMode == MEASURE
The 85-second minimum exceeds worst-case VLM inference time (~82s measured on the Pi 5), preventing queue buildup.
3.5 Port Diagram¶
| Port | Direction | Type | Description |
|---|---|---|---|
schedIn |
async input (drop) | Svc.Sched |
1 Hz rate group tick for auto-capture timing |
modeChangeIn |
async input | ModeChangePort |
Receives mode broadcasts from EventAction |
bufferGetOut |
output (sync) | Fw.BufferGet |
Checks out a 786KB buffer from BufferManager |
navStateOut |
output (sync) | NavStatePort |
Queries NavTelemetry for GPS at capture time |
inferenceRequestOut |
output | InferenceRequestPort |
Dispatches image + GPS to VlmInferenceEngine |
bufferReturnOut |
output | Fw.BufferSend |
Returns buffer on capture failure |
3.6 Commands¶
| Command | Opcode | Arguments | Behavior |
|---|---|---|---|
TRIGGER_CAPTURE |
0x00 | none | Manual single-shot capture. Rejected with EXECUTION_ERROR if not in MEASURE. |
ENABLE_AUTO_CAPTURE |
0x01 | interval: U32 |
Sets capture interval in seconds and enables auto-capture. Rejected if not in MEASURE. |
DISABLE_AUTO_CAPTURE |
0x02 | none | Stops auto-capture |
3.7 Events¶
| Event | Severity | Description |
|---|---|---|
ImageDispatched |
ACTIVITY_HI | Logged per successful capture with lat/lon coordinates |
BufferPoolExhausted |
WARNING_HI | No free buffers available for capture |
CameraHardwareError |
WARNING_HI | SimSat image fetch failed |
AutoCaptureEnabled |
ACTIVITY_HI | Auto-capture started with interval in seconds |
AutoCaptureDisabled |
ACTIVITY_HI | Auto-capture stopped (manual or mode change) |
SimSatImageUnavailable |
ACTIVITY_LO | SimSat returned no image (over ocean, cloud cover, etc.) |
CommandRejectedWrongMode |
WARNING_LO | Command rejected as not in MEASURE |
CaptureIntervalClamped |
WARNING_LO | Requested interval below 85s minimum, clamped to 85s |
3.8 Telemetry¶
| Channel | Type | Description |
|---|---|---|
ImagesCaptured |
U32 | Running total of images successfully captured and dispatched |
CapturesFailed |
U32 | Running total of captures failed (pool exhaustion or acquisition error) |
3.9 Configuration Constants¶
| Constant | Value | Description |
|---|---|---|
IMAGE_BUFFER_SIZE |
786,432 | 512 x 512 x 3 bytes (raw RGB) |
IMAGE_WIDTH / IMAGE_HEIGHT |
512 | Target image dimensions |
3.10 Environment Variables¶
| Variable | Default | Description |
|---|---|---|
ORION_SIMSAT_URL |
http://localhost:9005 |
SimSat REST API base URL (used by SimSatClient) |
4. Known Issues¶
- Blocking HTTP in capture:
SimSatClient::fetchMapboxImage()blocks the CameraManager thread for up to 30s (libcurl timeout). During this time, commands and mode changes queue up. TheschedInport usesdroppolicy so excess rate group ticks are silently discarded instead of asserting on queue overflow. Withoutdrop, sustained blocking (e.g., slow Mapbox at polar latitudes) fills the queue and triggers a fatalFW_ASSERT. This was observed in the 2026-05-05 simulation run when the satellite reached ~56°S and Mapbox responses slowed down:
EVENT: (268521472) ACTIVITY_LO: (navTelemetry) SimSatPositionUpdate : NavTelemetry: SimSat position Lat=-56.513170, Lon=-7.202748, Alt=810.766838km
Assert: ".../CameraManager/CameraManagerComponentAc.cpp:953" 8
FATAL 16797697 handled.
Exiting with abort signal and core dump file.
The assert value 8 corresponds to Os::Queue::Status::QUEUE_FULL.
5. Change Log¶
| Date | Description |
|---|---|
| 2026-04-17 | Initial implementation: SimSat Mapbox image fetch, auto-capture |
| 2026-04-18 | Added mode-aware auto-capture lifecycle, AutoCaptureDisabled event on mode exit |
| 2026-04-18 | Removed test image fallback; SimSat is sole image source |
| 2026-04-20 | Added mode gating on commands; added CommandRejectedWrongMode event |
| 2026-04-24 | Added CaptureIntervalClamped event; interval clamping with warning |
| 2026-05-03 | Fixed SDD cross-reference links for mkdocs; corrected auto-capture defaults |
| 2026-05-05 | Added drop policy to schedIn port to prevent fatal assert on queue overflow |
| 2026-05-05 | Updated minimum capture interval to 85s as the queue fills up quick (otherwise can drop but will have to handle buffer leak / drop wisely, and now is not the time) |