Calculate Range — Robotics/Coordinate Transforms
Robotics/Coordinate_Transforms/Calculate_Range · 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.
Calculate Range
Robotics / Coordinate Transforms
The straight-line distance between two positions:
range = |p₂ − p₁| = √((x₂−x₁)² + (y₂−y₁)² + (z₂−z₁)²)
It is the Euclidean distance, in whatever frame and units the two positions are given in – not a great-circle distance, and nothing here knows about a planet.
Ports
- Position 1 – the first position, a [3,1] column.
- Position 2 – the second position, a [3,1] column in the same frame and units.
- Range – the distance, a [1,1] scalar. Never negative, and zero exactly when the two positions coincide.
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: both positions 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, and for one reason
only: there is no square root in a Q16.16 datapath. The three differences and
their squares are genuine fixed point; only the root converts at the port
boundary and evaluates in real. What bounds those targets is the
range rather than the precision – the sum squares the separation, so
two points 180 units apart have already left what a Q16.16 word holds.
Simulink bridge
Import and export, mapped to Aerospace Blockset's
aerolibguid/Calculate Range. 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.
Its library path carries an embedded newline before Range.
Notes
- Algebraic and stateless: the output depends on this sample alone.
- The two inputs are interchangeable. The expression is even in the difference, so swapping the positions changes nothing – which is worth knowing in both directions: a model that has them the wrong way round is not wrong, and no test can catch a swap, because there is nothing to catch. The Simulink block names its output Range (2 to 1); that names the direction of the subtraction, not of the answer.
- Not linear – a root of a sum of squares – so the block carries no state space and model reduction correctly reports it as unmergeable.
- Verified against R2026a: [1 2 3]’ to [4 6 3]’ gives exactly 5, and [0.5 −1.25 2.75]’ to [−3.5 0.25 1]’ gives 4.6165463281548469.
Code facts#
| Fact | Value |
|---|---|
| registered type | Robotics/Coordinate_Transforms/Calculate_Range |
| family | Robotics/Coordinate_Transforms |
| solver environment class | ICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Calculate_Range |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Coordinate_Transforms/Calculate_Range/ICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Calculate_Range.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Coordinate_Transforms/Calculate_Range/ICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Calculate_Range.h |
| default size on canvas | 116 × 72 px |
| ports at insert | 2 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 | Position 1 |
| 2 | in | ICoreDouble | Position 2 |
| 3 | out | ICoreDouble | Range |
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 | aerolibguid/Calculate\nRange |
| 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 list: two [3,1] positions in, one scalar out. The two inputs are interchangeable -- the expression is even in their difference -- so a crossed pair of links is not a defect. The library path carries an embedded newline before 'Range'. 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).
Calculate Range -- the straight-line distance between two positions range = |p2 - p1| = sqrt((x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2)
MEASURED AGAINST R2026a, and the measurement settles the one thing the library name leaves open: this is the EUCLIDEAN distance, not a great-circle one. Between [1 2 3]' and [4 6 3]' aerolibguid/Calculate Range answers exactly 5 -- a 3-4-5 triangle in the plane z = 3, where any spherical formula answers something else -- and between [0.5 -1.25 2.75]' and [-3.5 0.25 1]' it answers 4.6165463281548469, the root of 21.3125 to the last bit.
The Simulink block names its output "Range (2 to 1)". Nothing about the result depends on that direction: the expression is even in the difference, so a model that swaps the two positions is not wrong -- which also means a rig cannot convict a swap, and the description says so rather than implying an ordering that is not there.
⚠ THE THREE HDL TARGETS ARE SIMULATION-ONLY FOR ONE REASON ONLY -- the square root. The three differences and their squares are genuine Q16.16; only the root converts to
real, exactly as Mach Number's does (that block converts for two reasons, the root and a division; there is no division here).
Sample results#
Plotted: vector — Sine Wave, [3,1]: amplitudes 1/2/3 at 2 rad/s (tried only because every scalar stimulus was refused)
Category dynamic · 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__Coordinate_Transforms__Calculate_Range.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).