OpenRoadCode IDD: Automotive Vehicle State

Source: docs/idd/automotive_vehicle_state.md

Status

  • Contract: openroad.vehicle.state
  • Current version: 5
  • Initial transport: ZeroMQ PUB/SUB
  • Payload encoding: JSON

This document defines the public OpenRoadCode vehicle-state dissemination contract. Producers may obtain the data from OBD-II, CAN, a simulator, a gateway, or another implementation. Consumers must not depend on the producer’s hardware or acquisition mechanism.

Message framing

The ZeroMQ representation uses two frames:

  1. Topic frame: UTF-8 string openroad.vehicle.state
  2. Payload frame: JSON object defined below

Subscribers may use the topic frame for ZeroMQ subscription filtering.

Envelope

{
  "version": 1,
  "timestamp": {
    "seconds": 1787333234,
    "nanoseconds": 123456000
  },
  "source": "obd2",
  "data": {
    "engine_speed_rad_s": 298.14,
    "vehicle_speed_m_s": 18.88,
    "throttle_position": 0.314,
    "accelerator_pedal_position": null,
    "engine_load": 0.467,
    "intake_manifold_pressure_pa": 126000,
    "barometric_pressure_pa": 99000,
    "boost_pressure_pa": 27026.0,
    "mass_air_flow_kg_s": 0.0187,
    "coolant_temperature_k": 363.15,
    "intake_air_temperature_k": 303.15,
    "fuel_level": 0.635,
    "control_voltage_v": 14.2
  }
}

version

Unsigned contract version. Versions 1 through 5 are supported for decoding. Producers emit Version 5. A producer must emit the version corresponding to the payload schema it is publishing.

timestamp

UTC Unix epoch time for the vehicle-state snapshot.

Field IDD type Meaning
seconds uint64 Whole seconds since 1970-01-01T00:00:00 UTC
nanoseconds uint32 Fractional nanoseconds within the second, range 0..999,999,999

Negative epoch timestamps are invalid. The timestamp describes the snapshot time, not message-receipt time. This is a wall-clock timestamp and is not a monotonic clock value.

source

UTF-8 string identifying the producer or acquisition source for diagnostics. Examples include obd2, simulator, socketcan, or an implementation-specific gateway name. Consumers must not use source to determine the semantic meaning of the vehicle data.

SI unit policy

All physical quantities in OpenRoadCode public messaging contracts use SI units. Automotive conventions such as RPM, mph, psi, degrees Fahrenheit, and grams per second are converted at the contract boundary.

Dimensionless normalized quantities use the range 0.0..1.0 rather than percentages.

Unit-bearing field names include the unit suffix to keep captures and diagnostic output self-describing.

Vehicle data fields

Every Version 4 field below must be present in data. If a nullable value is unsupported, unavailable, or stale beyond the producer’s validity policy, its JSON value is null.

Field JSON type SI unit / range Nullable Meaning
engine_speed_rad_s number rad/s yes Engine angular velocity
vehicle_speed_m_s number m/s yes Vehicle road speed; the reference composition supplies navigation ground speed
transmission_gear integer -1, 0, 1..6 yes Reverse, neutral, or estimated forward gear when known
throttle_position number 0.0..1.0 yes Measured throttle position
commanded_throttle_position number 0.0..1.0 yes ECU-commanded throttle position
accelerator_pedal_position number 0.0..1.0 yes Accelerator pedal position
engine_load number 0.0..1.0 yes Calculated engine load
absolute_engine_load number nonnegative ratio yes Absolute engine load reported by the ECU
fuel_system_status_1 integer 0..255 yes SAE J1979 fuel-system status byte for system 1
fuel_system_status_2 integer 0..255 yes SAE J1979 fuel-system status byte for system 2
short_term_fuel_trim_bank1 number signed ratio yes Bank 1 short-term fuel correction
long_term_fuel_trim_bank1 number signed ratio yes Bank 1 long-term fuel correction
ignition_timing_advance_deg number degrees yes Ignition advance relative to top dead center
intake_manifold_pressure_pa number Pa yes Absolute intake manifold pressure
barometric_pressure_pa number Pa yes Ambient/barometric pressure
boost_pressure_pa number Pa yes Gauge boost relative to barometric pressure; negative values may represent vacuum
mass_air_flow_kg_s number kg/s yes Mass air flow rate
coolant_temperature_k number K yes Engine coolant temperature
intake_air_temperature_k number K yes Intake air temperature
fuel_level number 0.0..1.0 yes Fuel tank level
fuel_rail_pressure_pa number Pa yes Fuel rail pressure
commanded_equivalence_ratio number 0.0..2.0 yes ECU-commanded equivalence ratio
measured_equivalence_ratio number 0.0..2.0 yes Measured equivalence ratio
engine_fuel_rate_m3_s number m³/s yes Engine fuel volume flow rate
control_voltage_v number V yes Vehicle/control-system electrical voltage

