Skip to content

SDV & Standards

VSS and the Eclipse Kuksa databroker

The Vehicle Signal Specification as a shared contract between ECU, platform and HMI teams — and how to test the whole signal path without a vehicle.

Advanced5 minVSS · SDV · Kuksa

A software-defined vehicle programme usually begins with an uncomfortable discovery: the signal catalogue already exists, in a format Android has never heard of, and three teams are each maintaining their own private mapping of it.

VSS replaces those spreadsheets with a contract.

Two conversions turn a vehicle network into an Android APIAUTOSAR ECUARXML system signalsSOME/IPservice discoveryVSS treeVehicle.Speed · units · typesKuksa databrokergRPC — test without hardwareVSS → VHAL codegenproperty id, area, accessVehicle HALIVehicle AIDLCarPropertyManagerapp-facingarxml → vssvss → vhal
From AUTOSAR signals to Android propertiesTwo generated conversions, one hand-reviewed overlay for what the source cannot express, and a databroker so none of it needs a vehicle to test.

What VSS is#

A tree of signal definitions maintained by COVESA. Every signal has a dotted path, a datatype, a unit and a description — none of it vendor-specific.

Vehicle/Powertrain/Battery.vspec
StateOfCharge:
  Current:
    datatype: float
    type: sensor
    unit: percent
    min: 0
    max: 100
    description: Physical state of charge of the high-voltage battery.
Vehicle/Cabin/Seat.vspec — branch with instances
Seat:
  type: branch
  instances:
    - Row[1,2]
    - ["DriverSide", "Middle", "PassengerSide"]
 
Seat.Massage.Intensity:
  datatype: uint8
  type: actuator
  min: 0
  max: 5

Modest on its own. Its value is that the ECU supplier, the platform team and the HMI team can now argue about one artefact instead of three private ones.

Node types map onto VHAL access#

VSS typeMeaningVHAL equivalent
sensorRead-only observationVehiclePropertyAccess.READ
actuatorCan be commandedREAD_WRITE
attributeStatic, set at buildREAD + changeMode STATIC
branchGrouping nodeno equivalent — structure only

That mapping is mechanical, which is exactly why it should be generated.

The two conversions#

ARXML → VSS#

AUTOSAR is the source of truth for the vehicle network. Extracting it means walking the ARXML package tree, resolving SYSTEM-SIGNAL definitions and their COMPU-METHOD scaling, and emitting VSS nodes.

arxml_to_vss.py
def to_vss_node(signal: SystemSignal) -> dict:
    scaling = resolve_compu_method(signal)
    return {
        "datatype": DATATYPE_MAP[signal.base_type],
        "type": "sensor" if signal.read_only else "actuator",
        "unit": scaling.unit,
        "min": scaling.apply(signal.raw_min),
        "max": scaling.apply(signal.raw_max),
        "description": signal.desc or signal.short_name,
    }

Scaling is where the bugs live

COMPU-METHOD factor/offset pairs apply to the raw bus value. Convert once, at the boundary, and record the unit in the VSS node. A signal scaled twice — or not at all — produces a plausible-looking number that is wrong by a constant factor, which is the hardest kind of defect to notice in a UI.

VSS → VHAL#

Most of a VehiclePropConfig is derivable from a VSS node. Not all of it.

VSS conceptVHAL equivalentDerivable?
datatype: floatVehiclePropertyType.FLOATYes
type: sensoraccess = READYes
type: actuatoraccess = READ_WRITEYes
min / maxVehicleAreaConfig boundsYes
Instance Row1.DriverSideVehicleAreaSeat.ROW_1_LEFTUsually
Sampling behaviourON_CHANGE vs CONTINUOUSNo
PermissionCar permission mappingNo

Those last two are the honest limit of automation. VSS describes what a signal is, not how often to sample it or who may write it. Both are product decisions and belong in a small, reviewed overlay file — not guessed by a generator.

Keep the generated layer generated#

The strongest discipline on this work is refusing to hand-edit generated output. The moment someone patches a generated VHAL config to fix one signal, the generator stops being the source of truth and the mapping begins rotting.

The workflow that survives a multi-year programme:

  1. Generate VSS from ARXML.
  2. Apply a small, reviewed overlay for what the source cannot express — sample rates, non-conventional area mappings, deliberate omissions.
  3. Generate VHAL configs from the merged tree.
  4. Regenerate in CI and fail the build if committed output differs.

Step 4 is what keeps the whole thing alive.

.github/workflows/signals.yml
- name: Regenerate signal artefacts
  run: |
    python tools/arxml_to_vss.py --in spec/network.arxml --out build/vss.json
    python tools/vss_overlay.py  --base build/vss.json --overlay spec/overlay.yaml \
                                 --out build/vss.merged.json
    python tools/vss_to_vhal.py  --in build/vss.merged.json --out build/DefaultConfig.h
 
- name: Fail if generated output drifted
  run: git diff --exit-code generated/

Testing without a vehicle#

The Eclipse Kuksa databroker publishes VSS values over gRPC. Point your VHAL at it in a debug build and the whole stack becomes testable on a desk.

Driving the stack from a shell
docker run -p 55555:55555 ghcr.io/eclipse-kuksa/kuksa-databroker:latest
 
kuksa-client set Vehicle.Powertrain.Battery.StateOfCharge.Current 42.5
kuksa-client get Vehicle.Powertrain.Battery.StateOfCharge.Current
 
# Confirm it surfaced on the Android side
adb shell dumpsys car_service --get-property 0x21100601

If those two agree, the mapping is correct and the remaining risk is in the transport, not the contract. That is a much smaller problem to have.

Scripted scenarios beat manual drives
scenario = [
    (0.0,  "Vehicle.Powertrain.Transmission.CurrentGear", 1),
    (0.5,  "Vehicle.Speed", 12.0),
    (2.0,  "Vehicle.Speed", 48.0),
    (6.0,  "Vehicle.Cabin.Door.Row1.DriverSide.IsOpen", True),   # while moving
]

That fourth line is a real test case — door open above speed threshold — and it is one you would otherwise have to stage in a car park.

The part that is not technical#

VSS pays off because three teams get a shared vocabulary. It fails when only one adopts it. If the supplier keeps shipping ARXML and the HMI team keeps a private mapping, you have added a format rather than removed one.

The migration is worth doing only when the generated artefacts become the thing everyone reviews. Until then it is overhead.

Next#

The transports that carry these signals, and how AAOS fits into a virtualised vehicle computer.

References & further reading

Code links target the main branch on cs.android.com. AOSP moves — if a path 404s, search the symbol instead.