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​