# Time-based reference model: stages 0–3

The pair experiment retains the scope described here. The newer **Traffic & capacity** workspace extends the same continuous mathematics into stages 4–6; see [TRAFFIC_MODEL.md](TRAFFIC_MODEL.md). It has its own versioned configuration.

Version: `trajectory-reference-0.1.0` implemented 2026-09-23; the current engine is `trajectory-reference-0.4.0` (see the version notes at the end). These are explicit provisional research choices, not supplier performance claims or a completed capacity/TLS model.

## Run it

Open **DAA experiment** in the website. The built-in crossing case runs in a Web Worker and compares the same missions with DAA enabled and disabled. Select either result, scrub the replay, or click an event. The altitude plot exposes the vertical maneuver that a top view alone cannot show.

**Use current U-plans** copies one or two existing routes and the current geofences into the experiment. The source scenario remains unchanged. Departure times are shifted by a common offset so the first mission starts at experiment time zero. Route heights are explicitly interpreted as AGL over flat ground. Each route gets its own speed/profile and retains its original path in the output. Acceleration, stops and yaw at waypoints can change timing compared with the old constant-speed route checker.

The experiment has its own versioned JSON import/export. A result file can be reimported to reconstruct and rerun its scenario. Old snapshot exports remain in Scenario/Compare runs; their event units have not been converted into physical collisions.

The single area's `airspace.tlsTargets` preserves separate `cs25Intruders` and `otherIntruders` targets in physical collisions per flight hour. `null` means unspecified. These categories are not simulated or assessed yet; the targets are metadata, never compared to A/n or the two-aircraft reference run. Import normalizes missing targets to `null`. Unsupported schema versions require an explicit adapter rather than a guessed migration.

```sh
node scripts/trajectory.cjs --example crossing --output crossing-on.json
node scripts/trajectory.cjs --example crossing --daa-off --output crossing-off.json
node scripts/trajectory.cjs --scenario crossing-on.json --output replay.json
node scripts/trajectory.cjs --example head-on
```

Omit `--output` for JSON on stdout. Output paths must be new files. Inputs are validated before execution; output is published from a temporary file without replacing an existing file.

## Scientific contract

| Quantity | Meaning |
| --- | --- |
| Coordinates | Local east/north/up, metres. Altitude is explicitly AGL over flat terrain. `groundElevationMetres` records the flat datum; no terrain, geoid or barometric conversion is claimed. |
| Body | A physical sphere with configurable radius, independent of all separation settings. |
| Protective volume | Horizontal cylinder radius `base radius + speedExpansionSeconds × horizontal speed`, with a configurable vertical half-height. A pair conflicts when horizontal distance is at most the sum of radii and simultaneous vertical distance is at most the sum of half-heights. |
| NMAC | A separate configurable pairwise horizontal/vertical proximity threshold. The defaults 20 m / 5 m are illustrative research inputs, not an adopted regulatory definition. |
| Physical contact | Distance between body centres reaches the sum of physical sphere radii. Count one event per contacting pair. Simultaneous contacts are resolved together; affected aircraft are counted separately. |
| Airspace/geofence breach | The body's conservative cylindrical envelope intersects a prohibited polygon prism or extends beyond the airspace box. A geofence is a restriction, not automatically a physical solid obstacle. |
| CA activation | A feasible reference maneuver actually begins after an alert and response latency. An alert with no feasible maneuver is a separate `avoidanceUnavailable` event; `avoidanceUnavailable` counts encounters, and failed re-attempts are counted separately. A conflict that is no longer predicted at command time is `alertCleared`, not a failure. |
| CA duration | Time from maneuver start until predicted conflict clearance plus the configured clear hold. Recovery follows as a separate interval. |
| Return completion | Position and velocity have rejoined the original time-parameterized route after the vertical offset returns to zero. |
| Exposure | Sum of actual airborne mission seconds within the run horizon, divided by 3600. Collisions terminate affected missions at contact time. Ground waiting does not add exposure. |
| Efficiency | Planned and flown 3D path length are integrated separately. Full-flight excess distance is reported only for completed flights; a truncated crashed route is not presented as efficient. |

Airspace is the experiment envelope. This version integrates all airborne mission time, including flagged excursions outside the envelope; it does not compute per-sector or per-area exposure rates. Collision/NMAC rates are descriptive rates for this single experiment, not probabilistic estimates of a population. There is no safety pass/fail or capacity claim.

