Generated reference › Calculate Range — Robotics/Coordinate Transforms
kind: generated#block#robotics-coordinate-transforms

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#

FactValue
registered typeRobotics/Coordinate_Transforms/Calculate_Range
familyRobotics/Coordinate_Transforms
solver environment classICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Calculate_Range
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Coordinate_Transforms/Calculate_Range/ICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Calculate_Range.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Coordinate_Transforms/Calculate_Range/ICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Calculate_Range.h
default size on canvas116 × 72 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
1inICoreDoublePosition 1
2inICoreDoublePosition 2
3outICoreDoubleRange

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.

supportSupport::Both
Simulink pathaerolibguid/Calculate\nRange
port-count rulePortsParam::None
SampleTime parameterno — 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#

Calculate Range — Sine Wave, [3,1]: amplitudes 1/2/3 at 2 rad/s (tried only because every scalar stimulus was refused)Calculate Range — Sine Wave, [3,1]: amplitudes 1/2/3 at 2 rad/s (tried only because every scalar stimulus was refused)-1-0.500.51012345t (s)in ICoreDouble-Out-0 [3x1] entry 0in ICoreDouble-Out-0 [3x1] entry 0out ICoreDouble-Out-0

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