Symmetric Inertia Tensor — Robotics/Mass Properties
Robotics/Mass_Properties/Symmetric_Inertia_Tensor · 6 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.
Symmetric Inertia Tensor
Robotics / Mass Properties
Assembles the 3×3 inertia matrix from its six independent entries, negating the products of inertia on the way:
I = [ Ixx -Ixy -Ixz ; -Ixy Iyy -Iyz ; -Ixz -Iyz Izz ]
The result is symmetric by construction, so a body's inertia can be given as six numbers rather than nine.
Ports
- Ixx, Iyy, Izz – the three moments of inertia, each a [1,1] scalar. They land on the diagonal unchanged.
- Ixy, Ixz, Iyz – the three products of inertia, each a [1,1] scalar. Each is negated and placed in both of its symmetric positions.
- I – the tensor, a [3,3] matrix. Its size follows nothing: it is always three by three.
The port order is Ixx, Ixy, Ixz, Iyy, Iyz, Izz – the same order the Simulink block uses, and not the three moments followed by the three products. Wiring it that way gives a tensor that is symmetric, plausible and wrong in five of its nine entries.
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 six 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 genuinely synthesizable, which is
unusual in this family: there is no arithmetic here at all – six copies and
six negations – so nothing leaves the fixed-point datapath, nothing can
overflow that the inputs did not already, and no value is converted to
real.
Simulink bridge
Import and export, mapped to Aerospace Blockset's
aerolibbdyn/Symmetric Inertia Tensor. That block has no dialog
parameters at all – measured in R2026a – so nothing is mapped and
the add_block carrying nothing is itself the assertion. It defines
no SampleTime either, so the rate stays on the ICore side.
Notes
- Algebraic and stateless: the output depends on this sample alone.
- Enter the products of inertia POSITIVE. The block negates them itself. Hand it values that have already been negated and the off-diagonal signs come out inverted, with nothing to report – six scalars are six scalars, and no block can tell which convention produced them.
- Linear, but not given a state space: the output is a matrix rather than a signal an A/B/C/D set could carry, so model reduction correctly reports it as unmergeable.
- Verified against R2026a: fed (12, 15, 18, 1.5, −2.5, 3.5) in
port order, both this block and the Simulink one answer
[12 -15 -18 ; -15 1.5 2.5 ; -18 2.5 3.5]– note the −2.5 coming back as +2.5.
Code facts#
| Fact | Value |
|---|---|
| registered type | Robotics/Mass_Properties/Symmetric_Inertia_Tensor |
| family | Robotics/Mass_Properties |
| solver environment class | ICoreBlock_0_Robotics_1_Mass_Properties_2_Symmetric_Inertia_Tensor |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Mass_Properties/Symmetric_Inertia_Tensor/ICoreBlock_0_Robotics_1_Mass_Properties_2_Symmetric_Inertia_Tensor.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Mass_Properties/Symmetric_Inertia_Tensor/ICoreBlock_0_Robotics_1_Mass_Properties_2_Symmetric_Inertia_Tensor.h |
| default size on canvas | 118 × 132 px |
| ports at insert | 6 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 | Ixx |
| 2 | in | ICoreDouble | Ixy |
| 3 | in | ICoreDouble | Ixz |
| 4 | in | ICoreDouble | Iyy |
| 5 | in | ICoreDouble | Iyz |
| 6 | in | ICoreDouble | Izz |
| 7 | out | ICoreDouble | I |
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 | aerolibbdyn/Symmetric Inertia Tensor |
| port-count rule | PortsParam::None |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
Caveat (shown to the user): the Simulink block carries no dialog parameters and no SampleTime, so the whole mapping is the library path and the PORT ORDER -- which is Ixx, Ixy, Ixz, Iyy, Iyz, Izz on both sides, read off the Simulink block's own inner Inport names and NOT the three moments followed by the three products. The products of inertia are entered positive and negated by the block, on both sides. 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).
Symmetric Inertia Tensor -- six scalars to a 3x3 I = [ Ixx -Ixy -Ixz ; -Ixy Iyy -Iyz ; -Ixz -Iyz Izz ]
MEASURED AGAINST R2026a, and both halves of the measurement are load-bearing.
THE PORT ORDER IS Ixx, Ixy, Ixz, Iyy, Iyz, Izz -- read off the Simulink block's own inner Inport names, and it is NOT the diagonal-first order the block's name suggests. A rig or a user wiring the three diagonal terms first gets a tensor that is symmetric, plausible, and wrong in five of its nine entries.
AND EVERY OFF-DIAGONAL ENTRY IS NEGATED. Fed (12, 15, 18, 1.5, -2.5, 3.5) in port order, aerolibbdyn/Symmetric Inertia Tensor answers
[ 12 -15 -18 ; -15 1.5 2.5 ; -18 2.5 3.5 ]
-- note the Iyz of -2.5 coming out as +2.5, which is what settles that the sign is applied unconditionally rather than being part of the expected input.
⚠ SO THE PRODUCTS OF INERTIA ARE ENTERED POSITIVE. Hand this block values that have already been negated and the off-diagonal signs come out inverted, with nothing to report: six scalars are six scalars and the block cannot tell which convention produced them. The description says so where a user reads it.
This is the only block in this family whose HDL export is genuinely SYNTHESIZABLE: there is no arithmetic here at all, only six copies and six negations, so nothing leaves Q16.16.
Sample results#
| t | in ICoreDouble-Out-0 | in ICoreDouble-Out-0 | in ICoreDouble-Out-0 | out ICoreDouble-Out-0 [3x3] entry 0 |
|---|---|---|---|---|
| 0 | -2 | -2 | -2 | [-2, 2, 2, 2]… |
| 0.4 | 0.5 | 0.5 | 0.5 | [0.5, -0.5, -0.5, -0.5]… |
| 0.8 | -2 | -2 | -2 | [-2, 2, 2, 2]… |
| 1.2 | 0.5 | 0.5 | 0.5 | [0.5, -0.5, -0.5, -0.5]… |
| 1.6 | -2 | -2 | -2 | [-2, 2, 2, 2]… |
| 2 | 0.5 | 0.5 | 0.5 | [0.5, -0.5, -0.5, -0.5]… |
| 2.4 | -2 | -2 | -2 | [-2, 2, 2, 2]… |
| 2.8 | 0.5 | 0.5 | 0.5 | [0.5, -0.5, -0.5, -0.5]… |
| 3.2 | -2 | -2 | -2 | [-2, 2, 2, 2]… |
| 3.6 | 0.5 | 0.5 | 0.5 | [0.5, -0.5, -0.5, -0.5]… |
| 4 | -2 | -2 | -2 | [-2, 2, 2, 2]… |
| 4.4 | 0.5 | 0.5 | 0.5 | [0.5, -0.5, -0.5, -0.5]… |
| 4.8 | -2 | -2 | -2 | [-2, 2, 2, 2]… |
| 5.2 | 0.5 | 0.5 | 0.5 | [0.5, -0.5, -0.5, -0.5]… |
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 … 1 |
ramp | Ramp: slope 1 from t = 0 | 0 … 5.9 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | -1 … 0.9996 |
step | Step: 0 -> 1 at t = 1 s | 0 … 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 3c100aff6f27235305db4ad4d572f32e342718ad · produced by docsSample --out <folder> --blocks Calculate_Range Moments_About_CG_Due_To_Forces Symmetric_Inertia_Tensor --steps 60 · data docs/generated/samples/Robotics__Mass_Properties__Symmetric_Inertia_Tensor.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).