With observed flight time `H = Σ airborneSeconds / 3600`, each event rate is `event count / H` and is undefined (`null`) when `H = 0`. CA per departed flight divides actual activations by departed missions. Mean CA duration uses only completed CA phases; censored phases and completed returns have separate counts. Recovery time totals the observed recovery seconds, including partial returns. Flight efficiency is `planned 3D length / flown 3D length`, and extra distance is `flown − planned`, only for completed missions. All counts and durations remain available in the result even when a rate cannot be computed.

Departure/arrival and contact geometry use closed endpoints. Zero-duration contact is visible but contributes zero flight time. Continued protective/NMAC overlap produces one entry–exit interval, merged across segment boundaries within the numerical tolerance. There is no count per replay frame.

## Trajectory mathematics

Nominal missions use straight 3D legs, starting and ending each leg at rest. Acceleration/deceleration is bounded separately horizontally (`accelerationMetresPerSecondSquared`) and vertically (`verticalAccelerationMetresPerSecondSquared`, defaulting to the horizontal value); along-leg acceleration is reduced on steep legs so its vertical component stays within the vertical limit. Short legs use triangular speed profiles; longer ones use trapezoids. During a heading change, the drone waits at the waypoint for `angle / yaw rate`. This is a simplified multirotor model, not a fixed-wing model. Takeoff/landing dynamics are outside this version: departure inserts an airborne vehicle at the first waypoint, arrival removes it at the last.

`{headingDegrees, distanceMetres, heightAglMetres}` legs can be converted to/from waypoints. Heading is clockwise from north; distance is horizontal; height is the altitude of the endpoint. A vertical-only leg has zero horizontal distance and a conventionally zero heading.

Each motion segment is:

```text
p(t) = p0 + v0 × t + 0.5 × a × t²
v(t) = v0 + a × t
```

Relative squared distance is at most quartic. The geometry kernel isolates polynomial roots between derivative extrema and intersects the horizontal/vertical time intervals. It also checks tangencies and moving segments against polygon edges, vertices, altitude limits and activation times. This catches conflicts entirely between displayed frames. Path length is an adaptive integral of velocity magnitude.

The old U-plan checker now calls the same pure mathematical module for route timing and continuous pair intervals. Its original semantics are preserved; the new trajectory experiment is opt-in. Its route-mathematics tests import that module directly, without extracting source code from `app.js`.

## Sensor, coordination and CA reference

Sensors have 360° coverage, Pd = 1 within range, no measurement error, and a fixed scan period. Range and scan cadence are physical model inputs. `traceIntervalSeconds` only controls exported/displayed samples; it cannot change detections or results. Unsupported sensor fields such as `pd` are rejected, not silently ignored.

At a scan, two cooperative aircraft share the ideal detection. A seeded, stable pair choice assigns the master. The black box receives observed intruder position and velocity and extrapolates constant velocity. It knows its own planned path and known restrictions. It does **not** receive the intruder's future simulated path, later maneuvers or actual future collisions.

An alert predicts a protective-volume conflict within the configured lookahead. After `latencySeconds`, the master tries a vertical offset upward, then downward if upward is infeasible. Offset height is the sum of vertical half-heights plus `clearanceMarginMetres`. Vertical motion ramps to bounded climb speed, holds past predicted conflict clearance, and ramps back to the original altitude.

Each candidate must preserve predicted protection, respect speed/acceleration/climb constraints, stay within the airspace and avoid known geofences through recovery. Its complete return must fit within the lookahead and the mission. The reference controller requires a level remaining route. If a candidate cannot meet those conditions, it reports unavailable; it does not invent a successful maneuver. The slave continues its route. A new alert episode starts only when no conflict is predicted, no command is pending and no maneuver is in progress. Within an episode, while the conflict is still predicted, the same master re-attempts after an unavailable maneuver or after its previous maneuver has ended.

The observation cutoff does not change planned behavior: shortening a run truncates its evidence rather than allowing the controller to know that the experiment is about to end. An ongoing CA or recovery is recorded as censored. Completed CA duration and completed return counts are separate.

Prediction may be wrong when the intruder accelerates, turns or lands. The independent ground-truth evaluator still records actual separation/contact. This limitation is deliberate and visible in the reference assumptions.

## Boundaries of this implementation

