Skip to main content

Limelight API Emulation Plan

This document defines the concrete implementation plan for Limelight emulation in HeliOS. Goal: each HeliOS stream exposes a Limelight-compatible adapter so existing Limelight robot code can connect with minimal or no code changes.

Scope

ItemDecision
Adapter granularityPer stream (one Limelight adapter per HeliOS stream)
Primary transportNT4 table matching Limelight naming conventions
Secondary transportLimelight HTTP endpoints per stream for full drop-in behavior
Feature gateemulate_limelight_api in POST /v1/device/nt4

Out Of Scope

These keys are explicitly not supported in this phase.

KeyDirectionStatus
llpythonReadExcluded
rawbarcodesReadExcluded
imumode_setWriteExcluded
imuassistalpha_setWriteExcluded
llrobotWriteExcluded

Current Runtime Anchors

AreaExisting code
NT publish loopbackend/src/helios-api/src/nt4/bridge.rs
Device NT4 settingsbackend/src/helios-api/src/http/device/nt4.rs
Stream inventory sourcehandles.engine.list_streams() usage in backend/src/helios-api/src/nt4/bridge.rs
Current Limelight ingestion (consumer)backend/src/helios-api/src/http/localization/peers/sources.rs

API Surface For This Phase

Read Keys

KeyTypeMeaningImplementation source
tvdoubleTarget valid (0/1)Detections present
txdoubleHorizontal angle offsetPrimary target solve
tydoubleVertical angle offsetPrimary target solve
txncdoubleHorizontal normalized coordinateTarget center in image
tyncdoubleVertical normalized coordinateTarget center in image
tadoubleTarget areaTarget contour/box area
tldoublePipeline latency msPipeline timing
cldoubleCapture latency msCapture timing
tiddoublePrimary fiducial IDPrimary target ID
t2ddouble[]Aggregate targeting vectorAdapter serializer
botposedouble[]Robot poseLocalization output
botpose_wpibluedouble[]Robot pose blue frameFrame conversion
botpose_wpireddouble[]Robot pose red frameFrame conversion
botpose_orb_wpibluedouble[]MegaTag2 blue variantOptional if available
botpose_orb_wpireddouble[]MegaTag2 red variantOptional if available
targetpose_cameraspacedouble[]Target pose camera framePer-target pose
targetpose_robotspacedouble[]Target pose robot frameRig transform
camerapose_targetspacedouble[]Camera pose target frameInverse transform
camerapose_robotspacedouble[]Camera pose robot frameRig layout
rawfiducialsdouble[]Flat fiducial listDetection flattening
rawdetectionsdouble[]Flat detection listDetection flattening
rawtargetsdouble[]Raw contour targetsContour output flattening
tcornxydouble[]Corner listCorner extraction
jsonstringLimelight JSON payloadHTTP/NT serializer
hbdoubleHeartbeatPer-frame monotonic counter
imudouble[]IMU dataIMU runtime snapshot (if available)

Write Keys

KeyTypeExpected behaviorImplementation mapping
pipelinedoubleSwitch active pipeline indexStream pipeline selection
ledModedoubleLED modeDevice/per-stream lighting command
streamdoubleLimelight stream modeAdapter-level layout mode flag
snapshotdoubleTrigger snapshot when incrementedMedia capture call
cropdouble[4]ROI cropPipeline parameter patch
keystone_setdouble[2]KeystonePipeline parameter patch
throttle_setdoubleProcessing throttleAdapter publish/update throttling
priorityiddoubleTarget preference IDTarget selection heuristic
fiducial_offset_setdouble[]Fiducial offsetsLocalization calibration override
robot_orientation_setdouble[]Orientation assistLocalization input override
fiducial_id_filters_setdouble[]ID allowlistDetection filter
fiducial_downscale_setdoubleFiducial scaleDetector config
camerapose_robotspace_setdouble[]Camera pose setCamera layout update
rewind_enable_setdoubleRewind on/offRecorder state control
capture_rewinddouble[]Capture rewind clipRecorder capture command

