pub struct DsfSolveInputs {Show 22 fields
pub muzzle_velocity_fps: f64,
pub ballistic_coefficient: f64,
pub drag_model: DragModel,
pub mass_gr: f64,
pub diameter_in: f64,
pub sight_height_in: f64,
pub temperature_f: f64,
pub pressure_inhg: f64,
pub humidity_pct: f64,
pub altitude_ft: f64,
pub wind_speed_mps: Option<f64>,
pub wind_direction_rad: Option<f64>,
pub shooting_angle_rad: Option<f64>,
pub zero_poi_vertical_m: Option<f64>,
pub zero_poi_horizontal_m: Option<f64>,
pub sight_offset_lateral_m: Option<f64>,
pub bc_reference_standard: Option<BcReferenceStandard>,
pub use_bc_segments: bool,
pub bc_segments: Option<Vec<BCSegmentData>>,
pub custom_drag_table: Option<DragTable>,
pub zero_distance_yd: Option<f64>,
pub bore_height_m: f64,
}Expand description
Full input set for solve_for_dsf — the scalar-BC model (mirroring
TruingModelInputsV1’s fields) plus every profile field the CLI’s historical
solve_profile_for_dsf fed into the physics that TruingModelInputsV1 alone has no
slot for (MBA-1357 Task 8 review, Finding 1). None on any Option field means
exactly what it meant to the historical code when a profile didn’t carry that field —
the same physically neutral default, documented per field below — so a profile that
sets none of them solves byte-identically to a bare converted TruingModelInputsV1,
and one that does gets ALL of it honored, not silently dropped.
Three fields the old profile-driven solve also read are intentionally NOT carried
here, confirmed empirically rather than just by reading the physics: a stored
twist-rate override, twist direction, and a stored bullet-length override. Every place
any of the three reaches the trajectory (enable_magnus’s Magnus force,
enable_aerodynamic_jump’s Litz jump estimator, enable_precession_nutation’s
spin-rate term) is gated behind one of those flags, all permanently off in this solve
(see solve_for_dsf); the only other consumer is the CLI’s own separately-computed
“Stability (SG)” display line, which dsf never prints. Verified by diffing
trajectory --saved-profile output between two otherwise-identical saved profiles
differing only in --twist-rate (7 vs 20) and, separately, only in --bullet-length
(1.0in vs 2.5in): Max Range, Max Height, Zero Angle, Time of Flight, Impact Velocity, Impact Energy, and the ground-impact range were byte-identical in both
pairs; only the SG display line (not part of TrajectoryResult) differed.
Fields§
§muzzle_velocity_fps: f64Muzzle velocity, feet/second.
ballistic_coefficient: f64Nominal scalar ballistic coefficient — superseded by bc_segments/
custom_drag_table when either is Some, same precedence the solver applies.
drag_model: DragModelFull drag-model family (MBA-1357 Task 8 review round 3, Critical #1): a saved
profile can be built with any of G1/G2/G5/G6/G7/G8/GI/GS/RA4 (profile save --drag-model), and dsf’s solve honors whichever one the profile actually
carries — same as trajectory --saved-profile. Unlike this struct, the
scalar-BC TruingModelInputsV1 model true-velocity/true-wind/plan-truing
share is deliberately G1/G7-only (DragModelArg); this field is wider because
dsf’s historical profile-driven solve was always wider, and narrowing it here
silently coerced non-G1/G7 profiles to G1 — see the From<&TruingModelInputsV1>
impl below for how a bridge caller’s G1/G7-only model maps onto this field.
mass_gr: f64Bullet mass, grains.
diameter_in: f64Bullet diameter, inches.
sight_height_in: f64Sight height over bore, inches.
temperature_f: f64Ambient temperature, degrees Fahrenheit.
pressure_inhg: f64Station pressure, inches of mercury.
humidity_pct: f64Relative humidity, percent (0 through 100).
altitude_ft: f64Altitude, feet.
wind_speed_mps: Option<f64>Wind speed, meters/second. None (the default) is calm — byte-identical to a bare
TruingModelInputsV1 solve.
wind_direction_rad: Option<f64>Wind direction, radians, wind-FROM convention (0 = headwind). None is 0.0.
shooting_angle_rad: Option<f64>Uphill (positive) / downhill (negative) shooting angle, radians. None is level
(0.0). Materially changes predicted drop when set — this is the field most likely
to matter of everything in this struct.
zero_poi_vertical_m: Option<f64>Deliberate vertical point-of-impact offset AT THE ZERO RANGE, meters (MBA-1359
semantics — see crate::cli_api::BallisticInputs::zero_poi_vertical_m). None
is 0.0 (no bias). Directly shifts predicted drop, unlike the two lateral-only
fields below.
zero_poi_horizontal_m: Option<f64>Deliberate horizontal point-of-impact offset at the zero range, meters. None is
0.0. Carried for full-fidelity TrajectoryResult output (lateral position); inert
for the vertical drop/Mach the dsf command itself reads off the result.
sight_offset_lateral_m: Option<f64>Lateral sight-to-bore mount offset, meters (MBA-1396). None is 0.0. Same
“carried for fidelity, lateral-only” note as zero_poi_horizontal_m.
bc_reference_standard: Option<BcReferenceStandard>Which standard atmosphere ballistic_coefficient/bc_segments are referenced to.
None is ICAO (matches every profile saved before this field existed). A real,
non-cosmetic ~1.8% retardation difference when Army Standard Metro.
use_bc_segments: boolThe profile’s own use_bc_segments opt-in flag (MBA-1357 Task 8 review round 2,
Finding: this is NOT redundant with bc_segments.is_some(), despite what an
earlier version of this doc comment claimed). solve_for_dsf ORs this with
bc_segments.is_some() (reproducing the historical
profile.use_bc_segments.unwrap_or(false) || bc_segments_data.is_some() exactly)
because the RK4 derivative path (derivatives.rs’s get_bc_for_velocity /
estimate_bc_segments_for) treats use_bc_segments == true with NO explicit
segments as an opt-in to AUTO-ESTIMATE a velocity-dependent BC curve from
diameter/mass/BC — a real drag-model change, not a no-op. Only the separate,
Mach-keyed gate in cli_api.rs (use_bc_segments && !segments.is_empty()) treats
an empty/absent table as inert; the derivative path does not. profile save --use-bc-segments makes flag-true-with-no-array a real saved state, so this is
reachable, not theoretical.
bc_segments: Option<Vec<BCSegmentData>>Velocity-banded BC schedule (MBA-1323 Phase 2). None/empty falls through to
use_bc_segments above (auto-estimation if that’s true, the scalar
ballistic_coefficient otherwise). When Some and non-empty, this REPLACES the
scalar BC for the solve unconditionally (the solver’s segments-then-scalar
precedence), same as the profile path always used.
custom_drag_table: Option<DragTable>Full Mach/Cd drag curve (MBA-1323 Phase 2, .a7p CUSTOM import). None uses
ballistic_coefficient/bc_segments instead. When Some, replaces the BC model
entirely, same as the profile path.
zero_distance_yd: Option<f64>Resolved zero distance, YARDS (the same imperial convention every other field here
that has one uses). None means no zero is configured — the solve stays flat
(muzzle_angle 0.0), byte-identical to the CLI’s historical behaviour for a
profile with neither auto_zero nor zero_distance set and no --zero-set
selected (MBA-1357 Task 8 review, Finding 2).
bore_height_m: f64Bore height above ground, meters — the same MBA-1339 --bore-height geometry
trajectory/come-ups take explicitly, used here only to size the ground-impact
plane the solve terminates at (target_height: 0.0, ground_threshold: 0.0 in
solve_for_dsf). Saved profiles predate that unified flag and never stored one,
so the CLI adapter falls back to the same historical default
trajectory --saved-profile uses absent an explicit value: 60 in (imperial units)
or 1500 mm (metric units) — NOT the same numeric default in both unit systems
(60 in = 1.524 m, 1500 mm = 1.500 m, a genuine ~24 mm difference, not a rounding
artifact of one shared constant).
Trait Implementations§
Source§impl Clone for DsfSolveInputs
impl Clone for DsfSolveInputs
Source§fn clone(&self) -> DsfSolveInputs
fn clone(&self) -> DsfSolveInputs
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for DsfSolveInputs
impl Debug for DsfSolveInputs
Source§impl From<&TruingModelInputsV1> for DsfSolveInputs
impl From<&TruingModelInputsV1> for DsfSolveInputs
Source§fn from(inputs: &TruingModelInputsV1) -> Self
fn from(inputs: &TruingModelInputsV1) -> Self
Widen a bare scalar-BC model into the full DsfSolveInputs shape a caller with
no profile-shaped extras reaches (Task 9’s true.dsf bridge command). EXPLICIT
bridge defaults — spelled out here because an app author needs to know what this
assumes: no wind, a level shot (0.0 shooting angle), no zero-POI bias, no
sight-mount offset, ICAO BC reference, no BC-segment auto-estimation
(use_bc_segments: false), no explicit BC-segment schedule, no custom drag
curve, and a 60 in (1.524 m) imperial-default bore height (a bridge caller has
no unit system of its own — every other field here is already imperial, e.g.
mass_gr/diameter_in, so the imperial bore-height default is the consistent
choice). zero_distance_yd carries inputs.zero_distance_yd (mandatory on
TruingModelInputsV1, so always Some here — never the “flat, no zero” case).
drag_model widens inputs.drag_model (DragModelArg, G1 or G7 only — the
bridge request’s own model has no wider choice) into the corresponding
DragModel variant; since the bridge never offers anything outside G1/G7,
nothing is lost by this widening, unlike the CLI’s saved-profile path which can
carry the full family.
Auto Trait Implementations§
impl Freeze for DsfSolveInputs
impl RefUnwindSafe for DsfSolveInputs
impl Send for DsfSolveInputs
impl Sync for DsfSolveInputs
impl Unpin for DsfSolveInputs
impl UnsafeUnpin for DsfSolveInputs
impl UnwindSafe for DsfSolveInputs
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.