1. Reconstruct a Crash Event Timeline from

Reconstruct a Crash Event Timeline from EDR Data Learning card

Why the EDR timeline is the backbone of the reconstruction

An Event Data Recorder (EDR) does not record a continuous video of the crash. It records a small set of discrete snapshots, each stamped with a time relative to a trigger event. The reconstruction task is therefore not "read the numbers" but "place each snapshot on a single, defensible time axis." Three independent clocks appear in a typical report and must be reconciled before any sequence of events can be asserted:

  • Ignition cycle counter — a monotonically increasing integer that increments at each ignition-on transition. It is the only field that lets you prove whether two records belong to the same trip or to different trips.
  • Time-from-trigger stamps — negative values before the algorithm enable point, zero at the trigger, positive values during the recording window. These are relative, not absolute.
  • Delta-v phase boundaries — the cumulative velocity change is reported at fixed sample offsets (commonly 10 ms steps), so the delta-v curve itself carries an implicit time base that must agree with the timestamp column.

A defensible sequence requires that all three agree. When they do not, the discrepancy is the finding, not a nuisance to be smoothed away.

Reading the report before parsing it

Start by identifying the report's structural blocks. A typical EDR output contains a header (vehicle identifiers, EDR part number, software version), a list of stored events, and for each event a set of data channels. The channels that matter for timeline work are:

ChannelTypical field nameRole in the timeline
Ignition cycle at eventIgnition Cycle, EventGroups records into trips; detects overwritten or cross-trip data
Time from triggerTime, Relative to TriggerPrimary x-axis for every other channel
Longitudinal / lateral delta-vDelta-V, Longitudinal / LateralDefines impact phase onset and duration
Airbag deployment timeTime to Deploy, Driver FrontalAnchors the restraint decision point
Pre-crash speedVehicle Speed, Pre-CrashEstablishes the pre-impact kinematic state
Brake / throttle statusBrake Switch, Throttle PositionDriver-action evidence before impact

Note the units printed next to each channel. Delta-v is frequently reported in km/h on one page and m/s in a derived table; speed may be mph. Unit confusion is the single most common source of a wrong timeline, and it is silent — the numbers look plausible.

Building the time axis

The trigger is the origin. Everything before it is negative, everything after is positive. The pre-crash window is typically 5 s of low-rate samples (often 1 Hz or 2 Hz), while the impact window is high-rate (100 Hz or faster). This means the time axis is piecewise: a coarse pre-crash segment, a fine impact segment, and a post-crash segment. Plotting all channels on one axis without marking the rate change invites misreading of slope and duration.

A practical parsing routine in Python, using only the standard library, illustrates the reconciliation logic. The input is a list of channel records already extracted from the report text; the output is a normalized event dictionary.

import re

def parse_edr_channels(raw_lines):
    """Extract channel name, value, unit from 'Name: value unit' lines."""
    channels = {}
    pattern = re.compile(r"^\s*([A-Za-z0-9 ,\-/]+?):\s*([-+]?\d*\.?\d+)\s*([A-Za-z/%]+)?\s*$")
    for line in raw_lines:
        m = pattern.match(line)
        if not m:
            continue
        name = m.group(1).strip().lower()
        value = float(m.group(2))
        unit = (m.group(3) or "").strip().lower()
        channels[name] = {"value": value, "unit": unit}
    return channels

def to_ms(value, unit):
    """Normalize time-like values to milliseconds."""
    if unit in ("s", "sec", "second", "seconds"):
        return value * 1000.0
    if unit in ("ms", "msec", "millisecond", "milliseconds"):
        return value
    raise ValueError(f"unrecognized time unit: {unit!r}")

def build_timeline(channels):
    timeline = {"ignition_cycle": None, "trigger_ms": 0.0, "phases": []}
    ic = channels.get("ignition cycle, event")
    if ic:
        timeline["ignition_cycle"] = int(ic["value"])

    dv = channels.get("delta-v, longitudinal")
    if dv:
        # delta-v reported in km/h must be converted to m/s for kinematic use
        dv_ms = dv["value"] / 3.6 if dv["unit"] in ("km/h", "kph") else dv["value"]
        timeline["delta_v_ms"] = dv_ms

    deploy = channels.get("time to deploy, driver frontal")
    if deploy:
        timeline["deploy_ms"] = to_ms(deploy["value"], deploy["unit"])

    return timeline

The function is deliberately strict: an unrecognized time unit raises rather than silently assuming seconds. That single design choice prevents the most common reconstruction error. Run it against the extracted lines and inspect the returned dictionary before plotting anything.

Separating ignition cycles and delta-v phases

Two records with the same ignition cycle counter belong to the same trip and can share a time axis. Two records with different counters cannot be concatenated into one continuous timeline — they are separate trips, and any "sequence" spanning them is an artifact. Check this first, before interpreting any delta-v value.

Within a single event, the delta-v curve has a recognizable shape: a near-zero pre-impact segment, a steep rise during the impact phase, and a plateau after separation. The impact phase onset is where the slope first exceeds a defined threshold (for example, 0.5 m/s per 10 ms sample); the end is where the slope returns below it. Airbag deployment time should fall inside or immediately after this window. If deployment is reported before impact onset, either the trigger definition differs from your assumption or a channel is mislabeled — investigate before proceeding.

Reconstructed EDR Event Timeline (single ignition cycle) Pre-crash (low rate) Impact phase Post-crash t = 0 (trigger) −5 s +3 s Δv plateau impact onset airbag deploy pre-crash speed (constant) Ignition cycle: 412 (single trip) Δv (m/s) phase boundary restraint event

Verifying the sequence before you commit to it

Three checks close the loop. First, monotonic delta-v: cumulative delta-v must not decrease during the impact phase; a dip indicates a sign convention error or a lateral/longitudinal channel swap. Second, deployment ordering: airbag deployment time must be greater than or equal to impact onset time, and typically within 20–50 ms of it for a frontal event. Third, speed consistency: the pre-crash speed minus the integrated delta-v should approximate the post-impact speed, within the resolution of the reported channels.

If the ignition cycle counter differs between the event record and the pre-crash record, stop. You are looking at data from two trips, and any timeline you build across them is not defensible. Report the mismatch as a data-integrity finding.

When all three checks pass, the timeline is ready to be stated as a sequence: pre-crash state at t = −5 s, driver action (brake/throttle) at its stamped time, impact onset at the first delta-v slope excursion, airbag deployment at its reported offset, and post-crash plateau. Each element carries its own timestamp and its own source channel, so any later challenge can be answered by pointing to the specific field rather than to a narrative.

Keep the raw channel values, their units, and the conversion applied in a small audit table alongside the timeline. A reconstruction that cannot show its unit conversions is a reconstruction that cannot be defended.