- DAA runs support up to two missions. Geometry-only runs with DAA off support up to 32 and flag simultaneous connected groups of 3+.
- No arbitrary multi-aircraft avoidance, DCB, traffic-demand generation, capacity search, imperfect sensing, failure process, RTTA or noise model is claimed.
- Scheduled static prism restrictions are supported; randomized urgent geofences and breach-versus-collision policy are later stages.
- There is one reference control policy, with per-mission physical/kinematic profiles. This is not support for multiple vendor DAA algorithms.
- A mission may enter a geofence or leave the airspace on its original plan; these violations are recorded, not hidden by clamping positions. CA candidates must respect those restrictions.
- Scenario limits are explicit: local coordinates within ±100 km, maximum 64 waypoints per route, 32 profiles/fences/missions, two hours, 30,000 sensor scans and 15,000 regular trace samples. Data with unsupported fields, references or invalid polygons is rejected.
- No six-degree-of-freedom flight dynamics, fixed-wing stall constraints, realistic downwash, wind, terrain or physical building geometry is represented.

Before treating this as a chosen project model, the team should confirm the reference maneuver, flat-ground scope, proximity thresholds, body dimensions, alert lookahead, scan cadence and counting conventions. All are identifiable in configuration or this contract; none should be interpreted as measured supplier capability.

### Decision record

The provisional choices above let implementation proceed without assigning scientific approval to anyone. The project group must name the decision owners and approve or revise them before research conclusions are drawn. Suggested review roles: the scientific supervisor for event definitions/kinematics, the requirements owner for collision/TLS and intruder-category meanings, and the project group jointly for capacity/acceptance criteria. No named person has been assumed to approve them.

Failure probabilities, false alarms, capacity criteria and a policy trading a geofence breach against collision avoidance remain unimplemented. Until those stages, imperfect-sensor inputs are rejected, failed reference maneuvers remain visible, and there is no capacity or safety acceptance verdict. E0's implementation contract is available; its project sign-off remains open.

## Acceptance and verification

Automated tests cover analytical head-on/crossing/accelerated/tangential cases, simultaneous horizontal/vertical conditions, between-frame contact and geofence crossings, waypoint conversion, actual exposure, collision termination, bounded and continuous maneuvers, successful return, insufficient room, delayed response, horizon censoring, trace-interval invariance, multi-drone membership, JSON/CLI replay and browser/Node equality.

The website's browser test checks the actual worker, on/off comparison, event scrubbing, failed late response and responsive layout. The two built-in reference encounters resolve with the ideal DAA settings and produce a physical contact with DAA off. These are verification examples, not statistical collision-rate evidence.

Stage status: E0 has an explicit provisional contract; E1 has shared mathematics, validated JSON and CLI; E2 has continuous kinematics and events; E3 has the bounded pairwise reference pipeline and return. Project approval of model assumptions and external validation remain separate from implementation correctness.

## Reference 0.3: recovery policy

Existing protective overlap uses a separate recovery rule: restore protection earlier than the nominal path, avoid physical contact and new NMAC intervals, and avoid re-entry. An already active NMAC must also end earlier. Outside protection, the original separation-preserving rule remains. Kinematic and restriction constraints still apply. Activations export the selected policy and predicted absolute protection-restoration time. This bounded vertical candidate search is not a general proof of maneuver feasibility. See [MODEL_VALIDATION.md](MODEL_VALIDATION.md).

## Reference 0.4: master selection and CA re-attempts

`seededChoice` previously took FNV-1a modulo two. Its low bit equals the parity of the number of odd character codes in the key, so the master followed key structure (for example, alternating with a trailing counter) rather than a random draw. A murmur3 finalizer now mixes every input bit; the choice remains reproducible from the seed (REQ-3.4).

Previously an episode stayed blocked while a conflict persisted: after `avoidanceUnavailable`, or after a completed maneuver, no further CA was attempted until the conflict disappeared. The master now re-attempts with a fresh observation (REQ-3.1, 3.5). Regression: a temporary restriction above a crossing blocks the first candidate; after it lifts, the re-attempt avoids the contact that the 0.3 engine recorded. `avoidanceUnavailable` remains one per encounter; `repeatedAvoidanceUnavailable` and `alertsCleared` are reported separately.

Acceleration limits are now checked per axis: the horizontal limit and an optional vertical limit (REQ-2.3, default equal to the horizontal limit). The CA ramp uses half the vertical limit. Under the former single vector bound, that ramp combined with nominal horizontal braking or acceleration gave |a| ≈ 1.118a, so no avoidance could start during a leg's start or stop phase. Regression: in the head-on reference at t = 1 s, still accelerating, the 0.3 engine found no candidate; 0.4 starts a 40 m offset immediately. All candidates accepted by the old bound remain identical. With the default vertical limit, nominal paths are unchanged.
