feat(perception): define TrackGeometry v1 contract

This commit is contained in:
DCCONSTRUCTIONS
2026-07-27 11:46:23 +03:00
parent 091d560ac8
commit 10c306f162
5 changed files with 1354 additions and 7 deletions
+28
View File
@@ -202,6 +202,21 @@ from .results import (
RecordedPerceptionResult,
validate_recorded_perception_result,
)
from .track_geometry import (
POINT_SLAB_SCHEMA,
TRACK_GEOMETRY_BINDING_SCHEMA,
TRACK_GEOMETRY_FRAME_SCHEMA,
TRACK_GEOMETRY_SCHEMA,
PointSlab,
TrackGeometry,
TrackGeometryContractError,
TrackGeometryCurrentness,
TrackGeometryEvidenceState,
TrackGeometryFrame,
TrackGeometryMetricBasis,
TrackGeometryOwnerKind,
TrackGeometrySourceBinding,
)
from .tracked_fusion_qualification import (
TrackedFusionQualificationResult,
validate_tracked_fusion_qualification_result,
@@ -302,6 +317,7 @@ __all__ = [
"PATCHWORKPP_SOURCE_COMMIT",
"PATCHWORKPP_SOURCE_TAG",
"PATCHWORKPP_SOURCE_URL",
"POINT_SLAB_SCHEMA",
"PatchworkPPGroundSegmenter",
"QueueSnapshot",
"RecordedCalibratedFusion",
@@ -363,6 +379,18 @@ __all__ = [
"TrackingQualificationResult",
"TrackedFusionQualificationResult",
"TELEMETRY_SCHEMA",
"TRACK_GEOMETRY_BINDING_SCHEMA",
"TRACK_GEOMETRY_FRAME_SCHEMA",
"TRACK_GEOMETRY_SCHEMA",
"PointSlab",
"TrackGeometry",
"TrackGeometryContractError",
"TrackGeometryCurrentness",
"TrackGeometryEvidenceState",
"TrackGeometryFrame",
"TrackGeometryMetricBasis",
"TrackGeometryOwnerKind",
"TrackGeometrySourceBinding",
"WORLD_STATE_SCHEMA",
"WorldStateProjector",
"classify_health",
+901
View File
@@ -0,0 +1,901 @@
"""Provider-neutral TrackGeometry v1 and frame-local PointSlab contract.
The contract preserves camera-owned semantic identity, lossless source-point
ownership and explicit current/held/persistent separation. It never infers a
semantic class, metric range, free space or runtime authority from missing
evidence.
"""
from __future__ import annotations
import math
import re
from dataclasses import dataclass
from enum import StrEnum
from typing import Final, cast
import numpy as np
import numpy.typing as npt
TRACK_GEOMETRY_SCHEMA: Final = "missioncore.track-geometry/v1"
TRACK_GEOMETRY_FRAME_SCHEMA: Final = "missioncore.track-geometry-frame/v1"
TRACK_GEOMETRY_BINDING_SCHEMA: Final = "missioncore.track-geometry-binding/v1"
POINT_SLAB_SCHEMA: Final = "missioncore.point-slab/v1"
_IDENTIFIER = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:/-]{0,159}$")
_SOURCE_PACK_ID = re.compile(r"^e10-lidar-pack-[a-f0-9]{64}$")
_E31_RESULT_ID = re.compile(r"^e31-source-qualification-[a-f0-9]{64}$")
_SHA256 = re.compile(r"^[a-f0-9]{64}$")
Float32Array = npt.NDArray[np.float32]
Int64Array = npt.NDArray[np.int64]
UInt32Array = npt.NDArray[np.uint32]
class TrackGeometryContractError(ValueError):
"""A TrackGeometry v1 value violates source or ownership semantics."""
class TrackGeometryOwnerKind(StrEnum):
CAMERA_TRACK = "camera-track"
GEOMETRY_CLUSTER = "geometry-cluster"
class TrackGeometryEvidenceState(StrEnum):
AGREE = "agree"
CAMERA_ONLY = "single-source-camera"
CONFLICT = "conflict"
UNKNOWN = "unknown"
GEOMETRY_ONLY = "single-source-geometry"
class TrackGeometryCurrentness(StrEnum):
CURRENT = "current"
HELD = "held"
PERSISTENT = "persistent"
class TrackGeometryMetricBasis(StrEnum):
CURRENT_POINTS = "current-points"
HELD_LAST_CURRENT = "held-last-current"
PERSISTENT_MODEL = "persistent-model"
UNAVAILABLE = "unavailable"
@dataclass(frozen=True, slots=True)
class TrackGeometrySourceBinding:
"""Bind one frame contract to exact source, representation and E31 truth."""
source_pack_id: str
source_session_id: str
representation_profile_id: str
e31_qualification_id: str
calibration_sha256: str
coordinate_frame: str
time_basis: str
selected_offset_ms: int
def __post_init__(self) -> None:
if _SOURCE_PACK_ID.fullmatch(self.source_pack_id) is None:
raise TrackGeometryContractError("source pack id is invalid")
_safe_identifier(self.source_session_id, "source session id")
_safe_identifier(
self.representation_profile_id,
"representation profile id",
)
if _E31_RESULT_ID.fullmatch(self.e31_qualification_id) is None:
raise TrackGeometryContractError("E31 qualification id is invalid")
if _SHA256.fullmatch(self.calibration_sha256) is None:
raise TrackGeometryContractError("calibration identity is invalid")
_safe_identifier(self.coordinate_frame, "coordinate frame")
_safe_identifier(self.time_basis, "time basis")
if (
not isinstance(self.selected_offset_ms, int)
or isinstance(self.selected_offset_ms, bool)
or abs(self.selected_offset_ms) > 1000
):
raise TrackGeometryContractError("selected offset is invalid")
def to_dict(self) -> dict[str, object]:
return {
"schema_version": TRACK_GEOMETRY_BINDING_SCHEMA,
"source_pack_id": self.source_pack_id,
"source_session_id": self.source_session_id,
"representation_profile_id": self.representation_profile_id,
"e31_qualification_id": self.e31_qualification_id,
"calibration_sha256": self.calibration_sha256,
"coordinate_frame": self.coordinate_frame,
"time_basis": self.time_basis,
"selected_offset_ms": self.selected_offset_ms,
"authority": _authority(),
}
@classmethod
def from_dict(cls, value: object) -> TrackGeometrySourceBinding:
document = _object(value, "track geometry source binding")
_exact_keys(
document,
{
"schema_version",
"source_pack_id",
"source_session_id",
"representation_profile_id",
"e31_qualification_id",
"calibration_sha256",
"coordinate_frame",
"time_basis",
"selected_offset_ms",
"authority",
},
"track geometry source binding",
)
if document.get("schema_version") != TRACK_GEOMETRY_BINDING_SCHEMA:
raise TrackGeometryContractError("track geometry source binding schema is incompatible")
_require_authority(document.get("authority"))
return cls(
source_pack_id=_string(document, "source_pack_id"),
source_session_id=_string(document, "source_session_id"),
representation_profile_id=_string(
document,
"representation_profile_id",
),
e31_qualification_id=_string(document, "e31_qualification_id"),
calibration_sha256=_string(document, "calibration_sha256"),
coordinate_frame=_string(document, "coordinate_frame"),
time_basis=_string(document, "time_basis"),
selected_offset_ms=_integer(document, "selected_offset_ms"),
)
@dataclass(frozen=True, slots=True)
class PointSlab:
"""Contiguous accepted points with one frame-local owner per source row."""
frame_index: int
source_frame_index: int
source_point_count: int
coordinate_frame: str
owner_keys: tuple[str, ...]
source_indices: Int64Array
points_xyz_m: Float32Array
owner_indices: UInt32Array
def __post_init__(self) -> None:
_nonnegative_integer(self.frame_index, "frame index")
_nonnegative_integer(self.source_frame_index, "source frame index")
_nonnegative_integer(self.source_point_count, "source point count")
_safe_identifier(self.coordinate_frame, "point coordinate frame")
if len(set(self.owner_keys)) != len(self.owner_keys):
raise TrackGeometryContractError("point owner keys must be unique")
for owner_key in self.owner_keys:
_safe_identifier(owner_key, "point owner key")
source_indices = np.asarray(self.source_indices)
points = np.asarray(self.points_xyz_m)
owner_indices = np.asarray(self.owner_indices)
if source_indices.dtype != np.dtype("<i8") or source_indices.ndim != 1:
raise TrackGeometryContractError("point source indices must be one-dimensional int64")
if points.dtype != np.dtype("<f4") or points.shape != (
source_indices.size,
3,
):
raise TrackGeometryContractError("point coordinates must be Nx3 float32")
if owner_indices.dtype != np.dtype("<u4") or owner_indices.shape != (source_indices.size,):
raise TrackGeometryContractError("point owner indices must be one-dimensional uint32")
if not np.isfinite(points).all():
raise TrackGeometryContractError("point coordinates must be finite")
if source_indices.size:
if not self.owner_keys:
raise TrackGeometryContractError("owned points require owner keys")
if (
np.any(source_indices < 0)
or np.any(source_indices >= self.source_point_count)
or np.unique(source_indices).size != source_indices.size
):
raise TrackGeometryContractError(
"source point indices must be unique and frame-local"
)
if np.any(owner_indices >= len(self.owner_keys)):
raise TrackGeometryContractError("point owner index is out of range")
if np.unique(owner_indices).size != len(self.owner_keys):
raise TrackGeometryContractError("point owner table cannot contain unused owners")
elif self.owner_keys:
raise TrackGeometryContractError("empty point slabs cannot declare unused owners")
source_copy = np.array(source_indices, dtype="<i8", copy=True)
point_copy = np.array(points, dtype="<f4", copy=True)
owner_copy = np.array(owner_indices, dtype="<u4", copy=True)
source_copy.setflags(write=False)
point_copy.setflags(write=False)
owner_copy.setflags(write=False)
object.__setattr__(self, "source_indices", source_copy)
object.__setattr__(self, "points_xyz_m", point_copy)
object.__setattr__(self, "owner_indices", owner_copy)
@property
def row_count(self) -> int:
return int(self.source_indices.size)
def owner_point_count(self, owner_key: str) -> int:
try:
owner_index = self.owner_keys.index(owner_key)
except ValueError:
return 0
return int(np.count_nonzero(self.owner_indices == owner_index))
def owned_source_indices(self, owner_key: str) -> Int64Array:
try:
owner_index = self.owner_keys.index(owner_key)
except ValueError:
result = np.empty(0, dtype="<i8")
else:
result = self.source_indices[self.owner_indices == owner_index].copy()
result.setflags(write=False)
return result
def to_dict(self) -> dict[str, object]:
return {
"schema_version": POINT_SLAB_SCHEMA,
"frame_index": self.frame_index,
"source_frame_index": self.source_frame_index,
"source_point_count": self.source_point_count,
"coordinate_frame": self.coordinate_frame,
"owner_keys": list(self.owner_keys),
"source_indices": self.source_indices.tolist(),
"points_xyz_m": self.points_xyz_m.tolist(),
"owner_indices": self.owner_indices.tolist(),
"semantics": {
"source_indices_are_frame_local": True,
"one_owner_per_row": True,
"absence_of_points_means_free": False,
},
}
@classmethod
def from_dict(cls, value: object) -> PointSlab:
document = _object(value, "point slab")
_exact_keys(
document,
{
"schema_version",
"frame_index",
"source_frame_index",
"source_point_count",
"coordinate_frame",
"owner_keys",
"source_indices",
"points_xyz_m",
"owner_indices",
"semantics",
},
"point slab",
)
if document.get("schema_version") != POINT_SLAB_SCHEMA:
raise TrackGeometryContractError("point slab schema is incompatible")
semantics = _object(document.get("semantics"), "point slab semantics")
_exact_keys(
semantics,
{
"source_indices_are_frame_local",
"one_owner_per_row",
"absence_of_points_means_free",
},
"point slab semantics",
)
if (
not _boolean(semantics, "source_indices_are_frame_local")
or not _boolean(semantics, "one_owner_per_row")
or _boolean(semantics, "absence_of_points_means_free")
):
raise TrackGeometryContractError("point slab semantics changed")
owner_keys = tuple(
_string_value(item, "point owner key") for item in _array(document, "owner_keys")
)
source_indices = cast(
Int64Array,
_integer_array(document, "source_indices", "<i8"),
)
owner_indices = cast(
UInt32Array,
_integer_array(document, "owner_indices", "<u4"),
)
points = _points_array(document.get("points_xyz_m"))
return cls(
frame_index=_integer(document, "frame_index"),
source_frame_index=_integer(document, "source_frame_index"),
source_point_count=_integer(document, "source_point_count"),
coordinate_frame=_string(document, "coordinate_frame"),
owner_keys=owner_keys,
source_indices=source_indices,
points_xyz_m=points,
owner_indices=owner_indices,
)
@dataclass(frozen=True, slots=True)
class TrackGeometry:
"""One semantic track or unknown-class occupied geometry product."""
owner_key: str
owner_kind: TrackGeometryOwnerKind
evidence_state: TrackGeometryEvidenceState
currentness: TrackGeometryCurrentness
metric_basis: TrackGeometryMetricBasis
reason_codes: tuple[str, ...]
semantic_track_id: int | None = None
semantic_label: str | None = None
bbox_xyxy: tuple[float, float, float, float] | None = None
range_m: float | None = None
held_from_frame_index: int | None = None
persistent_model_id: str | None = None
def __post_init__(self) -> None:
_safe_identifier(self.owner_key, "geometry owner key")
if not self.reason_codes or len(set(self.reason_codes)) != len(self.reason_codes):
raise TrackGeometryContractError("geometry reason codes must be nonempty and unique")
for reason in self.reason_codes:
_safe_identifier(reason, "geometry reason code")
self._validate_owner_identity()
self._validate_currentness()
self._validate_metric()
self._validate_state()
def _validate_owner_identity(self) -> None:
if self.owner_kind is TrackGeometryOwnerKind.CAMERA_TRACK:
if (
not isinstance(self.semantic_track_id, int)
or isinstance(self.semantic_track_id, bool)
or self.semantic_track_id < 0
or not isinstance(self.semantic_label, str)
or not self.semantic_label.strip()
or len(self.semantic_label) > 120
or self.bbox_xyxy is None
):
raise TrackGeometryContractError(
"camera track requires camera-owned semantic identity"
)
bbox = np.asarray(self.bbox_xyxy, dtype=np.float64)
if (
bbox.shape != (4,)
or not np.isfinite(bbox).all()
or bbox[2] <= bbox[0]
or bbox[3] <= bbox[1]
):
raise TrackGeometryContractError("camera track bbox is invalid")
elif (
self.semantic_track_id is not None
or self.semantic_label is not None
or self.bbox_xyxy is not None
):
raise TrackGeometryContractError("geometry-only owners cannot invent camera semantics")
def _validate_currentness(self) -> None:
if self.currentness is TrackGeometryCurrentness.CURRENT:
if self.held_from_frame_index is not None or self.persistent_model_id is not None:
raise TrackGeometryContractError(
"current geometry cannot carry held or persistent provenance"
)
elif self.currentness is TrackGeometryCurrentness.HELD:
if (
self.owner_kind is not TrackGeometryOwnerKind.CAMERA_TRACK
or self.held_from_frame_index is None
or self.held_from_frame_index < 0
or self.persistent_model_id is not None
):
raise TrackGeometryContractError(
"held geometry requires prior camera-track provenance"
)
elif (
self.owner_kind is not TrackGeometryOwnerKind.GEOMETRY_CLUSTER
or self.held_from_frame_index is not None
or self.persistent_model_id is None
):
raise TrackGeometryContractError(
"persistent geometry requires a separate geometry model"
)
if self.persistent_model_id is not None:
_safe_identifier(self.persistent_model_id, "persistent model id")
def _validate_metric(self) -> None:
has_range = self.range_m is not None
if has_range and (
not isinstance(self.range_m, (int, float))
or isinstance(self.range_m, bool)
or not math.isfinite(float(self.range_m))
or float(self.range_m) <= 0.0
):
raise TrackGeometryContractError("geometry range is invalid")
if self.metric_basis is TrackGeometryMetricBasis.UNAVAILABLE:
if has_range:
raise TrackGeometryContractError("unavailable metric geometry cannot publish range")
elif not has_range:
raise TrackGeometryContractError("qualified metric geometry requires a positive range")
if (
self.metric_basis is TrackGeometryMetricBasis.CURRENT_POINTS
and self.currentness is not TrackGeometryCurrentness.CURRENT
):
raise TrackGeometryContractError("current-point metrics require current geometry")
if (
self.metric_basis is TrackGeometryMetricBasis.HELD_LAST_CURRENT
and self.currentness is not TrackGeometryCurrentness.HELD
):
raise TrackGeometryContractError("held metrics require held geometry")
if (
self.metric_basis is TrackGeometryMetricBasis.PERSISTENT_MODEL
and self.currentness is not TrackGeometryCurrentness.PERSISTENT
):
raise TrackGeometryContractError("persistent metrics require persistent geometry")
def _validate_state(self) -> None:
if self.owner_kind is TrackGeometryOwnerKind.GEOMETRY_CLUSTER:
if self.evidence_state is not TrackGeometryEvidenceState.GEOMETRY_ONLY:
raise TrackGeometryContractError("unknown-class geometry must remain geometry-only")
if self.currentness is TrackGeometryCurrentness.CURRENT:
expected = TrackGeometryMetricBasis.CURRENT_POINTS
else:
expected = TrackGeometryMetricBasis.PERSISTENT_MODEL
if self.metric_basis is not expected:
raise TrackGeometryContractError(
"geometry-only metric basis does not match currentness"
)
return
if self.evidence_state is TrackGeometryEvidenceState.GEOMETRY_ONLY:
raise TrackGeometryContractError("camera tracks cannot publish geometry-only state")
if self.currentness is TrackGeometryCurrentness.HELD:
if (
self.evidence_state is not TrackGeometryEvidenceState.UNKNOWN
or self.metric_basis
not in {
TrackGeometryMetricBasis.HELD_LAST_CURRENT,
TrackGeometryMetricBasis.UNAVAILABLE,
}
):
raise TrackGeometryContractError(
"held camera tracks must remain explicit unknown evidence"
)
return
expected_basis = {
TrackGeometryEvidenceState.AGREE: (TrackGeometryMetricBasis.CURRENT_POINTS),
TrackGeometryEvidenceState.CAMERA_ONLY: (TrackGeometryMetricBasis.UNAVAILABLE),
TrackGeometryEvidenceState.CONFLICT: (TrackGeometryMetricBasis.UNAVAILABLE),
TrackGeometryEvidenceState.UNKNOWN: (TrackGeometryMetricBasis.UNAVAILABLE),
}[self.evidence_state]
if self.metric_basis is not expected_basis:
raise TrackGeometryContractError(
"camera-track evidence state cannot invent metric geometry"
)
def to_dict(self) -> dict[str, object]:
return {
"schema_version": TRACK_GEOMETRY_SCHEMA,
"owner_key": self.owner_key,
"owner_kind": self.owner_kind.value,
"evidence_state": self.evidence_state.value,
"currentness": self.currentness.value,
"metric_basis": self.metric_basis.value,
"reason_codes": list(self.reason_codes),
"semantic": (
None
if self.owner_kind is TrackGeometryOwnerKind.GEOMETRY_CLUSTER
else {
"owner": "camera",
"track_id": self.semantic_track_id,
"label": self.semantic_label,
"bbox_xyxy": (None if self.bbox_xyxy is None else list(self.bbox_xyxy)),
}
),
"range_m": self.range_m,
"held_from_frame_index": self.held_from_frame_index,
"persistent_model_id": self.persistent_model_id,
"policy": {
"camera_owns_semantics": True,
"geometry_cannot_invent_class": True,
"absence_of_points_means_free": False,
},
"authority": _authority(),
}
@classmethod
def from_dict(cls, value: object) -> TrackGeometry:
document = _object(value, "track geometry")
_exact_keys(
document,
{
"schema_version",
"owner_key",
"owner_kind",
"evidence_state",
"currentness",
"metric_basis",
"reason_codes",
"semantic",
"range_m",
"held_from_frame_index",
"persistent_model_id",
"policy",
"authority",
},
"track geometry",
)
if document.get("schema_version") != TRACK_GEOMETRY_SCHEMA:
raise TrackGeometryContractError("track geometry schema is incompatible")
policy = _object(document.get("policy"), "track geometry policy")
_exact_keys(
policy,
{
"camera_owns_semantics",
"geometry_cannot_invent_class",
"absence_of_points_means_free",
},
"track geometry policy",
)
if (
not _boolean(policy, "camera_owns_semantics")
or not _boolean(policy, "geometry_cannot_invent_class")
or _boolean(policy, "absence_of_points_means_free")
):
raise TrackGeometryContractError("track geometry policy changed")
_require_authority(document.get("authority"))
owner_kind = _enum(
TrackGeometryOwnerKind,
document.get("owner_kind"),
"track geometry owner kind",
)
semantic = document.get("semantic")
if owner_kind is TrackGeometryOwnerKind.CAMERA_TRACK:
semantic_document = _object(semantic, "camera semantic identity")
_exact_keys(
semantic_document,
{"owner", "track_id", "label", "bbox_xyxy"},
"camera semantic identity",
)
if semantic_document.get("owner") != "camera":
raise TrackGeometryContractError("semantic identity must remain camera-owned")
semantic_track_id = _integer(semantic_document, "track_id")
semantic_label = _string(semantic_document, "label")
bbox_xyxy = _bbox(semantic_document.get("bbox_xyxy"))
elif semantic is None:
semantic_track_id = None
semantic_label = None
bbox_xyxy = None
else:
raise TrackGeometryContractError("geometry-only identity cannot contain semantics")
return cls(
owner_key=_string(document, "owner_key"),
owner_kind=owner_kind,
evidence_state=_enum(
TrackGeometryEvidenceState,
document.get("evidence_state"),
"track geometry evidence state",
),
currentness=_enum(
TrackGeometryCurrentness,
document.get("currentness"),
"track geometry currentness",
),
metric_basis=_enum(
TrackGeometryMetricBasis,
document.get("metric_basis"),
"track geometry metric basis",
),
reason_codes=tuple(
_string_value(item, "geometry reason code")
for item in _array(document, "reason_codes")
),
semantic_track_id=semantic_track_id,
semantic_label=semantic_label,
bbox_xyxy=bbox_xyxy,
range_m=_optional_number(document.get("range_m"), "range"),
held_from_frame_index=_optional_integer(
document.get("held_from_frame_index"),
"held source frame",
),
persistent_model_id=_optional_string(
document.get("persistent_model_id"),
"persistent model id",
),
)
@dataclass(frozen=True, slots=True)
class TrackGeometryFrame:
"""One source frame with explicit objects and exclusive accepted points."""
binding: TrackGeometrySourceBinding
frame_index: int
source_frame_index: int
session_seconds: float
source_available: bool
point_slab: PointSlab
geometries: tuple[TrackGeometry, ...]
def __post_init__(self) -> None:
_nonnegative_integer(self.frame_index, "frame index")
_nonnegative_integer(self.source_frame_index, "source frame index")
if (
not isinstance(self.session_seconds, (int, float))
or isinstance(self.session_seconds, bool)
or not math.isfinite(float(self.session_seconds))
or float(self.session_seconds) < 0.0
):
raise TrackGeometryContractError("session time is invalid")
if not isinstance(self.source_available, bool):
raise TrackGeometryContractError("source availability is invalid")
if (
self.point_slab.frame_index != self.frame_index
or self.point_slab.source_frame_index != self.source_frame_index
or self.point_slab.coordinate_frame != self.binding.coordinate_frame
):
raise TrackGeometryContractError("point slab frame binding is inconsistent")
by_owner = {geometry.owner_key: geometry for geometry in self.geometries}
if len(by_owner) != len(self.geometries):
raise TrackGeometryContractError("geometry owner keys must be unique")
unknown_owners = set(self.point_slab.owner_keys).difference(by_owner)
if unknown_owners:
raise TrackGeometryContractError("point slab references an unknown geometry owner")
for geometry in self.geometries:
owned_count = self.point_slab.owner_point_count(geometry.owner_key)
owns_current = geometry.metric_basis is TrackGeometryMetricBasis.CURRENT_POINTS
if owns_current is not (owned_count > 0):
raise TrackGeometryContractError(
"current point ownership and metric basis disagree"
)
if geometry.currentness is TrackGeometryCurrentness.HELD and (
geometry.held_from_frame_index is None
or geometry.held_from_frame_index >= self.frame_index
):
raise TrackGeometryContractError("held geometry must reference an earlier frame")
if not self.source_available and (
self.point_slab.row_count
or any(
geometry.metric_basis is TrackGeometryMetricBasis.CURRENT_POINTS
for geometry in self.geometries
)
):
raise TrackGeometryContractError(
"unavailable source cannot publish current metric points"
)
def to_dict(self) -> dict[str, object]:
return {
"schema_version": TRACK_GEOMETRY_FRAME_SCHEMA,
"binding": self.binding.to_dict(),
"frame_index": self.frame_index,
"source_frame_index": self.source_frame_index,
"session_seconds": self.session_seconds,
"source_available": self.source_available,
"point_slab": self.point_slab.to_dict(),
"geometries": [geometry.to_dict() for geometry in self.geometries],
"policy": {
"camera_owns_semantics": True,
"one_owner_per_source_point": True,
"current_held_persistent_are_separate": True,
"absence_of_points_means_free": False,
"unknown_remains_unknown": True,
},
"authority": _authority(),
}
@classmethod
def from_dict(cls, value: object) -> TrackGeometryFrame:
document = _object(value, "track geometry frame")
_exact_keys(
document,
{
"schema_version",
"binding",
"frame_index",
"source_frame_index",
"session_seconds",
"source_available",
"point_slab",
"geometries",
"policy",
"authority",
},
"track geometry frame",
)
if document.get("schema_version") != TRACK_GEOMETRY_FRAME_SCHEMA:
raise TrackGeometryContractError("track geometry frame schema is incompatible")
policy = _object(document.get("policy"), "track geometry frame policy")
_exact_keys(
policy,
{
"camera_owns_semantics",
"one_owner_per_source_point",
"current_held_persistent_are_separate",
"absence_of_points_means_free",
"unknown_remains_unknown",
},
"track geometry frame policy",
)
if (
not _boolean(policy, "camera_owns_semantics")
or not _boolean(policy, "one_owner_per_source_point")
or not _boolean(
policy,
"current_held_persistent_are_separate",
)
or _boolean(policy, "absence_of_points_means_free")
or not _boolean(policy, "unknown_remains_unknown")
):
raise TrackGeometryContractError("track geometry frame policy changed")
_require_authority(document.get("authority"))
return cls(
binding=TrackGeometrySourceBinding.from_dict(document.get("binding")),
frame_index=_integer(document, "frame_index"),
source_frame_index=_integer(document, "source_frame_index"),
session_seconds=_number(document, "session_seconds"),
source_available=_boolean(document, "source_available"),
point_slab=PointSlab.from_dict(document.get("point_slab")),
geometries=tuple(
TrackGeometry.from_dict(item) for item in _array(document, "geometries")
),
)
def _safe_identifier(value: str, label: str) -> str:
if not isinstance(value, str) or _IDENTIFIER.fullmatch(value) is None:
raise TrackGeometryContractError(f"{label} is not a safe identifier")
return value
def _nonnegative_integer(value: object, label: str) -> int:
if not isinstance(value, int) or isinstance(value, bool) or value < 0:
raise TrackGeometryContractError(f"{label} is invalid")
return value
def _object(value: object, label: str) -> dict[str, object]:
if not isinstance(value, dict) or any(not isinstance(key, str) for key in value):
raise TrackGeometryContractError(f"{label} must be an object")
return value
def _exact_keys(
document: dict[str, object],
expected: set[str],
label: str,
) -> None:
if set(document) != expected:
raise TrackGeometryContractError(f"{label} fields are incompatible")
def _array(document: dict[str, object], key: str) -> list[object]:
value = document.get(key)
if not isinstance(value, list):
raise TrackGeometryContractError(f"{key} must be an array")
return value
def _string(document: dict[str, object], key: str) -> str:
return _string_value(document.get(key), key)
def _string_value(value: object, label: str) -> str:
if not isinstance(value, str) or not value:
raise TrackGeometryContractError(f"{label} must be a nonempty string")
return value
def _optional_string(value: object, label: str) -> str | None:
if value is None:
return None
return _string_value(value, label)
def _integer(document: dict[str, object], key: str) -> int:
value = document.get(key)
if not isinstance(value, int) or isinstance(value, bool):
raise TrackGeometryContractError(f"{key} must be an integer")
return value
def _optional_integer(value: object, label: str) -> int | None:
if value is None:
return None
if not isinstance(value, int) or isinstance(value, bool):
raise TrackGeometryContractError(f"{label} must be an integer")
return value
def _number(document: dict[str, object], key: str) -> float:
return _number_value(document.get(key), key)
def _optional_number(value: object, label: str) -> float | None:
if value is None:
return None
return _number_value(value, label)
def _number_value(value: object, label: str) -> float:
if (
not isinstance(value, (int, float))
or isinstance(value, bool)
or not math.isfinite(float(value))
):
raise TrackGeometryContractError(f"{label} must be a finite number")
return float(value)
def _boolean(document: dict[str, object], key: str) -> bool:
value = document.get(key)
if not isinstance(value, bool):
raise TrackGeometryContractError(f"{key} must be a boolean")
return value
def _integer_array(
document: dict[str, object],
key: str,
dtype: str,
) -> npt.NDArray[np.signedinteger | np.unsignedinteger]:
values = _array(document, key)
if any(not isinstance(value, int) or isinstance(value, bool) for value in values):
raise TrackGeometryContractError(f"{key} must contain integers")
try:
return np.asarray(values, dtype=dtype)
except (OverflowError, ValueError) as exc:
raise TrackGeometryContractError(f"{key} is out of range") from exc
def _points_array(value: object) -> Float32Array:
if not isinstance(value, list) or any(
not isinstance(row, list)
or len(row) != 3
or any(not isinstance(item, (int, float)) or isinstance(item, bool) for item in row)
for row in value
):
raise TrackGeometryContractError("point coordinates must be an Nx3 array")
if not value:
return np.empty((0, 3), dtype="<f4")
try:
return np.asarray(value, dtype="<f4")
except (OverflowError, ValueError) as exc:
raise TrackGeometryContractError("point coordinates are out of range") from exc
def _bbox(value: object) -> tuple[float, float, float, float]:
if not isinstance(value, list) or len(value) != 4:
raise TrackGeometryContractError("camera bbox must have four values")
numbers = tuple(_number_value(item, "camera bbox coordinate") for item in value)
return (
float(numbers[0]),
float(numbers[1]),
float(numbers[2]),
float(numbers[3]),
)
def _enum[EnumT: StrEnum](
enum_type: type[EnumT],
value: object,
label: str,
) -> EnumT:
if not isinstance(value, str):
raise TrackGeometryContractError(f"{label} must be a string")
try:
return enum_type(value)
except ValueError as exc:
raise TrackGeometryContractError(f"{label} is unknown") from exc
def _authority() -> dict[str, bool]:
return {
"commands_enabled": False,
"navigation_or_safety_accepted": False,
}
def _require_authority(value: object) -> None:
authority = _object(value, "track geometry authority")
_exact_keys(
authority,
{"commands_enabled", "navigation_or_safety_accepted"},
"track geometry authority",
)
if _boolean(authority, "commands_enabled") or _boolean(
authority, "navigation_or_safety_accepted"
):
raise TrackGeometryContractError("TrackGeometry v1 cannot grant runtime authority")