Latency Measurement
OCP measures round-trip latency by sending a timestamp from the vehicle, through the operator, and back. If the measured latency exceeds the configured latency_limit (default 500ms), OCP raises the HighLatency fault. See Faults for details.
Timestamp round-trip
The timestamp travels through the following path:
-
Vehicle OCP generates timestamp - OCP creates
ack_time(an elapsed-time timestamp) andack_time_mac(a MAC computed with a private key that is randomized on system start). These are included in the control message sent to the vehicle integration code over TCP. -
Vehicle integration code echoes timestamp - Your code receives the control message, copies
ack_timeandack_time_macinto the response message, and sends it back to OCP over the same TCP connection. See Vehicle side for the message format. -
OCP embeds timestamp in video - OCP takes the returned timestamps and embeds them as metadata (SEI) in the outgoing video stream.
-
Video is transmitted - Oden transmits the video from vehicle to operator.
-
Operator OCP extracts timestamp - OCP on the operator side makes the timestamp available to the operator environment (web view or shared data).
-
Operator echoes timestamp back - The timestamp is returned to OCP on the operator side. How this happens depends on the operator configuration.
-
Timestamp sent to vehicle - OCP includes the returned timestamp in the next control message sent back to the vehicle.
-
Vehicle OCP validates and measures - OCP validates the timestamp via the MAC to ensure the timestamp was not tampered with, then computes the round-trip latency as
current_time - returned_ack_time.
The ack_time and ack_time_mac values must be passed through unmodified at every step. The either is validated on the vehicle; if it does not match, the timestamp is rejected and latency measurement will not work.
|
The measured latency includes: vehicle integration processing time, video transmission latency including network, and operator processing time.
Operator configurations
On the operator side, OCP reads the gamepad directly and sends it as controller input unless ocp_disable_gamepad is set (see Disabling OCP gamepad input). The timestamp echo-back and optional user data depend on how the operator side is configured.
There are four configurations. In all cases, OCP handles the gamepad — the difference is in how timestamps are echoed back and how user data flows.
OCP only (no web view, no custom plugin)
OCP reads the gamepad and sends control commands. OCP handles the timestamp round-trip internally by extracting the timestamp from the incoming video stream and echoing it back in the next control message. Latency measurement works out of the box. No user data is sent.
This is the simplest configuration.
Web view
When a web view is active, the web view handles the timestamp echo. OCP still reads and sends gamepad input by default.
The web view handles two cases automatically:
-
No custom JS sends data: The web view auto-echoes the timestamp on its own. No user data is sent.
-
Custom JS calls
sendNamedUserMessage: The web view stops auto-echoing and instead injects the timestamp into eachsendNamedUserMessagecall. Custom data can be sent to the vehicle.
odenClient.sendNamedUserMessage("ocp_client_user_data", {
active_vehicle: "my_vehicle",
client_user_data: {
"my_vehicle": {
user_data: { steering_mode: "manual" },
ocp_disable_gamepad: false
}
}
});
See Operator side for the full web view API.
Player-side TCP
An external application connects to the player-side TCP server and handles the timestamp echo. The application reads ack_time and ack_time_mac from the vehicle feedback data and returns them as ack_time_returned and ack_time_mac_returned in the client data message. See Player side TCP for details.
Custom operator plugin (no web view)
A custom Oden plugin handles the timestamp echo and can provide its own user data. The plugin uses shared data channels to communicate with OCP:
- Reading from OCP
-
The plugin reads the
vehicle_ocpshared data, which containsVehicleFeedbackDataincludingack_time(u64) andack_time_mac(u32). - Writing back to OCP
-
The plugin publishes to the
client_ocpshared data with the following fields:-
ack_time_returned- theack_timevalue fromvehicle_ocp, passed through unmodified -
ack_time_mac_returned- theack_time_macvalue fromvehicle_ocp, passed through unmodified -
user_data- optional custom data to send to the vehicle -
ocp_disable_gamepad- optional, see Disabling OCP gamepad input
-
See Plugins for general plugin information. Contact your representative for the plugin SDK.
Disabling OCP gamepad input
By default, OCP reads the connected gamepad and sends it as controller input to the vehicle. This can be disabled by setting ocp_disable_gamepad: true in the data sent back to OCP (from the web view, a custom plugin, or a player-side TCP client).
When ocp_disable_gamepad is set to true:
-
OCP stops sending gamepad controller input to the vehicle.
-
The
InputLostfault is suppressed (since no gamepad input is expected). -
The web view, plugin, or TCP client is responsible for providing control input through its own means.
This is used when the operator interface provides its own control scheme - for example, a custom web UI with on-screen controls or a plugin that reads from a different input device.
Client data source locking
By default, OCP handles timestamp echo-back internally — no external client data source is needed and latency measurement works out of the box.
This default behavior can be overridden by exactly one external source: web view, custom plugin, or player-side TCP. The first source that sends client data to OCP becomes the locked source. Once locked, OCP only accepts data from that source.
If OCP detects data from a second source after locking, it treats this as a configuration error:
-
An error is logged identifying both the locked source and the conflicting source.
-
All client data communication is stopped — including from the source that was previously working.
-
A restart is required to recover.
This strict behavior exists because multiple sources sending timestamps and user data simultaneously would cause unpredictable latency measurement and control behavior. Rather than silently producing wrong results, OCP fails visibly.
Summary
| Configuration | Gamepad input | Timestamp echo | User data |
|---|---|---|---|
OCP only |
OCP reads & sends |
OCP self-echoes from video |
None |
Web view, no custom JS |
OCP reads & sends |
Web view auto-echoes |
None |
Web view + custom JS |
OCP reads & sends (unless disabled) |
Web view auto-injects into |
Via web view JS |
Custom plugin |
OCP reads & sends (unless disabled) |
Plugin reads |
Via plugin shared data |
Player-side TCP |
OCP reads & sends (unless disabled) |
TCP client reads |
Via TCP JSON messages |