Developers

Assessment schema

Every processed sortie produces assessment.json. The API returns it as assessment in GET /api/sorties/{sid}. Distances are meters, speeds m/s, angles degrees, times seconds from the first frame.

Top level#

FieldTypeDescription
statusstringcomplete or rejected
sortie_idstringSortie identifier
metaobjectUpload metadata: pilot, receiver, tail, camera, date, data source, model release tag, marking
platformobjectThe allow-list decision: platform, template scores, when it was decided
summaryobjectHeadline results (below)
categoriesobjectOne entry per scored category
eventsarrayDetected events in time order
inputsobjectHow pilot inputs relate to the motion, when telemetry has them
controlsobjectControl surface and stick estimates per source, and their agreement
seriesobjectTime series at the analysis rate
trackingobjectTrack quality and the 6-DoF track
securityobjectWhat the sanitizer did and the banner applied
productsobjectFile names of the videos and charts
processing_s, video_duration_s, versionnumber, number, stringTiming and software version

A rejected sortie has only status, sortie_id, meta, decision, reason, processing_s and version. No imagery or derived product is kept.

summary#

{
  "overall_score": 53.0,
  "grade": "Debrief required",          // Proficient | Needs refinement | Debrief required
  "contacts": 1,
  "contact_time_s": 30.2,
  "phase_durations_s": {"approach": 12.4, "precontact": 1.8, "closing": 9.0, "contact": 30.2, ...},
  "peak_closure_mps": 1.12
}

categories#

{
  "closure":   {"score": 0.0,  "value": 1.12, "unit": "m/s peak closure near contact", "weight": 0.25},
  "alignment": {"score": 89.4, "value": 2.2,  "unit": "deg RMS from boom centerline",   "weight": 0.2},
  "stability": {"score": 20.8, "value": 0.74, "unit": "m RMS position scatter in contact", "weight": 0.2},
  "envelope":  {"score": 100,  "value": 100.0,"unit": "% of contact time in ideal zone", "weight": 0.25},
  "procedure": {"score": 60.0, "value": 1.8,  "unit": "s stabilized at pre-contact", "weight": 0.1,
                "notes": ["pre-contact stabilization 1.8 s < 3 s"]}
}

Values in these examples are illustrative. The unit string changes when no contact was made, so always display it with the value.

events#

[
  {"t": 13.3, "type": "precontact_stabilized", "severity": "info", "detail": "Stabilized in the pre-contact position"},
  {"t": 30.1, "type": "excessive_closure", "severity": "critical",
   "detail": "Closure 1.30 m/s near contact (limit 1.20)", "closure_mps": 1.3}
]

type is one of precontact_stabilized, contact, disconnect, high_closure, excessive_closure, overshoot, envelope_warning, envelope_limit, vertical_oscillation, breakaway. severity is info, warning or critical. Some events carry extra measured fields.

series#

Parallel arrays at the analysis rate (10 Hz by default): t, phase, contact, moment_score (null outside scored phases), geometry such as closure rate and offsets from the contact point, envelope coordinates and margin, and roll_deg, pitch_deg, yaw_deg.

tracking#

FieldDescription
analysis_hz, samplesAnalysis rate and sample count
valid_fractionShare of samples with a trusted fit
median_iouMedian silhouette fit quality
pos_sigma_m_medianMedian position uncertainty
active_windows_sTime windows where a receiver was present and analyzed
boom_sourceWhere the boom geometry came from: image or telemetry
pos, velThe 6-DoF track's position and velocity per sample

security#

sanitization counts frames processed, masked, blurred and written; metadata_stripped and frames_outside_presence_windows_discarded are always true; banner is the marking stamped on the frames; settings records the sanitizer configuration that produced the products. Release state and custody live in custody.json, served by the security routes.

Was this page helpful?