Skip to content

Identifier.value = 0 is ambiguous: cannot distinguish unset from intentional ID 0 #897

@jdsika

Description

@jdsika

Problem

Protobuf3 scalar fields have no "presence" concept — the default value for uint64 is 0, which is indistinguishable from "field not set." This creates an ambiguity in OSI's Identifier message type:

message Identifier {
  uint64 value = 1;
}

When host_vehicle_id.value is 0, consumers cannot determine whether:

  • The field was intentionally set to ID 0 (a valid vehicle exists with that ID), or
  • The field was never populated by the simulator (protobuf default)

How this manifests in practice

In the ASAM OSI Converter for Lichtblick, we resolve the host vehicle by comparing host_vehicle_id.value against moving_object[].id.value. When the field is unset (default 0):

  1. If no vehicle has ID 0 → the host vehicle is "not found," triggering a warning. This is safe but produces confusing diagnostics for users who simply forgot to set the field.
  2. If a vehicle coincidentally has ID 0 → it is silently treated as the host vehicle, which may be incorrect.

We also implemented a fallback mechanism where SensorView.host_vehicle_id is used when GroundTruth.host_vehicle_id is missing (see lichtblick-suite/asam-osi-converter#109). But the 0-ambiguity makes it impossible to reliably detect "missing" vs "set to 0" for the fallback logic.

Divergence between GroundTruth and SensorView

A related problem: host_vehicle_id appears in both GroundTruth and SensorView, but there is no spec-level requirement that they agree. When they diverge, consumers must choose which to trust. We now emit a warning in this case (PR #177), but this is a workaround for a gap in the specification.

Proposal

Option A (Recommended): Reserve ID 0 as invalid/unset

Add a rule to the OSI specification that Identifier.value = 0 is reserved and must not be used as a valid object ID. This is a common pattern in protobuf-based systems (e.g., gRPC uses 0 for OK status but reserves it from being a valid error code). This allows consumers to treat value == 0 as "not set."

Option B: Add a validation rule in qc-osi-trace

If changing the spec is too disruptive, add a QC rule that flags Identifier.value == 0 as a warning. This is related to the is_equal_to rule extension proposed in OpenSimulationInterface/qc-osi-trace#11, which addresses cross-field consistency for host_vehicle_id.

Option C: Use optional qualifier

Protobuf3 now supports the optional keyword for scalar fields, which enables presence tracking via has_* methods:

message Identifier {
  optional uint64 value = 1;
}

This is the most correct solution but would be a breaking change for existing consumers.

Related

Metadata

Metadata

Assignees

Labels

ConceptAn issue that is being detailed out through expert discussion and offline work

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions