Generated reference › LLA To ECEF Position — Robotics/Axes Transformations
kind: generated#block#robotics-axes-transformations

LLA To ECEF Position — Robotics/Axes Transformations

φλh xyz

Robotics/Axes_Transformations/LLA_To_ECEF_Position · 2 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.

LLA To ECEF Position

Robotics / Axes Transformations

Converts a geodetic position – latitude, longitude and altitude above the ellipsoid – into a Cartesian position in the planet-fixed ECEF frame. With e² = f(2−f):

  • N = R / √(1 − e²·sin²φ), the prime vertical radius of curvature
  • ρ = (N + h)·cosφ, the distance from the spin axis
  • z = (N(1 − e²) + h)·sinφ
  • x = ρ·cosλ and y = ρ·sinλ

It is the cheap direction of the pair: four lines of algebra with no iteration, where its inverse ECEF Position To LLA is a root of a quartic.

Ports

  • mu_iota – the geodetic latitude φ and longitude λ stacked as one [2,1], both in DEGREES. The shape is fixed: it is how the Simulink block is drawn, and one point crosses at a time.
  • h – the altitude above the ellipsoid, a scalar in R's length unit.
  • p_ECEF – the position as one [3,1], [x; y; z] in R's length unit. The shape is fixed and does not follow the inputs.

Parameters

  • Flattening – the ellipsoid's flattening f, a dimensionless scalar. Defaults to 0.0033528106647474805, WGS84's 1/298.257223563. Zero gives a sphere. A value of exactly 1 is refused: it is a degenerate ellipsoid with no polar extent and N then divides by zero at the poles.
  • Equatorial Radius – the ellipsoid's equatorial radius R, a scalar. Defaults to WGS84's 6378137 metres, and its unit is the unit h is read in and the output is written in.
  • 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 f and R are baked into the emitted arithmetic at export time rather than published as tunable parameters – an ellipsoid is structural, and e² and N's numerator are folded once by the generator so no target repeats the algebra. Literals are printed at 17 significant digits, so the software targets match the C++ reference to the last bit.

The three hardware targets are simulation-only: they carry the whole computation in floating-point real and quantize only at the port boundary, because a sine, a square root and a division do not belong in a Q16.16 datapath. A fixed-point port also cannot carry an Earth-sized radius – Q16.16 saturates past about 32767 – so a hardware export of this block is for a small custom body or for lengths in a larger unit.

Simulink bridge

Import and export, mapped to Aerospace Blockset's aerolibtransform2/LLA to ECEF Position. 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 a written F or R and discards it, answering for WGS84 regardless. The Simulink block defines no SampleTime, so the rate stays on the ICore side.

Notes

  • Algebraic and stateless: the output depends only on this sample's inputs.
  • Not linear, so the block carries no state space and model reduction correctly reports it as unmergeable.
  • The angles are converted with ×π/180 rather than through a pre-divided slope or a degree-exact sine. MATLAB's own lla2ecef reaches its sines through sind/cosd, which is exact at multiples of 90 and cannot be reproduced by a plain sine; the two agree to about a unit in the last place, which is why this block is held to a 10−12 band rather than to zero.
  • Verified against R2026a: driven end to end through the parity rig, the exported MATLAB core agrees with the Simulink block to well inside that band.

Code facts#

FactValue
registered typeRobotics/Axes_Transformations/LLA_To_ECEF_Position
familyRobotics/Axes_Transformations
solver environment classICoreBlock_0_Robotics_1_Axes_Transformations_2_LLA_To_ECEF_Position
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Axes_Transformations/LLA_To_ECEF_Position/ICoreBlock_0_Robotics_1_Axes_Transformations_2_LLA_To_ECEF_Position.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Axes_Transformations/LLA_To_ECEF_Position/ICoreBlock_0_Robotics_1_Axes_Transformations_2_LLA_To_ECEF_Position.h
default size on canvas150 × 78 px
ports at insert2 in, 1 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDoublemu_iota
2inICoreDoubleh
3outICoreDoublep_ECEF

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 variableDefaultSimulink parameter
FlatteningcFmt(WGS84_F)—
Equatorial RadiuscFmt(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.

supportSupport::Both
Simulink pathaerolibtransform2/LLA to ECEF Position
port-count rulePortsParam::None
SampleTime parameterno — the counterpart defines none; the rate stays on the ICore side
always setptype = Custom, units = Metric (MKS)
ICore configSimulink parameterValue translation
CONFIG_F.c_str()Fpasses through
CONFIG_R.c_str()Rpasses through

Caveat (shown to the user): latitude and longitude cross TOGETHER on one [2,1] port in DEGREES, exactly as the Simulink block is drawn, with the altitude on a port of its own and the position leaving as one [3,1]. 'ptype' is always written as Custom, because a block left on Earth (WGS84) accepts a written F or R and discards it -- measured in R2026a. The Simulink block has no SampleTime, so the rate stays on the ICore side. ⚠ The two sides do not spell the degree conversion the same way -- MATLAB reaches its sines through sind/cosd, which is exact at multiples of 90 -- so they agree to about a unit in the last place rather than bit for bit

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:

  • B0 2 Simulink params rule(s) this tool cannot resolve
  • B0 every stimulus in the sample errored — cross-checks skipped

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).

LLA To ECEF Position -- geodetic coordinates to a Cartesian planet-fixed position N = R / sqrt(1 - e2 * sin(lat)^2) the prime vertical radius of curvature rho = (N + h) * cos(lat) distance from the spin axis z = (N * (1 - e2) + h) * sin(lat) x = rho * cos(lon), y = rho * sin(lon)

Four lines of algebra and no iteration anywhere, which is what makes this the cheap direction of the pair: its inverse, ECEF Position To LLA, is a root of a quartic and has to be solved by repetition.

⚠ THE PORT SHAPES MIRROR THE SIMULINK BLOCK AND ARE FIXED. Latitude and longitude arrive TOGETHER on one [2,1] port in DEGREES -- that is how the Aerospace Blockset block is drawn, and splitting them here would put a port on the ICore side that the bridge could not carry. The altitude has a port of its own, and the position leaves as one [3,1].

⚠ THE ANGLES ARE CONVERTED WITH * PI / 180, NOT WITH A PRE-DIVIDED SLOPE. MATLAB's own lla2ecef reaches its sines through sind/cosd, which is exact at multiples of 90 and therefore not reproducible from a plain sine at all; the two spellings agree to about a unit in the last place, which is why this block is held to the 1e-12 band rather than to zero. Geodetic To Geocentric Latitude measured the same distinction and recorded it -- an algebraically identical spelling is not a numerically identical one.

ALGEBRAIC and STATELESS.

Sample results#

No stimulus produced a sampled output in this rig — Invalid input size at LLA To ECEF Position block: ICore Blocks/Home/LLA To ECEF Position. That is a fact about the single-block rig, not a verdict on the block: an offline batch fit, a block whose output only appears at onSolverFinish, or one that needs a driven environment cannot be exercised alone.

Category unsampled · sample time 0.1 · 60 steps · commit d6e8ad5247e8aa12ff4e80d2fcde8399b98c5f00 · produced by docsSample --out <folder> --blocks LLA_To_ECEF_Position ECEF_Position_To_LLA LLA_To_Flat_Earth Flat_Earth_To_LLA --steps 60

Sample data: docs/generated/samples/Robotics__Axes_Transformations__LLA_To_ECEF_Position.json