Generated reference › Spherical To Cartesian — Robotics/Coordinate Transforms
kind: generated#block#robotics-coordinate-transforms

Spherical To Cartesian — Robotics/Coordinate Transforms

Robotics/Coordinate_Transforms/Spherical_To_Cartesian · 3 input / 3 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 To Cartesian

Robotics / Coordinate Transforms

Converts a spherical triple to Cartesian form, entry by entry:

x = r·sin φ·cos θ, y = r·sin φ·sin θ, z = r·cos φ

θ is the azimuth and φ the inclination measured from the +Z axis – the same convention its inverse, Cartesian To Spherical, produces.

Ports

  • r – the radius, any size [m,n]. It may be negative – see Notes.
  • theta – the azimuth in radians. Same size as r.
  • phi – the inclination from +Z in radians. Same size as r. φ = 0 points along +Z; φ = π/2 lies in the XY plane.
  • x, y, z – the Cartesian components, the same size as the inputs.

Parameters

  • 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. There is no tunable parameter.

The three HDL targets are simulation-only: a sine and a cosine have no Q16.16 form to call. Every backend needs only multiplies and those two functions, which each of the ten has by name – including PLC Structured Text. Nothing is guarded, because nothing here has a restricted domain.

Simulink bridge

Both directions, onto simulink_extras/Transformations/Spherical to Cartesian. That block has no dialog parameters whatsoever (verified with get_param(blk, 'DialogParameters'), which comes back empty), so the bridge is the library path alone. It also has no SampleTime parameter, so Sampling Time (s) does not cross.

Notes

  • Algebraic and stateless; nonlinear, and deliberately carries no state space.
  • A negative radius is passed through the formula, not corrected, and θ and φ are not wrapped – both measured against the Simulink block. Angles far outside their canonical ranges are fine, since sine and cosine are periodic. That is what lets this block take the raw angles that poses and headings carry in this library.
  • Round-tripping is exact but not an identity in general. Feeding the outputs back through Cartesian To Spherical returns the same point in canonical form – r ≥ 0, θ in (−π, π], φ in [0, π]. Measured at 4.4e-16.

Code facts#

FactValue
registered typeRobotics/Coordinate_Transforms/Spherical_To_Cartesian
familyRobotics/Coordinate_Transforms
solver environment classICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Spherical_To_Cartesian
sourcesrc/ICoreSDK/ICoreBlockLibrary/Blocks/Robotics/Coordinate_Transforms/Spherical_To_Cartesian/ICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Spherical_To_Cartesian.cpp
headersrc/ICoreSDK/ICoreBlockLibrary/Blocks/Robotics/Coordinate_Transforms/Spherical_To_Cartesian/ICoreBlock_0_Robotics_1_Coordinate_Transforms_2_Spherical_To_Cartesian.h
default size on canvas132 × 96 px
ports at insert3 in, 3 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDoubler
2inICoreDoubletheta
3inICoreDoublephi
4outICoreDoublex
5outICoreDoubley
6outICoreDoublez

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 pathsimulink_extras/Transformations/Spherical to Cartesian
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 has no dialog parameters at all, so nothing but the block itself crosses; it also defines no SampleTime, so "Sampling Time (s)" does not cross and the block runs at the surrounding Simulink rate

Catalog contract: src/ICoreSDK/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 Ports lists 4 entries for 6 ports (3 in, 3 out) — grouped, or one undocumented? a reader must say

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 To Cartesian — the 3-D transform, elementwise x = r * sin(phi) * cos(theta) y = r * sin(phi) * sin(theta) z = r * cos(phi)

theta is the AZIMUTH, phi the INCLINATION FROM +Z -- the convention measured off its inverse. Verified with an INDEPENDENT polar probe (max err 0.000e+00 on all three components) as well as by round-tripping through Cartesian_To_Spherical (4.4e-16): the round trip alone would only have proved the pair mutually consistent.

⚠ TOTAL, so no guards anywhere: a negative r is applied as written rather than canonicalized, and theta/phi outside their canonical ranges are neither wrapped nor clamped -- both measured. PLC ST needs no reconstruction either, having SIN and COS.

Sample results#

Spherical To Cartesian — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sampleSpherical To Cartesian — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample-202012345t (s)in ICoreDouble-Out-0in ICoreDouble-Out-0in ICoreDouble-Out-0out ICoreDouble-Out-0out ICoreDouble-Out-1out ICoreDouble-Out-2
tin ICoreDouble-Out-0in ICoreDouble-Out-0in ICoreDouble-Out-0out ICoreDouble-Out-0out ICoreDouble-Out-1out ICoreDouble-Out-2
0-2-2-2-0.7568-1.6540.8323
0.40.50.50.50.21040.11490.4388
0.8-2-2-2-0.7568-1.6540.8323
1.20.50.50.50.21040.11490.4388
1.6-2-2-2-0.7568-1.6540.8323
20.50.50.50.21040.11490.4388
2.4-2-2-2-0.7568-1.6540.8323
2.80.50.50.50.21040.11490.4388
3.2-2-2-2-0.7568-1.6540.8323
3.60.50.50.50.21040.11490.4388
4-2-2-2-0.7568-1.6540.8323
4.40.50.50.50.21040.11490.4388
4.8-2-2-2-0.7568-1.6540.8323
5.20.50.50.50.21040.11490.4388

Every 4th of 60 samples, from the table stimulus.

The same rig also ran:

StimulusWhat it isOutput range
impulseImpulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair)0 … 0.4546
rampRamp: slope 1 from t = 0-2.75 … 1.979
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias0 … 0.4546
stepStep: 0 -> 1 at t = 1 s0 … 0.4546

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 ccf005c8 · produced by docsSample --out <folder> --steps 60 · data docs/generated/samples/Robotics__Coordinate_Transforms__Spherical_To_Cartesian.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).