pub struct BallisticInputs {Show 64 fields
pub bc_value: f64,
pub bc_type: DragModel,
pub bc_reference_standard: BcReferenceStandard,
pub bullet_mass: f64,
pub muzzle_velocity: f64,
pub bullet_diameter: f64,
pub bullet_length: f64,
pub muzzle_angle: f64,
pub target_distance: f64,
pub azimuth_angle: f64,
pub shot_azimuth: f64,
pub shooting_angle: f64,
pub cant_angle: f64,
pub sight_height: f64,
pub sight_offset_lateral_m: f64,
pub muzzle_height: f64,
pub target_height: f64,
pub zero_poi_vertical_m: f64,
pub zero_poi_horizontal_m: f64,
pub ground_threshold: f64,
pub altitude: f64,
pub temperature: f64,
pub pressure: f64,
pub humidity: f64,
pub latitude: Option<f64>,
pub wind_speed: f64,
pub wind_angle: f64,
pub twist_rate: f64,
pub is_twist_right: bool,
pub caliber_inches: f64,
pub weight_grains: f64,
pub manufacturer: Option<String>,
pub bullet_model: Option<String>,
pub bullet_id: Option<String>,
pub bullet_cluster: Option<usize>,
pub use_rk4: bool,
pub use_adaptive_rk45: bool,
pub enable_advanced_effects: bool,
pub enable_magnus: bool,
pub enable_coriolis: bool,
pub use_powder_sensitivity: bool,
pub powder_temp_sensitivity: f64,
pub powder_temp: f64,
pub powder_temp_curve: Option<Vec<(f64, f64)>>,
pub powder_curve_temp_c: Option<f64>,
pub tipoff_yaw: f64,
pub tipoff_decay_distance: f64,
pub use_bc_segments: bool,
pub bc_segments: Option<Vec<(f64, f64)>>,
pub bc_segments_data: Option<Vec<BCSegmentData>>,
pub use_enhanced_spin_drift: bool,
pub use_form_factor: bool,
pub enable_wind_shear: bool,
pub wind_shear_model: String,
pub enable_trajectory_sampling: bool,
pub sample_interval: f64,
pub drops_reference: DropsReference,
pub enable_pitch_damping: bool,
pub enable_precession_nutation: bool,
pub enable_aerodynamic_jump: bool,
pub use_cluster_bc: bool,
pub custom_drag_table: Option<DragTable>,
pub cd_scale: f64,
pub bc_type_str: Option<String>,
}Fields§
§bc_value: f64§bc_type: DragModel§bc_reference_standard: BcReferenceStandardWhich standard atmosphere bc_value/bc_segments/bc_segments_data are
referenced to (MBA-1365). Icao (the default) is a no-op; ArmyStandardMetro
is converted to the ICAO reference exactly once, in TrajectorySolver::new,
before any retardation math runs. See BcReferenceStandard.
bullet_mass: f64§muzzle_velocity: f64§bullet_diameter: f64§bullet_length: f64§muzzle_angle: f64§target_distance: f64§azimuth_angle: f64§shot_azimuth: f64Compass bearing the shot is fired ALONG, radians, 0 = North, π/2 = East.
Used only by the Coriolis model (Earth-rotation depends on which way downrange
points relative to true North). Distinct from azimuth_angle, which is the
small horizontal aiming offset and rotates the launch velocity.
shooting_angle: f64§cant_angle: f64Rifle cant angle in radians about the line of sight — positive = clockwise from the
shooter’s view (top of the scope tips right). Rotates the sight-frame aim offsets
(muzzle_angle, azimuth_angle) about the LOS and swings the bore’s sight-height
offset laterally, producing the classic canted-rifle POI error (right-and-low for
clockwise cant with an upward zero). Zeroing always solves un-canted (“zero level,
fire canted”). NOTE: treats muzzle_angle as a sight-frame offset — the standard
zero-then-fire usage; a raw gravity-frame launch angle would not rotate physically.
0.0 = level rifle (bit-identical to pre-cant behavior). (MBA-1286)
sight_height: f64§sight_offset_lateral_m: f64Lateral offset between the sight axis and the bore axis, meters (MBA-1396;
offset-mounted optics): positive = the sight sits RIGHT of the bore, so the bore
starts LEFT of the line of sight (initial lateral position z -= offset). When a
zero is solved, a windage-zero convergence term of offset / zero_distance is
added to azimuth_angle (see BallisticInputs::windage_zero_bias_rad) so the
trajectory crosses the LOS laterally at the zero range — matching AB/JBM/Shooter,
not a constant parallel offset. Without a zero solve (an explicit muzzle angle),
only the physical displacement applies. Distinct from zero_poi_horizontal_m,
which is an angular ZERO-STATE bias, not mount geometry. 0.0 (the default) is
byte-identical to pre-MBA-1396 behavior.
muzzle_height: f64§target_height: f64§zero_poi_vertical_m: f64Deliberate vertical point-of-impact offset AT THE ZERO RANGE, meters (MBA-1359;
Kestrel “zero height” semantics): positive = the rifle is deliberately zeroed to
impact HIGH by this much at the zero distance. Applied POST-solve by
calculate_and_set_zero_angle as a constant angular bias of
zero_poi_vertical_m / zero_distance on the solved elevation — the zero trials
themselves always solve perfect convergence, and the small-angle addition is
identical in both zero target frames. 0.0 (the default) is byte-identical to
pre-MBA-1359 behavior.
zero_poi_horizontal_m: f64Deliberate horizontal point-of-impact offset AT THE ZERO RANGE, meters (MBA-1359;
Kestrel “zero offset” semantics): positive = impacts RIGHT by this much at the
zero distance. Applied POST-solve as an azimuth bias of
zero_poi_horizontal_m / zero_distance when a zero is solved — see
BallisticInputs::windage_zero_bias_rad. 0.0 (the default) is neutral.
ground_threshold: f64§altitude: f64§temperature: f64§pressure: f64§humidity: f64Relative humidity as a FRACTION in [0, 1] (e.g. 0.5 = 50%). NOTE the scale
differs from AtmosphericConditions::humidity, which is a PERCENT in [0, 100].
The atmosphere helpers (calculate_air_density_*) expect percent, so convert via
BallisticInputs::humidity_percent before passing this value to them (MBA-722).
latitude: Option<f64>§wind_speed: f64§wind_angle: f64§twist_rate: f64§is_twist_right: bool§caliber_inches: f64§weight_grains: f64§manufacturer: Option<String>§bullet_model: Option<String>§bullet_id: Option<String>§bullet_cluster: Option<usize>§use_rk4: bool§use_adaptive_rk45: bool§enable_advanced_effects: bool§enable_magnus: bool§enable_coriolis: bool§use_powder_sensitivity: bool§powder_temp_sensitivity: f64§powder_temp: f64§powder_temp_curve: Option<Vec<(f64, f64)>>Optional measured powder-temperature -> muzzle-velocity curve, as
(temperature_celsius, muzzle_velocity_m_s) points sorted ascending by
temperature. When present it supersedes the linear powder_temp_sensitivity
model: the muzzle velocity is interpolated from this table at the ambient
temperature (clamped to the endpoints — no extrapolation beyond measured
data). This is the data-driven, non-linear alternative to the constant slope.
powder_curve_temp_c: Option<f64>Temperature (Celsius) at which to interpolate powder_temp_curve — the POWDER
temperature, which may differ from the ambient temperature (air). None uses
temperature. Decouples the velocity lookup from the air-density temperature.
tipoff_yaw: f64§tipoff_decay_distance: f64§use_bc_segments: boolEnables velocity-keyed bc_segments_data. Explicit Mach-keyed bc_segments retain their
legacy behavior and remain active when this flag is false.
bc_segments: Option<Vec<(f64, f64)>>§bc_segments_data: Option<Vec<BCSegmentData>>§use_enhanced_spin_drift: bool§use_form_factor: boolLegacy compatibility flag. Name-derived “form factors” are intentionally not multiplied
into reference Cd when bc_value is already the retardation denominator (MBA-1184).
enable_wind_shear: bool§wind_shear_model: String§enable_trajectory_sampling: bool§sample_interval: f64§drops_reference: DropsReferenceWhich plane sampled drop values are referenced to (MBA-1403). The default
DropsReference::Los keeps the historical behavior (drop perpendicular to the
line of sight) byte-identical; DropsReference::Target reports drop as vertical
in the target plane — the LOS-perpendicular drop scaled by
1 / cos(shooting_angle) (JBM’s “target plane” checkbox) — and, when a non-zero
target_height is supplied, slopes the sampler’s LOS datum toward it. This is an
OUTPUT-mode toggle: the solved trajectory itself is unchanged, and zero-solve
target_height semantics are untouched.
enable_pitch_damping: bool§enable_precession_nutation: bool§enable_aerodynamic_jump: bool§use_cluster_bc: bool§custom_drag_table: Option<DragTable>§cd_scale: f64Whole-curve multiplier applied to the custom deck’s interpolated Cd (MBA-1356):
Cd_used = table.interpolate(mach) * cd_scale. Meaningful only alongside
custom_drag_table — it is read at the three custom-deck interpolation sites in
cli_api.rs/derivatives.rs/fast_trajectory.rs and left untouched on the standard
G-model/BC path (those users true their drag via --bc-adjustment instead; scaling
a reference table too would double-count). Default 1.0 is neutral (byte-identical
to the pre-MBA-1356 behavior). Validated finite and > 0 by validate_for_solve.
bc_type_str: Option<String>Implementations§
Source§impl BallisticInputs
impl BallisticInputs
Sourcepub fn humidity_percent(&self) -> f64
pub fn humidity_percent(&self) -> f64
humidity as a PERCENT in [0, 100], clamped — the scale the atmosphere
density helpers expect. Centralizes the 0–1 → 0–100 conversion so callers don’t
re-derive it (and can’t accidentally feed the raw 0–1 fraction as a percentage).
See the field doc on BallisticInputs::humidity (MBA-722).
Sourcepub fn windage_zero_bias_rad(&self, zero_distance_m: f64) -> f64
pub fn windage_zero_bias_rad(&self, zero_distance_m: f64) -> f64
Azimuth bias (radians) a zero solved at zero_distance_m applies to the launch
direction. Two independent terms share this one convergence point:
- MBA-1359 — the deliberate horizontal POI offset at the zero range
(
zero_poi_horizontal_m), an angular zero-state bias; - MBA-1396 — the lateral sight-mount offset (
sight_offset_lateral_m): the bore startsoffsetleft of the LOS (seeinitial_position), so the windage zero steersoffset / zero_distanceright to cross the LOS at the zero range.
calculate_and_set_zero_angle applies this to its OWN solver’s azimuth_angle;
callers that copy a solved zero angle onto separate flight inputs (the CLI/WASM
auto-zero paths) must add this to their flight azimuth_angle themselves — the
returned elevation angle cannot carry it. Returns exactly 0.0 when both offsets
are 0.0 or zero_distance_m is not positive, so default inputs stay
byte-identical.
Sourcepub fn sectional_density_lb_in2(&self) -> Option<f64>
pub fn sectional_density_lb_in2(&self) -> Option<f64>
Sectional density in lb/in²: weight_grains / 7000 / diameter_in².
Derived from the imperial mirror fields (weight_grains / caliber_inches), falling
back to the SI bullet_mass (kg) / bullet_diameter (meters) for SI-only callers
(mirrors the fallbacks in derivatives.rs). None when neither source is usable.
Sourcepub fn custom_drag_denominator(&self, fallback_bc: f64) -> f64
pub fn custom_drag_denominator(&self, fallback_bc: f64) -> f64
Retardation denominator to use when custom_drag_table is active.
A custom drag table supplies the projectile’s ACTUAL drag coefficient, so the
point-mass retardation formula must divide it by the projectile’s SECTIONAL DENSITY
(lb/in²), not by a ballistic coefficient: BC = SD / i (form factor i vs the reference
projectile), and with the projectile’s own curve i == 1, so Cd_own / SD == Cd_ref / BC.
Dividing the curve’s Cd by bc_value made custom-table trajectories wrongly scale
with whatever BC happened to be set.
Falls back to fallback_bc (with a one-time stderr warning) when mass/diameter are
unavailable, so degenerate inputs degrade to the old behavior instead of panicking.
Sourcepub fn bc_reference_standard_inert_warning(&self) -> Option<&'static str>
pub fn bc_reference_standard_inert_warning(&self) -> Option<&'static str>
Whether a declared bc_reference_standard is inert on this configuration
(MBA-1365), and if so, the message explaining why.
A custom drag table (custom_drag_table) supplies the projectile’s actual Cd and
divides by sectional density, not by a BC value (see custom_drag_denominator),
so an ArmyStandardMetro reference has no physical effect once a table is active.
Pure and side-effect-free — same shape as main.rs’s adjustment_unit_noop_warning
(MBA-1414) — so each surface decides how to surface it: the native CLI prints it to
stderr once per run, while the WASM browser terminal (no visible stderr) splices it
into its table-output text instead.
Sourcepub fn normalize_for_solve(&mut self)
pub fn normalize_for_solve(&mut self)
Apply every input-conditioning step integration requires, exactly once (MBA-1415).
Every public entry point into integration must call this, not just
TrajectorySolver::new. fast_trajectory::fast_integrate and
fast_integrate_with_segments are pub and are called directly by the Python
binding, so conditioning that lives only in the solver constructor is invisible to
those consumers: the caller sets a field, gets no error, and the value is silently
ignored. That exact shape has already cost this project twice — MBA-1296 (a dropped
field that zeroed Coriolis in production) and the MBA-1356 review catch
(cd_scale dropped by the segmented fast path). Adding a step here rather than at a
call site is what keeps the next one from repeating it.
Idempotent, and it must stay that way: Monte Carlo builds a solver per sample, and
the fast entry points may receive inputs that already passed through a solver. Each
step below is either an absolute override (derived fields, powder-resolved velocity) or
self-disarming (the BC conversion rewrites bc_reference_standard to the reference it
just converted into, so a second call finds nothing to do). A step that scales a value
in place without disarming itself would double-apply silently — do not add one.
Trait Implementations§
Source§impl Clone for BallisticInputs
impl Clone for BallisticInputs
Source§fn clone(&self) -> BallisticInputs
fn clone(&self) -> BallisticInputs
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 BallisticInputs
impl Debug for BallisticInputs
Auto Trait Implementations§
impl Freeze for BallisticInputs
impl RefUnwindSafe for BallisticInputs
impl Send for BallisticInputs
impl Sync for BallisticInputs
impl Unpin for BallisticInputs
impl UnsafeUnpin for BallisticInputs
impl UnwindSafe for BallisticInputs
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.