Expand description
Describe an atmosphere the way a solve resolves it: the service behind the
atmosphere.density_altitude bridge command.
§Why this exists
Density altitude was reachable only as one field inside a DOPE card, so an embedding app wanting to show it had to reimplement the formula — and an external Android app did, then hand-maintained the copy with its own regression tests (2026-09). A copy of a formula is a copy that drifts. This service answers the question directly, from the same code the solver and the card use.
§One atmosphere schema, decoded and resolved one way
The request carries the SAME atmosphere object a solve-json v1 request does
(AtmosphereV1). It is decoded by the solve’s own shape validator and resolved by the
solve’s own resolver (solve_v1::resolve_atmosphere), so every error the solve would give
for that object comes back identically — same code, same $.atmosphere.* path — as do the
ICAO-standard defaults for whatever is omitted (each announced in assumptions) and the
QNH-to-station reduction. An app can send the atmosphere it is about to solve with and get
the density altitude of precisely that air.
§Then checks the solve does not make (yet — MBA-1594)
The solve’s resolver only requires temperature and pressure to be positive, which admits air
that cannot exist: 5 K, a humidity whose vapor pressure exceeds the air’s total pressure, a
pressure altitude of 30 km. Those are also exactly what the two likeliest unit mistakes
produce — °C sent as temperature_k, hPa sent as pressure_pa — so a figure computed from
them is a wrong answer delivered confidently. This service refuses them instead, with the
same invalid_value envelope and the path of the input to blame:
temperature_koutside 173.15–373.15 K (−100 °C to 100 °C), where the engine’s saturation-vapor and compressibility formulas are defined;- station pressure whose pressure altitude is outside −5 km to 11 km — the standard atmosphere’s troposphere, which is all the closed-form arithmetic here covers;
- a relative humidity that would need more vapor pressure than the total pressure;
- either density altitude outside −5 km to 11 km.
None of these rejects a condition anyone has fired a rifle in.
§Two density altitudes, by name
“Density altitude” means two different things in the field, and one number under one name
is how the confusion this module answers arose. The response therefore never offers a bare
density_altitude; it offers both, and a caller has to choose:
faa_rule—crate::atmosphere::faa_rule_density_altitude_ft: NWS pressure altitude plus the FAA’s “120 ft per °C” rule of thumb. Humidity-free. This is the formula the engine’s DOPE card header uses, and the exact inverse of the density-altitude ENTRY mode.density_matched—crate::atmosphere::density_matched_altitude_m: the ISA altitude whose standard density equals this air’s actual density, humidity included. The textbook definition, and what humidity-aware tools report — the National Weather Service’s own density-altitude calculator included.
They coincide at ICAO standard sea-level dry air; anywhere else a match is coincidence. They differ by 33.1 m at 15 °C, 1013.25 hPa and 50% RH (humidity), and by about 22 m at 30 °C in perfectly DRY air (the FAA rule’s straight-line approximation). The difference between them is therefore NOT a humidity correction, and must not be presented as one.
air_density_kg_m3 is reported as well: the CIPM-2007 density the solver itself uses at
the muzzle, which answers “how thin is the air” with no definition to argue about.
Structs§
- Altitude
V1 - One altitude in both units a shooter meets it in. Density altitude is conventionally quoted in feet even by shooters who range in meters, so both travel together rather than asking every caller to convert.
- Density
Altitude Request V1 atmosphere.density_altituderequest.- Density
Altitude Response V1 atmosphere.density_altituderesult.- Density
Altitudes V1 - The two density altitudes, each under its own name. See the module docs for why there is
no single
density_altitudevalue.
Functions§
- decode_
density_ altitude_ request_ v1 - Decode an
atmosphere.density_altituderequest from JSON the waysolvedecodes itsatmosphere: the solve’s own shape validator runs first, so an unknown or unit-suffixed field, an explicitnull, a string where a number belongs or an unrecognizedpressure_referenceis refused with the solve’s code at the solve’s$.atmosphere.*path. - density_
altitude_ v1 - Resolve
request.atmosphereexactly as a solve would, check that the air it describes can exist and lies where these formulas hold, then report its pressure altitude, both density altitudes and its air density.