Relative Ratio — Robotics/Flight Parameters
Robotics/Flight_Parameters/Relative_Ratio · 5 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.
Relative Ratio
Robotics / Flight Parameters
Brings a flow at Mach M to rest isentropically and reports the total (stagnation) temperature, pressure and density it reaches, each as a ratio of the ISA sea-level value. With k = 1 + (γ−1)/2 · M²:
- θ = T · k / 288.15
- √θ
- δ = P · kγ/(γ−1) / 101325
- σ = ρ · k1/(γ−1) / 1.225
The three denominators are the ISA sea-level temperature, pressure and density; they are what makes each output a relative ratio, and they are fixed – there is no configuration to change them.
Ports
- M – the Mach number, a [1,1] scalar, dimensionless. It enters only as M², so its sign does not matter.
- γ – the ratio of specific heats, a [1,1] scalar, dimensionless. 1.4 for dry air. It must not be exactly 1: both exponents divide by γ−1.
- T – the static temperature, a [1,1] scalar, in kelvin.
- P – the static pressure, a [1,1] scalar, in pascal.
- ρ – the static density, a [1,1] scalar, in kg/m³.
- theta – the total temperature over 288.15 K, a [1,1] scalar, dimensionless.
- sqrt_theta – the square root of the port above, a [1,1] scalar. It is offered separately because the Simulink block offers it.
- delta – the total pressure over 101325 Pa, a [1,1] scalar, dimensionless.
- sigma – the total density over 1.225 kg/m³, a [1,1] scalar, dimensionless.
No output's size follows an input: every port on this block is scalar.
The units matter here in a way they do not on most blocks, because the three sea-level constants are in SI. Feeding pressure in another unit does not rescale the answer – it makes it wrong.
Parameters
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
There are no others: all five quantities arrive on ports.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text.
The three HDL targets are simulation-only, for three reasons
rather than one. Two of the four outputs raise a value to a power whose
exponent is itself an input, so nothing can be folded into a constant at
export time; there is a square root; and a sea-level pressure of 101325
is far outside what a Q16.16 word holds. Everything converts at the port
boundary and runs in real. The cores simulate correctly and are not
offered as synthesizable.
Where the maths is undefined, the two worlds answer differently on
purpose. γ = 1 divides by zero in both exponents; γ < 1 at a
high enough Mach makes k negative, and a negative base with a fractional exponent
has no real value; a negative T makes θ negative and its root
imaginary. The seven software targets produce IEEE Inf or NaN there
and agree exactly; the three HDL cores answer 0, because fixed point
carries neither – and because VHDL's math_real would otherwise
abort the simulation rather than return a bad number.
Simulink bridge
Import and export, mapped to Aerospace Blockset's
aerolibasang/Relative Ratio. No configuration crosses, because there
is none: all five inputs are ports on both sides.
Five Simulink parameters are always implied and carry no configuration here.
units is always Metric (MKS), matching the SI constants
above; and theta, sq_theta, delta and
sigma are always on, because this block always produces all
four. Those four checkboxes are how the Simulink block removes output
ports, and an ICore block's port list is not a parameter, so keeping them on is
what makes the two port lists the same length.
The Simulink block defines no SampleTime, so the rate
stays on the ICore side.
Notes
- Algebraic and stateless: the outputs depend on this sample alone.
- Not linear – two variable-exponent powers and a root – so the block carries no state space and model reduction correctly reports it as unmergeable.
- At M = 0 the factor k is 1 and the three ratios collapse to the static state over sea level, which is the cheapest check that a rig is wired the way it thinks it is.
- √θ is a separate output rather than something to compute downstream because that is what the Simulink block offers; it is exactly the square root of the first output.
Code facts#
| Fact | Value |
|---|---|
| registered type | Robotics/Flight_Parameters/Relative_Ratio |
| family | Robotics/Flight_Parameters |
| solver environment class | ICoreBlock_0_Robotics_1_Flight_Parameters_2_Relative_Ratio |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Flight_Parameters/Relative_Ratio/ICoreBlock_0_Robotics_1_Flight_Parameters_2_Relative_Ratio.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Flight_Parameters/Relative_Ratio/ICoreBlock_0_Robotics_1_Flight_Parameters_2_Relative_Ratio.h |
| default size on canvas | 128 × 112 px |
| ports at insert | 5 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 | M |
| 2 | in | ICoreDouble | gamma |
| 3 | in | ICoreDouble | T |
| 4 | in | ICoreDouble | P |
| 5 | in | ICoreDouble | rho |
| 6 | out | ICoreDouble | theta |
| 7 | out | ICoreDouble | sqrt_theta |
| 8 | out | ICoreDouble | delta |
| 9 | out | ICoreDouble | sigma |
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#
No config variable beyond the Sampling Time (s) every block carries.
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 | aerolibasang/Relative Ratio |
| port-count rule | PortsParam::None |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| always set | units = Metric (MKS), theta = on, sq_theta = on, delta = on, sigma = on |
Caveat (shown to the user): all five quantities are ports on both sides, in the order M, gamma, Tstatic, Pstatic, rho -- and the units are SI, because the three sea-level constants (288.15 K, 101325 Pa, 1.225 kg/m^3) are baked into both blocks. The four output checkboxes are always written 'on': they are how the Simulink block REMOVES output ports, and this block always produces all four. 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 lists agree. check_block_descriptions.py finds no disagreement between the description's Ports, Parameters, Code export and Simulink bridge lists and the code's.
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).
Relative Ratio -- the four sea-level ratios of a flow's TOTAL state Bring a flow at Mach M to rest isentropically and its temperature, pressure and density all rise by a power of the same factor. With k = 1 + (gamma-1)/2 * M^2:
theta = Tstatic * k / 288.15 sqrt(theta) delta = Pstatic * k^(gamma/(gamma-1)) / 101325 sigma = rho * k^(1/(gamma-1)) / 1.225
The three denominators are the ISA sea-level values, and they are what the word "relative" in the block's name refers to. They are baked in on both sides: the Simulink mask carries them as the constants 1/288.15, 1/101325 and 1/1.225, which is where these came from.
MEASURED AGAINST R2026a rather than recalled. At M = 0.62, gamma = 1.4, Tstatic = 250.3, Pstatic = 70000.7 and rho = 0.9012, aerolibasang/Relative Ratio answers 0.93542621551275396 0.96717434597530239 0.89530572149109577 0.8853263135685997 and the four expressions above reproduce all four to within one unit in the last place.
⚠ THE BLOCK IS SCALAR ON EVERY PORT, and that is measured too: fed five 2-element columns the Simulink block fails to compile ("Error due to multiple causes"), so the five inputs and four outputs are all [1,1] here as well.
⚠ THE THREE HDL TARGETS ARE SIMULATION-ONLY, for three reasons rather than one: two powers whose EXPONENT is a function of an input (so nothing folds into a constant at export time), a square root, and a sea-level pressure of 101325 that a Q16.16 word cannot represent at all. The guards in those three backends are not optional the way IEEE's are in the software targets: VHDL's math_real ASSERTS on SQRT of a negative and on "**" with a non-positive base, which aborts a simulation rather than answering a NaN.
⚠ WHAT MAKES THE MATHS UNDEFINED, in both worlds. gamma = 1 puts a zero in both exponent denominators; gamma < 1 with a large enough Mach makes k negative, and a negative base with a fractional exponent has no real value; a negative Tstatic makes theta negative and its root imaginary. The seven software targets answer IEEE infinity or NaN there and agree exactly with each other; the three HDL cores answer 0, because fixed point carries neither. Stated in the description rather than papered over with a branch nobody asked for.
Sample results#
16 sample(s) were non-finite (nan/inf) and are absent from the plot; they are in the table below and in the JSON.
| t | in ICoreDouble-Out-0 | in ICoreDouble-Out-0 | in ICoreDouble-Out-0 | out ICoreDouble-Out-0 | out ICoreDouble-Out-1 | out ICoreDouble-Out-2 |
|---|---|---|---|---|---|---|
| 0 | -2 | -2 | -2 | 0.0347 | 0.1863 | nan |
| 0.4 | 0.5 | 0.5 | 0.5 | 0.001627 | 0.04033 | 5.264e-6 |
| 0.8 | -2 | -2 | -2 | 0.0347 | 0.1863 | nan |
| 1.2 | 0.5 | 0.5 | 0.5 | 0.001627 | 0.04033 | 5.264e-6 |
| 1.6 | -2 | -2 | -2 | 0.0347 | 0.1863 | nan |
| 2 | 0.5 | 0.5 | 0.5 | 0.001627 | 0.04033 | 5.264e-6 |
| 2.4 | -2 | -2 | -2 | 0.0347 | 0.1863 | nan |
| 2.8 | 0.5 | 0.5 | 0.5 | 0.001627 | 0.04033 | 5.264e-6 |
| 3.2 | -2 | -2 | -2 | 0.0347 | 0.1863 | nan |
| 3.6 | 0.5 | 0.5 | 0.5 | 0.001627 | 0.04033 | 5.264e-6 |
| 4 | -2 | -2 | -2 | 0.0347 | 0.1863 | nan |
| 4.4 | 0.5 | 0.5 | 0.5 | 0.001627 | 0.04033 | 5.264e-6 |
| 4.8 | -2 | -2 | -2 | 0.0347 | 0.1863 | nan |
| 5.2 | 0.5 | 0.5 | 0.5 | 0.001627 | 0.04033 | 5.264e-6 |
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) | 0 … 0.00347 |
ramp | Ramp: slope 1 from t = 0 | 0 … 1.767 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | -0.001483 … 0.003468 |
step | Step: 0 -> 1 at t = 1 s | 0 … 0.00347 |
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 3c100aff6f27235305db4ad4d572f32e342718ad · produced by docsSample --out <folder> --blocks Radius_At_Geocentric_Latitude Relative_Ratio Wind_Angular_Rates --steps 60 · data docs/generated/samples/Robotics__Flight_Parameters__Relative_Ratio.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).