Version history

  • Version 1: base vehicle state plus transmission_gear.
  • Version 2: adds engine_fuel_rate_m3_s.
  • Version 3: adds commanded_equivalence_ratio.
  • Version 4: adds commanded throttle, absolute load, fuel-system status, fuel trims, ignition timing, fuel-rail pressure, and measured equivalence ratio.

Nullability

Fields are not omitted when unavailable. Producers emit explicit JSON null values so the Version 4 object shape remains stable.

Example partial producer:

{
  "engine_speed_rad_s": 298.14,
  "vehicle_speed_m_s": 18.88,
  "throttle_position": null,
  "accelerator_pedal_position": null,
  "engine_load": null,
  "intake_manifold_pressure_pa": null,
  "barometric_pressure_pa": null,
  "boost_pressure_pa": null,
  "mass_air_flow_kg_s": null,
  "coolant_temperature_k": 363.15,
  "intake_air_temperature_k": null,
  "fuel_level": null,
  "control_voltage_v": null
}

Producer requirements

A Version 4 producer must:

  • publish on openroad.vehicle.state;
  • emit version equal to 5;
  • provide a valid Unix-epoch timestamp;
  • use the SI units and dimensionless ranges defined above;
  • include every Version 4 data field;
  • use JSON null for unavailable values;
  • avoid encoding hardware- or protocol-specific semantics into the public fields.

The producer controls its publication rate. Version 4 does not require a particular frequency.

Consumer requirements

Consumers should treat each message as a complete vehicle-state snapshot. Consumers must tolerate null for every nullable data field and must not assume a particular producer type or publication frequency.

Consumers should reject or explicitly handle unsupported contract versions rather than silently interpreting them as a different version.

Versioning

The version field versions the payload contract, not the ZeroMQ transport.

Changes that alter the meaning, unit, type, required presence, or interpretation of an existing field require a new contract version. Version 4 field semantics must not be silently changed after publication.

Transport implementations are intentionally separate from this IDD. A future transport may carry the same contract without changing the automotive data semantics.

Version 5: ECU torque

Version 5 adds two required, nullable SI fields. Earlier versions still decode, with these fields set to null:

Field Type Unit/range Meaning
actual_engine_torque_ratio number or null -1.25..1.30 Mode 01 PID 62’s percent torque divided by 100
reference_engine_torque_nm number or null nonnegative Nm Mode 01 PID 63’s reference torque

Actual torque equals ratio times reference torque. Power in watts equals torque in Nm times engine angular speed in rad/s. This is ECU-reported/modelled engine output, not a measurement of wheel power. Missing values or zero reference torque do not yield a derived output. Negative torque/power represent engine braking. The OBD source polls supported torque PIDs only in the ECU priority group; each read still performs at most one PID request. Instantaneous output is withheld after 10 seconds without a successful torque or RPM sample, or after an empty torque reply. Producers and consumers must be updated together; restart a long-running automotive service after deploying this contract. Older consumers that only accept versions 1–4 cannot decode version 5.