Radius At Geocentric Latitude — Robotics/Flight Parameters
Robotics/Flight_Parameters/Radius_At_Geocentric_Latitude · 1 input / 1 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.
Radius at Geocentric Latitude
Robotics / Flight Parameters
The distance from a planet's centre to its surface, at a given geocentric latitude, for an ellipsoid of equatorial radius R and flattening f:
r(λ) = √( R² / (1 + (1/(1−f)² − 1) · sin²λ) )
At the equator this is R; at the pole it collapses to R·(1−f), the polar radius.
Ports
- λ – the geocentric latitude, in DEGREES. Any size [m,n]; the block works entry by entry.
- r – the radius, in the units of R. Same size as the input.
Parameters
- Flattening – the ellipsoid's flattening f, a scalar. Dimensionless. Defaults to 0.0033528106647474805, which is WGS84's 1/298.257223563. A value of exactly 1 is refused: the formula divides by (1−f)². Zero gives a sphere of radius R at every latitude.
- Equatorial Radius – the ellipsoid's equatorial radius R, a scalar, in whatever length unit the output should carry. Defaults to WGS84's 6378137 metres.
- 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.
Both parameters are baked into the arithmetic at export time, not
exposed as tunables: they describe which planet this is, which is structure
rather than a knob. The two constants actually emitted are
R² and 1/(1−f)² − 1, printed at
17 significant digits so every backend computes the same double.
The three HDL targets are simulation-only: a sine, a division
and a square root have no Q16.16 form, so the values convert at the port
boundary and the arithmetic runs in real. And the fixed-point
port cannot carry an Earth-sized radius at all – Q16.16 saturates past
about 32767 – so an HDL export of this block is for small custom bodies,
or for a radius expressed in a larger unit. The seven software targets have no
such limit.
Simulink bridge
Import and export, mapped to Aerospace Blockset's
aerolibasang/Radius at Geocentric Latitude.
Flattening → F and Equatorial Radius →
R, values passing straight through.
Two Simulink parameters are always implied and carry no configuration here:
ptype is always Custom and units always
Metric (MKS). Custom is not cosmetic – measured in R2026a, a block
left on its Earth (WGS84) setting accepts and discards a written
F or R, so the two values only take effect alongside it. Custom carrying the
WGS84 numbers is bit-identical to the Earth setting, so nothing is lost.
The Simulink block defines no SampleTime, so the rate stays
on the ICore side.
Notes
- Algebraic and stateless: the output depends on this sample alone.
- The latitude is in degrees, and it is geocentric – the angle at the planet's centre, not the geodetic latitude a map uses. The neighbouring Wind Angular Rates takes radians; the two come from the same Simulink sublibrary.
- Not linear – a square root of a reciprocal of a sine squared – so the block carries no state space and model reduction correctly reports it as unmergeable.
- The result is symmetric in λ: northern and southern latitudes of the same magnitude give the same radius, and so do λ and 180−λ.
Code facts#
| Fact | Value |
|---|---|
| registered type | Robotics/Flight_Parameters/Radius_At_Geocentric_Latitude |
| family | Robotics/Flight_Parameters |
| solver environment class | ICoreBlock_0_Robotics_1_Flight_Parameters_2_Radius_At_Geocentric_Latitude |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Flight_Parameters/Radius_At_Geocentric_Latitude/ICoreBlock_0_Robotics_1_Flight_Parameters_2_Radius_At_Geocentric_Latitude.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Flight_Parameters/Radius_At_Geocentric_Latitude/ICoreBlock_0_Robotics_1_Flight_Parameters_2_Radius_At_Geocentric_Latitude.h |
| default size on canvas | 134 × 72 px |
| ports at insert | 1 in, 1 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 | lambda |
| 2 | out | ICoreDouble | r |
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 |
|---|---|---|
Flattening | rgFmt(WGS84_F) | — |
Equatorial Radius | rgFmt(WGS84_R) | — |
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/Radius at Geocentric\nLatitude |
| port-count rule | PortsParam::None |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| always set | ptype = Custom, units = Metric (MKS) |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
CONFIG_F.c_str() | F | passes through |
CONFIG_R.c_str() | R | passes through |
Caveat (shown to the user): the latitude is in DEGREES on both sides, and it is GEOCENTRIC rather than geodetic. 'ptype' is always written as Custom: measured in R2026a, a block left on Earth (WGS84) accepts a written F or R and discards it, so the pair only takes effect alongside Custom -- which, carrying the WGS84 numbers, is bit-identical to the Earth setting. 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:
B02 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).
Radius at Geocentric Latitude -- r(lambda) on an ellipsoid r(lambda) = sqrt( R^2 / (1 + (1/(1-f)^2 - 1) * sin^2(lambda)) )
R is the equatorial radius and f the flattening; at lambda = 0 the expression is R and at lambda = 90 it collapses to R*(1-f), the polar radius, which is what fixes the shape of the denominator rather than any of the several near-identical forms in circulation.
MEASURED AGAINST R2026a rather than recalled. With its WGS84 defaults the Simulink block answers 6378137, 6372770.6011371911, 6367417.7249666834 and 6356752.3142451793 at 0, 30, 45 and 90; with a custom f = 0.081, R = 2.9 it answers 2.9, 2.8355003900093494, 2.7751214617639866 and 2.6652419437363424 at 0, 30, -45 and 88.5. The expression above reproduces all eight to the last bit.
⚠ THE LATITUDE IS IN DEGREES. That is a measurement, not a convention borrowed from a sibling: fed 1.5708 the block moves the radius by 16 m, and fed 90 it lands exactly on the polar radius. The neighbouring Wind Angular Rates takes RADIANS, and the two blocks come from the same Simulink sublibrary.
⚠ ptype IS EMITTED AS 'Custom' AND THAT IS LOAD-BEARING. Measured: with ptype at its 'Earth (WGS84)' default a set_param of F or R is accepted and silently discarded -- the dialog field is disabled and the block keeps the WGS84 numbers. The pair only sticks when Custom is part of the same set_param call, which is exactly what a fixedParam gives (the .m writer emits every mapped and fixed pair in ONE call, and MATLAB applies them together: measured, F and R stick whether Custom is listed before them or after). 'Custom' with the WGS84 numbers is bit-identical to 'Earth (WGS84)' -- 6370186.8928369889 at lambda = 37.5 from both -- so nothing is lost by always choosing it.
⚠ THE THREE HDL TARGETS ARE SIMULATION-ONLY. A sine, a division and a square root have no Q16.16 form. Worse for this block than for its neighbours: Q16.16 saturates past 32767, so an EARTH-SIZED radius cannot be carried on a fixed-point port at all. Those targets are for small custom bodies, and the description says so.
Sample results#
| t | in ICoreDouble-Out-0 | out ICoreDouble-Out-0 |
|---|---|---|
| 0 | -2 | 6.378e6 |
| 0.4 | 0.5 | 6.378e6 |
| 0.8 | -2 | 6.378e6 |
| 1.2 | 0.5 | 6.378e6 |
| 1.6 | -2 | 6.378e6 |
| 2 | 0.5 | 6.378e6 |
| 2.4 | -2 | 6.378e6 |
| 2.8 | 0.5 | 6.378e6 |
| 3.2 | -2 | 6.378e6 |
| 3.6 | 0.5 | 6.378e6 |
| 4 | -2 | 6.378e6 |
| 4.4 | 0.5 | 6.378e6 |
| 4.8 | -2 | 6.378e6 |
| 5.2 | 0.5 | 6.378e6 |
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) | 6.378e6 … 6.378e6 |
ramp | Ramp: slope 1 from t = 0 | 6.378e6 … 6.378e6 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | 6.378e6 … 6.378e6 |
step | Step: 0 -> 1 at t = 1 s | 6.378e6 … 6.378e6 |
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__Radius_At_Geocentric_Latitude.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).