Expand description
Mach-keyed drop-scale-factor (DSF) truing table (MBA-1357).
Applied Ballistics’ published two-stage truing workflow calibrates muzzle velocity (MV) first — that fixes the supersonic drag curve against a chronograph/observed-drop comparison at Mach >= 1.2. Below that, as the bullet moves through the transonic region and into the subsonic regime, no single MV correction can fix drop discrepancies that grow with range: the residual is a slowly-varying function of Mach, not a constant offset. AB’s second stage records a handful of observed drop / predicted drop ratios at specific (subsonic-or-transonic) Mach numbers and uses them to scale predicted drop at nearby Mach numbers on later solves.
This module is a cleanroom reimplementation of that workflow’s shape, not a
bit-for-bit copy of AB’s unpublished interpolation — Kestrel/AB do not publish their
exact curve. The design decision unique to this implementation is the anchor:
the table’s Mach domain is (0, 1.2) (points at/above Mach 1.2 belong to MV truing,
not here — DsfTable::from_points rejects them), and every table implicitly
continues with a DSF of 1.0 at Mach 1.2 — the exact boundary where MV calibration
takes over. That implicit anchor point (1.2, 1.0) is never stored in
DsfTable::points; it exists only inside DsfTable::factor_at’s interpolation so
the transition from “supersonic, MV-trued, unscaled” to “transonic/subsonic,
DSF-scaled” is continuous — a shot solved at Mach 1.1999 and one solved at Mach 1.2001
get (to floating-point precision) the same drop. This is a functional-equivalence
choice made for this engine, not a replication of AB’s internal method.
Below the lowest recorded point, DsfTable::factor_at flat-clamps to that point’s
DSF — there is no data past it, and AB’s guidance is that further subsonic drop
continues to track the last-calibrated regime rather than drift back toward identity.
apply_dsf is a drop-only post-processing step over an already-solved
crate::TrajectoryResult: it rescales each point’s vertical position relative to
the line of sight by the DSF at that point’s Mach, and touches nothing else —
velocity, kinetic energy, time, and downrange/windage position are byte-identical
before and after. Per-point Mach is computed the same way the solver’s own
diagnostics compute it (see apply_dsf’s doc comment for the exact fields), NOT
from a re-derived per-altitude local speed of sound the engine does not store per
point.
No feature gate: this module must compile for wasm32-unknown-unknown. It is
fs-free (profile persistence of a table’s points is the caller’s job, e.g.
main.rs’s saved-profile handling in a later task).
Structs§
- DsfPoint
- One observed drop-scale-factor keyed to the Mach number it was recorded at.
- DsfTable
- A validated, Mach-sorted table of up to
DSF_MAX_POINTSDsfPoints.
Enums§
- Upsert
Outcome - What
DsfTable::upsertdid with the incoming point.
Constants§
- DSF_
ANCHOR_ VALUE - DSF value of the implicit anchor at
DSF_MACH_CEILING— identity, matching the MV-trued supersonic regime this table hands off from. - DSF_
MACH_ CEILING - Upper bound (exclusive) of the Mach domain a
DsfPointmay describe. Observations at or above this Mach belong to muzzle-velocity truing, not the DSF table; it doubles as the implicit anchor’s Mach coordinate ((DSF_MACH_CEILING, 1.0)) inDsfTable::factor_at. - DSF_MAX
- Exclusive upper bound a point’s
dsfmust clear. - DSF_
MAX_ POINTS - Maximum number of distinct points a
DsfTablemay hold. - DSF_MIN
- Exclusive lower bound a point’s
dsfmust clear. - DSF_
SUPERSEDE_ TOLERANCE_ MACH - A new point within this many Mach units of an existing one supersedes it in
DsfTable::upsertinstead of being appended.
Functions§
- apply_
dsf - Apply a DSF table to an already-solved trajectory, IN PLACE, scaling only each
point’s drop below the line of sight — in BOTH
result.pointsand, when present,result.sampled_points.