SensorflowStudio / tests /test_rotr /test_consequence.py
whassan's picture
Deploy Sensorflow Studio (part 4)
4b5fa98 verified
Raw History Blame Contribute Delete
2.68 kB
"""Counterfactual consequence: cosmetic violations classify as
NO_MATERIAL_CONSEQUENCE; a missed crossing pedestrian is SAFETY_CRITICAL;
every verdict carries measured evidence from both branches."""
from __future__ import annotations
import pytest
from sensorflow.rotr.attribution import attribute
from sensorflow.rotr.consequence import classify
@pytest.fixture(scope="module")
def classified(bank_v1, detections_v1):
out = {}
for sc in bank_v1:
for v in detections_v1[sc.scenario_id]:
attr = attribute(sc, v)
out[v.violation_id] = (sc, v, attr, classify(sc, v, attr))
return out
def _by_kind_cause(classified, kind, cause):
return [t for t in classified.values()
if t[0].planted.kind == kind and t[0].planted.cause_layer == cause]
class TestClasses:
def test_missed_crossing_pedestrian_is_safety_critical(self, classified):
cases = _by_kind_cause(classified, "fail_yield_pedestrian", "perception")
assert cases
for sc, v, attr, cf in cases:
assert cf.consequence_class == "SAFETY_CRITICAL"
assert cf.observed_safety.min_clearance_m is not None
assert cf.observed_safety.min_clearance_m < 1.5
def test_cosmetic_wrong_lane_is_no_material_consequence(self, classified):
cases = _by_kind_cause(classified, "wrong_lane_association",
"localization")
assert cases
for sc, v, attr, cf in cases:
assert cf.consequence_class == "NO_MATERIAL_CONSEQUENCE"
assert cf.planner_evaluation.max_position_divergence_m < 2.0
def test_control_fault_replays_the_plan(self, classified):
cases = _by_kind_cause(classified, "stop_overshoot", "control")
assert cases
for sc, v, attr, cf in cases:
assert cf.planner_evaluation.engine == "planned-trajectory"
assert cf.consequence_class != "NO_MATERIAL_CONSEQUENCE"
class TestEvidence:
def test_both_branches_measured(self, classified):
for sc, v, attr, cf in classified.values():
pe = cf.planner_evaluation
assert pe.observed_trajectory and pe.corrected_trajectory
assert pe.engine
for sa in (cf.observed_safety, cf.corrected_safety):
assert sa.max_braking_mps2 >= 0.0
assert "surrogate" in sa.surrogate_caveat.lower() or \
"TTC" in sa.surrogate_caveat
def test_counterfactual_provenance_labeled(self, classified):
for sc, v, attr, cf in classified.values():
assert cf.provenance.source == "COUNTERFACTUAL"
assert cf.corrected_layers