Spherical Harmonic Gravity Model — Robotics/Gravity Models
Robotics/Gravity_Models/Spherical_Harmonic_Gravity_Model · 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.
Spherical Harmonic Gravity Model
Robotics / Gravity Models
Computes the gravitational acceleration at a position in the planet-fixed frame from a full spherical harmonic model of the planet's gravity field, to a chosen degree and order N:
U = GM/r · [1 + Σn=2..N (Re/r)n Σm=0..n P̄nm(sin φ) (C̄nm cos mλ + S̄nm sin mλ)], g = ∇U
with r the distance from the planet's centre, φ the geocentric latitude, λ the longitude and P̄nm the fully normalized associated Legendre functions. Unlike a zonal model, the tesseral and sectoral terms (m > 0) carry how the field varies with longitude.
It is the Aerospace Blockset's Spherical Harmonic Gravity Model and
MATLAB's gravitysphericalharmonic, with the same coefficient files:
EGM2008 (the default), EGM96 and EIGEN-GL04C for the Earth,
LP100K and LP165P for the Moon, GMM-2B for Mars, or
Custom coefficients of your own. It includes only gravitation: add the
Centrifugal Effect Model for the planet's rotation.
Ports
- Xecef – the position [3,1], [x; y; z] in the planet-fixed frame: metres, or feet in English units.
- g_ecef – the gravitational acceleration [3,1] in the same frame: m/s², or ft/s² in English units.
Parameters
- Units – Metric (MKS) or English. English converts the model's Re and GM to feet exactly as the Simulink block does.
- Degree – N, a whole number from 2 to 60: the degree and order the sum runs to. Default 60.
- Planet Model – EGM2008, EGM96, LP100K, LP165P, GMM2B, EIGENGL04C or Custom.
- Custom GM – the gravitational parameter (m³/s²), used only by Custom.
- Custom Re – the reference radius (m), used only by Custom.
- Custom C – the normalized cosine coefficients, used only by Custom: a square matrix of at least (N+1)×(N+1) whose entry (n+1, m+1) is degree n, order m – the layout of the Simulink block's data files.
- Custom S – the normalized sine coefficients, the same shape.
- 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. Each prints the same description of the calculation that the simulation itself runs, so every target does the same arithmetic in the same order. The coefficients up to the chosen degree are baked in as constants, which is why the degree is capped.
⚠ The three HDL targets run in simulation-only real arithmetic, quantizing only at the port boundaries – which bounds every port to about ±32767. A planet's radius in metres is far above that, so an HDL core carries a real planet only after the position has been rescaled (a Custom model in other units does this).
Simulink bridge
Import and export, mapped to aerolibgravity2/Spherical Harmonic Gravity
Model. Units maps to units, Degree to
degree, and the six named planet models to ptype;
action is written as None, because this block never warns.
Custom does not cross: Simulink reads custom coefficients from a data file
through a reader function, which a model cannot carry, so a Custom block is
exported with the model left at Simulink's default and the exchange report says
so. A Simulink block above degree 60 cannot be imported.
Notes
- Stateless: the output depends only on the position at that step.
- The geographic poles are handled exactly as in Simulink: there gx and gy are exactly zero.
- ⚠ At exactly the south pole the Simulink block answers NaN; this
block, like MATLAB's
gravitysphericalharmonic, answers the finite value. - Below the reference radius the series is outside its region of convergence; the block computes it anyway, as Simulink does with its action set to None.
Code facts#
| Fact | Value |
|---|---|
| registered type | Robotics/Gravity_Models/Spherical_Harmonic_Gravity_Model |
| family | Robotics/Gravity_Models |
| solver environment class | ICoreBlock_0_Robotics_1_Gravity_Models_2_Spherical_Harmonic_Gravity_Model |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Gravity_Models/Spherical_Harmonic_Gravity_Model/ICoreBlock_0_Robotics_1_Gravity_Models_2_Spherical_Harmonic_Gravity_Model.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Gravity_Models/Spherical_Harmonic_Gravity_Model/ICoreBlock_0_Robotics_1_Gravity_Models_2_Spherical_Harmonic_Gravity_Model.h |
| default size on canvas | 170 × 80 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 | Xecef |
| 2 | out | ICoreDouble | g_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 variable | Default | Simulink parameter |
|---|---|---|
Units | Metric (MKS)%~%English~~Metric (MKS) | units |
Degree | 60 | degree |
Planet Model | modelsCustom~~MODEL_NAMES[0] | ptype |
Custom GM | 398600441800000 | not crossed |
Custom Re | 6378137 | not crossed |
Custom C | 0 0 0; 0 0 0; -0.00048416514379081503 -2.066155090741759… | not crossed |
Custom S | [0 0 0; 0 0 0; 0 1.3844138913797899e-09 -1.40027370385934… | not crossed |
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 | aerolibgravity2/Spherical Harmonic Gravity Model |
| port-count rule | PortsParam::None |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| deliberately not crossed | Custom GM, Custom Re, Custom C, Custom S |
| always set | action = None |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
Units | units | Metric (MKS) → Metric (MKS), English → English |
Planet Model | ptype | EGM2008 → EGM2008, EGM96 → EGM96, LP100K → LP100K, LP165P → LP165P, GMM2B → GMM2B, EIGENGL04C → EIGENGL04C |
Degree | degree | passes through |
Caveat (shown to the user): the six named planet models, the degree and the units cross 1:1. Custom does not: Simulink reads custom coefficients from a data file through a reader function, which a model cannot carry, so a Custom block exports with ptype left at Simulink's default and is reported. 'action' is written as None because this block never warns. The degree is capped at 60 here, below Simulink's limits, because every export bakes the coefficient table in as constants. The Simulink block has no SampleTime
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:
B0no sample under docs/generated/samples/ — nothing to cross-check (P8.1)
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).
Spherical Harmonic Gravity Model -- EGM/LP/GMM spherical-harmonic gravity to degree N <= 60 g = grad U at a planet-fixed position, U the fully normalized expansion to degree and order N. The arithmetic is ICoreSphericalHarmonicGravitySupport's -- the block's own reference C (saeroshgravity.c) and the subsystem it sat in -- written once for the live run and once as statements for the ten exports; this file holds the configuration, the port and the bridge.
⚠ MEASURED AGAINST R2026a, 2100 random positions (1.001 to 11 radii, poles and axes included) over all six named models, degrees 2 to 60, both unit systems:
against the Simulink block at most 3.0e-16 relative, 65-76 % of rows bit-identical against gravitysphericalharmonic at most 1.0e-15 relative
and the emitted Python is bit-identical to the live run on all 2100. ⚠ At exactly the SOUTH pole (x = y = 0, z < 0) the Simulink block answers NaN on all three axes; the MATLAB function and this block give the finite value, and the north pole agrees with both.
Sample results#
No sample run is committed for this block. Samples come from the headless harness (DOCS_PLAN.md P8.1) into docs/generated/samples/; until one exists this block's behaviour is witnessed by the parity and export-verification suites, not by a plot here.