HTTP Compatibility Surface

EndpointExpected behaviorHeliOS statusWork needed
/resultsLimelight JSON results payloadMissingAdd per-stream handler + serializer
/statusLimelight status JSONMissingAdd per-stream status projection
Snapshot/capture controlsTrigger captures with LL semanticsMissingBind to media/capture APIs
MJPEG stream URLsLimelight-like stream access patternPartial (HeliOS preview endpoint exists)Add compatible path aliases

Code Implementation Blueprint

Module Layout

ModuleFileResponsibility
Limelight adapter corebackend/src/helios-api/src/nt4/limelight.rsBuild per-stream adapter state, publish read keys
Limelight control loopbackend/src/helios-api/src/nt4/limelight_control.rsSubscribe to write keys and apply translated commands
Limelight serializersbackend/src/helios-api/src/nt4/limelight_types.rsStrong types + array/json flattening helpers
Limelight HTTP routesbackend/src/helios-api/src/http/integrations/limelight.rs/results, /status, snapshot/stream aliases
Adapter registrybackend/src/helios-api/src/nt4/bridge.rsSpawn/stop adapter when emulate_limelight_api is toggled

Runtime State Types

TypeKey fields
LimelightAdapterIdstream_id, table_name
LimelightReadSnapshottv, tx, ty, tid, pose arrays, raw arrays, hb, tl, cl, json
LimelightControlStateLast write values (pipeline, ledMode, crop, etc.), monotonic counters for edge-trigger keys
LimelightPublishCacheLast published values by topic to avoid redundant NT writes

Data Flow

StepOperation
1Enumerate active non-internal streams
2Resolve stream -> Limelight table name
3Build LimelightReadSnapshot from latest stream outputs/localization
4Publish changed NT topics for that stream table
5Update heartbeat and latency fields
6Serve /results and /status from same snapshot serializer
7Consume control writes and apply translated updates to stream/runtime

Publish Loop (Concrete Plan)

ItemPlan
Tick rate20-50 ms loop (not the existing 5 s telemetry cadence)
Snapshot sourceIn-memory latest output cache per stream
BackpressureSkip publish when no data changes except heartbeat/latency
Connection lifecycleRebuild publishers on NT reconnect or stream list changes
IsolationOne adapter state per stream; failure of one stream does not stop others

Control Loop (Concrete Plan)

ItemPlan
Subscription scopeSubscribe to write keys for each stream table
Edge-trigger behaviorTrack previous value for snapshot and capture_rewind counters
ValidationClamp/validate inputs before applying (crop, ranges, array lengths)
Application pathTranslate to existing HeliOS APIs/controllers for streams, media, localization, lighting
Failure handlingReject invalid payloads and emit adapter warning logs without panicking

HTTP Emulation (Concrete Plan)

EndpointImplementation
GET /limelight/{table}/resultsSerialize from LimelightReadSnapshot using Limelight JSON field names
GET /limelight/{table}/statusSerialize adapter + stream + device state
Snapshot trigger endpointIncrement internal control path used by snapshot key
Stream alias endpointRedirect/serve from existing HeliOS preview stream URL

Delivery Phases

PhaseDeliverable
1Read-key NT publish + heartbeat + /results
2Write-key control loop for core controls (pipeline, ledMode, snapshot, crop)
3Remaining in-scope write keys + /status + stream aliases
4Conformance tests against Limelight helper clients

Conformance Test Matrix (In Scope)

TestPass criteria
NT key presenceAll required keys appear with correct types
NT control writebackWriting control keys changes stream behavior predictably
Pose frame correctnessbotpose* and targetpose* match expected coordinate frames
Timing/heartbeathb, tl, and cl update at frame cadence and stay monotonic
HTTP payload parity/results and /status match Limelight field names and shape
Robot integration smokeLimelight helper client runs without code changes

References