ISA Atmosphere — Robotics/Atmosphere
Robotics/Atmosphere/ISA_Atmosphere · 1 input / 4 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text
Description#
The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.
ISA Atmosphere
Robotics / Atmosphere
The International Standard Atmosphere as a lapse-rate model whose ten constants are all configuration: a geopotential altitude in, and the atmosphere's temperature, speed of sound, static pressure and density out. One layer with a lapse rate up to the troposphere, an isothermal layer to the tropopause, and nothing changing above it. With hT and hS the altitude clamped into each of those two ranges:
- T = T₀ − L·hT
- θ = T·(1/T₀) and ratio = θg/(LR)·e(g/R)(htrop−hS)/T
- P = P₀·ratio and ρ = ρ₀·(ratio/θ)
- a = √((γR)T)
Left at its defaults it is the standard atmosphere; changed, it is any single-lapse atmosphere, which is what Aerospace Blockset offers under the second name Lapse Rate Model. A fixed seven-layer atmosphere that takes no constants at all is COESA Atmosphere.
Ports
- h – the geopotential altitude, in metres. Any size [m,n]; the block works entry by entry.
- T – the temperature, in kelvin. Same size as the input.
- a – the speed of sound, in m/s. Same size as the input.
- P – the static pressure, in pascals. Same size as the input.
- rho – the density, in kg/m³. Same size as the input.
Parameters
- Gravitational Acceleration – g, a scalar in m/s². Defaults to 9.80665.
- Ratio Of Specific Heats – γ, dimensionless. Defaults to 1.4, and it affects the speed of sound only.
- Characteristic Gas Constant – R, a scalar in J/(kg·K). Defaults to 287.0531.
- Lapse Rate – L, a scalar in K/m, and a positive value is a temperature that FALLS with altitude: T = T₀ − L·hT. Defaults to 0.0065. Exactly zero is refused – it makes the pressure exponent g/(LR) infinite, and an infinite exponent over a base that rounds to just under 1 answers zero rather than an isothermal atmosphere.
- Height Of Troposphere – htrop, in metres, where the lapse stops. Defaults to 11000.
- Height Of Tropopause – hstrat, in metres, where the isothermal layer stops and every output holds its value. Defaults to 20000, and it must not be below the troposphere.
- Sea Level Density – ρ₀, in kg/m³. Defaults to 1.225.
- Sea Level Pressure – P₀, in pascals. Defaults to 101325.
- Sea Level Temperature – T₀, in kelvin, and it must be positive. Defaults to 288.15.
- Minimum Sea Level Altitude – h₀, in metres, a FLOOR and not an origin: the lapse is applied to the clamped altitude rather than to (h − h₀), so at h₀ = 500 the temperature is T₀ − 500L and not T₀. Defaults to 0, and it must not be above the troposphere.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text.
The ten constants are baked into the emitted arithmetic at export time rather than exposed as tunables, along with the four quantities derived from them – 1/T₀, g/(LR), g/R and γR. They describe which atmosphere this is, which is structure and not a knob, and deriving them once is also what keeps the ten backends from differing by an association order. All are printed at 17 significant digits.
The three hardware targets are simulation-only: a power with a fractional exponent, an exponential and a square root have no Q16.16 form, so values convert at the port boundary and the arithmetic runs in floating point. And a fixed-point port cannot carry a sea-level pressure at all – Q16.16 saturates past about 32767, while the default P₀ is 101325 – so a hardware export of this block wants either a thin-atmosphere altitude range or a smaller P₀.
Simulink bridge
Import and export, mapped to Aerospace Blockset's
aerolibatmos2/Lapse Rate Model. All ten configuration values cross
straight through to the parameters of the same meaning:
Gravitational Acceleration → g,
Ratio Of Specific Heats → gamma,
Characteristic Gas Constant → R,
Lapse Rate → L,
Height Of Troposphere → h_trop,
Height Of Tropopause → h_strat,
Sea Level Density → rho0,
Sea Level Pressure → P0,
Sea Level Temperature → T0 and
Minimum Sea Level Altitude → h0.
aerolibatmos2/ISA Atmosphere Model is the same Simulink
block – identical mask, identical parameter list – differing only
in whether its custom switch is on, so this one entry covers both
library paths. Four parameters are always implied: custom is always
on, because every constant here is configuration; useExtended
always off, the extended form being a seven-layer atmosphere and therefore
COESA Atmosphere's job; viscosityOut always off, since
switching it on adds two more output ports and this block has four; and
action always None, that parameter only choosing whether
Simulink warns about an altitude outside its range. The Simulink block defines
no SampleTime parameter, measured, so the rate stays on the
ICore side.
Notes
- Algebraic and stateless: the outputs depend on this sample alone.
- Not linear, so the block carries no state space and model reduction correctly reports it as unmergeable.
- The altitude is GEOPOTENTIAL, not geometric, and nothing converts between the two.
- Above the tropopause nothing changes. Both clamps are saturated there, so all four outputs hold their tropopause values however high the altitude goes – which is what the reference does, and not a physical claim.
- A non-positive temperature answers zero on all four outputs. A large
enough lapse rate drives T through zero, at which point the pressure's power has
a negative base; VHDL's real
**asserts there rather than answering, aborting a simulation instead of producing a bad number, so all ten targets carry the same guard. - The default ρ₀ and R are very slightly inconsistent with the perfect-gas relation, which is why this block's sea-level density is exactly 1.225 and COESA Atmosphere's is 1.2249991558877125. Both are faithful to their own reference.
- Verified against R2026a over two full parameter sets and 25 altitudes – 100 answers – agreeing to at worst 1.8×10−16 relative.
Code facts#
| Fact | Value |
|---|---|
| registered type | Robotics/Atmosphere/ISA_Atmosphere |
| family | Robotics/Atmosphere |
| solver environment class | ICoreBlock_0_Robotics_1_Atmosphere_2_ISA_Atmosphere |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Atmosphere/ISA_Atmosphere/ICoreBlock_0_Robotics_1_Atmosphere_2_ISA_Atmosphere.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Atmosphere/ISA_Atmosphere/ICoreBlock_0_Robotics_1_Atmosphere_2_ISA_Atmosphere.h |
| default size on canvas | 160 × 110 px |
| ports at insert | 1 in, 4 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | h |
| 2 | out | ICoreDouble | T |
| 3 | out | ICoreDouble | a |
| 4 | out | ICoreDouble | P |
| 5 | out | ICoreDouble | rho |
Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.
Configuration variables#
| Config variable | Default | Simulink parameter |
|---|---|---|
Gravitational Acceleration | iaFmt(DEF_G) | — |
Ratio Of Specific Heats | iaFmt(DEF_GAMMA) | — |
Characteristic Gas Constant | iaFmt(DEF_R) | — |
Lapse Rate | iaFmt(DEF_L) | — |
Height Of Troposphere | iaFmt(DEF_HTROP) | — |
Height Of Tropopause | iaFmt(DEF_HSTRAT) | — |
Sea Level Density | iaFmt(DEF_RHO0) | — |
Sea Level Pressure | iaFmt(DEF_P0) | — |
Sea Level Temperature | iaFmt(DEF_T0) | — |
Minimum Sea Level Altitude | iaFmt(DEF_H0) | — |
Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.
Simulink bridge#
| support | Support::Both |
| Simulink path | aerolibatmos2/Lapse Rate Model |
| port-count rule | PortsParam::None |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| always set | custom = on, useExtended = off, viscosityOut = off, action = None |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
CONFIG_G.c_str() | g | passes through |
CONFIG_GAMMA.c_str() | gamma | passes through |
CONFIG_R.c_str() | R | passes through |
CONFIG_L.c_str() | L | passes through |
CONFIG_HTROP.c_str() | h_trop | passes through |
CONFIG_HSTRAT.c_str() | h_strat | passes through |
CONFIG_RHO0.c_str() | rho0 | passes through |
CONFIG_P0.c_str() | P0 | passes through |
CONFIG_T0.c_str() | T0 | passes through |
CONFIG_H0.c_str() | h0 | passes through |
Caveat (shown to the user): the altitude is GEOPOTENTIAL and in metres, and the four outputs are kelvin, m/s, pascals and kg/m^3. 'aerolibatmos2/ISA Atmosphere Model' is the SAME Simulink block -- identical mask, identical parameter list -- differing only in whether 'custom' is on, so this entry covers both library paths. 'custom' is always written on, because every constant here is configuration; 'useExtended' always off, the extended form being a seven-layer atmosphere and therefore COESA Atmosphere's job; 'viscosityOut' always off, since switching it on adds two more output ports and this block has four; 'action' always None, that parameter only choosing whether Simulink warns about an altitude outside its range. The Simulink block has no SampleTime, so the rate stays on the ICore side
Catalog contract: src/ICoreBlocks/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The checker has a blind spot here — it could not resolve something (a grouped port bullet, a computed config name), which is reported and never counted as a pass. A reader has to settle it:
B010 Simulink params rule(s) this tool cannot resolve
The verdict above is
tools/docs/check_block_descriptions.py(P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.
File banner (developer view)#
The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).
ISA Atmosphere -- the International Standard Atmosphere, as a lapse-rate model you can tune hT = min(max(h, h0), h_trop) T = T0 - L * hT hS = min(max(h, h_trop), h_strat) theta = T * (1 / T0) ratio = theta^(g/(L*R)) * exp((g/R) * (h_trop - hS) / T) P = P0 * ratio rho = rho0 * (ratio / theta) a = sqrt((gamma * R) * T)
⚠ THREE OF THOSE SPELLINGS ARE NOT THE OBVIOUS ALGEBRAIC FORM, AND THEY WERE MEASURED. Against R2026a's own block over two full parameter sets and 25 altitudes -- 100 answers -- this arrangement lands at worst 1.8e-16 relative, about one unit in the last place. The obvious forms are three to four times further out:
T / T0in place ofT * (1/T0)reaches 6.1e-16,exp(-g*(hS-h_trop)/(R*T))in place of the pre-dividedg/Randrho0*(P/P0)*(T0/T)in place ofrho0*(ratio/theta)each cost their own last places. The Simulink block carries a Gain of 1/T0, a Gain of g/R and a division by theta -- read out of the masked subsystem, then confirmed by driving it -- so every backend writes them the same way round.⚠ h0 IS A FLOOR, NOT AN ORIGIN: the lapse acts on the CLAMPED altitude, not on (h - h0), so at h0 = 500 the temperature is T0 - L*500 rather than T0. Measured, and it is the one thing about this block a reader is likely to assume the other way round.
⚠ ONE SIMULINK BLOCK, TWO LIBRARY ENTRIES --
ISA Atmosphere ModelandLapse Rate Modelare the same masked block at two settings of itscustomswitch. See the header.⚠ A LAPSE RATE OF EXACTLY ZERO IS REFUSED, with a reason: it makes the pressure exponent infinite, and an infinite exponent over a base that rounds to just under 1 answers zero rather than an isothermal atmosphere.
ALGEBRAIC and STATELESS, and nonlinear in its input, so no state space.
Sample results#
| t | in ICoreDouble-Out-0 | out ICoreDouble-Out-0 | out ICoreDouble-Out-1 | out ICoreDouble-Out-2 |
|---|---|---|---|---|
| 0 | -2 | 288.1 | 340.3 | 1.013e5 |
| 0.4 | 0.5 | 288.1 | 340.3 | 1.013e5 |
| 0.8 | -2 | 288.1 | 340.3 | 1.013e5 |
| 1.2 | 0.5 | 288.1 | 340.3 | 1.013e5 |
| 1.6 | -2 | 288.1 | 340.3 | 1.013e5 |
| 2 | 0.5 | 288.1 | 340.3 | 1.013e5 |
| 2.4 | -2 | 288.1 | 340.3 | 1.013e5 |
| 2.8 | 0.5 | 288.1 | 340.3 | 1.013e5 |
| 3.2 | -2 | 288.1 | 340.3 | 1.013e5 |
| 3.6 | 0.5 | 288.1 | 340.3 | 1.013e5 |
| 4 | -2 | 288.1 | 340.3 | 1.013e5 |
| 4.4 | 0.5 | 288.1 | 340.3 | 1.013e5 |
| 4.8 | -2 | 288.1 | 340.3 | 1.013e5 |
| 5.2 | 0.5 | 288.1 | 340.3 | 1.013e5 |
Every 4th of 60 samples, from the table stimulus.
The same rig also ran:
| Stimulus | What it is | Output range |
|---|---|---|
impulse | Impulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair) | 288.1 … 288.1 |
ramp | Ramp: slope 1 from t = 0 | 288.1 … 288.1 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | 288.1 … 288.1 |
step | Step: 0 -> 1 at t = 1 s | 288.1 … 288.1 |
Plotted: table — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample
Category static · sample time 0.1 · 60 steps · commit 7df85021459493e38f84f64127a6774c411e769c · produced by docsSample --out <folder> --blocks COESA_Atmosphere ISA_Atmosphere Pressure_Altitude --steps 60 · data docs/generated/samples/Robotics__Atmosphere__ISA_Atmosphere.json · the SVG is generated from those numbers by tools/docs/plot_svg.py, so it is a run and not a drawing (R-D10).