Positioning

TriggerEngine is an offline rule-based mining pipeline for Waymo Open Dataset interactive TFRecord shards. It turns trajectories, map geometry, traffic-light state, and VRU interactions into review cases that can be inspected by a person and replayed as regression evidence.

The current stage is open-loop: recorded scenarios go in, structured events and static viewers come out. It does not yet drive an agent or vehicle controller. The next stage will use the existing Scenario IR / evaluation feedback contracts to connect the mined cases to closed-loop simulation.

The problem

Long-tail events are sparse in large driving datasets, so manual replay does not scale. A single-frame threshold is fast but noisy and hard to explain. The design goal is therefore not to label every frame; it is to emit a review event with a traceable reason for triggering.

Key design decisions

1. Separate configuration from runtime

YAML rules pass through RuleParser and RuleCompiler into an active ExecutionPlan. At runtime, TriggerEngine.evaluate(context) accepts only an AlignmentContext. Operator registration, subject compatibility, and temporal source tags can fail fast before a batch run starts.

2. Compose frame signals into evidence-backed events

Single-frame rules emit TagEvents. TagTimeline then composes them with sustained and sequence rules. The classic cut-in rule requires the same SDC-target pair to satisfy this sequence within 0.8 seconds:

adjacent_vehicle -> cut_in_lateral_approach -> same_path_overlap

Step by step, the judgment is:

Step Intermediate tag What it checks Result
01 adjacent_vehicle The same sdc_pair contains two vehicles, with a lateral gap of about 1.5 - 4.5m and longitudinal distance under 15m Candidate enters the window
02 cut_in_lateral_approach Both vehicles are moving; the target moves laterally toward ego and the headings converge A cut-in is developing
03 same_path_overlap Ego is still moving and the pair reaches the same-path geometry, with lateral error under 1.2m Merge geometry is present
04 cut_in_confirmed The same pair hits the steps in order within 0.8s; unmatched frames may exist between steps Emit a review event
05 cut_in_risk Add low_ttc_pair in the same temporal window Raise review priority

This is not “small lateral distance on one frame equals cut-in”. It is single-frame tags -> TagTimeline -> ordered sequence -> review policy. The final episode policy compacts consecutive hits by subject so one cut-in does not become a stream of duplicate events.

Adding low_ttc_pair upgrades the result to cut_in_risk. The event keeps supporting frame indices, timestamps, ego/target identity, and rule metadata so a reviewer can follow the evidence instead of seeing an unexplained boolean.

3. Make review semantics explicit

Intermediate signals remain supporting / debug; final analyst-facing items use intent: review. Episode and cooldown policies then compact repeated frame hits by subject. The current classic pack covers low-TTC, confirmed cut-in, map-aware red-light, SDC hard braking, VRU close interaction, blocked/unable-to-proceed, and lane-change conflict.

Viewer evidence

These are screenshots from the actual review viewer. The index groups cases by review tag; the scenario view keeps EGO/TARGET, scenario id, frame, time, and the event summary in one inspection path.

TriggerEngine review index showing five review tags and 183 events
Review index: 5 review tags / 183 events, organized for fast triage.
TriggerEngine viewer showing a confirmed cut-in with EGO and TARGET
Confirmed cut-in: `cut_in_confirmed`, EGO/TARGET, frame 8, and t=0.80s are visible in the evidence view.

Engineering value

Layer Implementation Why it matters
Data Waymo adapter + alignment context Stable rule inputs from raw proto data
Rules YAML DSL + OperatorRegistry + RuleRegistry New scenario logic without rewriting orchestration
Engine TagEvent, TagTimeline, event policy Explainability, temporal logic, and deduplication
Delivery Batch summary + payload JSON + static HTML Reviewable, shareable, regression-friendly output

Performance work is profile-driven: SDC-only pair candidates and cheap geometry gates run before expensive TTC or lane matching. A recorded first-five-shard benchmark reduced engine time from 82.07s to 9.01s while keeping review output unchanged.

Next step: open-loop to closed-loop

The current delivery boundary is offline mining plus evidence viewing. The next step is to compile high-value cases into executable scenario inputs, connect them to an agent/runtime, compare closed-loop behavior against the trigger conditions, and feed the evaluation result back as evaluation feedback. That turns TriggerEngine into the front end of a simulation-evaluation loop rather than a one-off filter.

Code map

  • trigger_engine/data/: readers, frame schema, and Waymo / nuScenes adapters.
  • trigger_engine/rules/: DSL parser, AST, compiler, and rule execution.
  • trigger_engine/operators/: kinematic, interaction, map, and review predicates.
  • trigger_engine/engine/: orchestration, subject cache, temporal timeline, and event policy.
  • tools/run_review_batch.py: batch scanning, profiling, and viewer artifact generation.