Generated reference › Order Spectrum — Control Systems/Vibration
kind: generated#block#control-systems-vibration

Order Spectrum — Control Systems/Vibration

Control_Systems/Vibration/Order_Spectrum · 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.

Order Spectrum

Control Systems / Vibration

The order spectrum of a rotating machine – MATLAB's orderspectrum over the frames completed so far. A component of a machine sits at a fixed order of its shaft (a multiple of the rotation rate), so it smears across an ordinary spectrum whenever the speed moves. This block measures the signal against shaft angle instead of time: it interpolates the vibration onto a constant-angle grid using the tachometer, transforms every frame of that grid through a window, and publishes the root-mean-square over the frames so far, order by order.

Ports

  • x – the vibration, a scalar stream.
  • rpm – the shaft speed at the same instant, a scalar stream in revolutions per minute. It is what turns time into angle: the block integrates it (trapezoid by trapezoid) to get shaft revolutions.
  • spec – the order spectrum, a column of nfft/8 + 2 entries, where nfft = max(256, Window Length). Entry m is order m·Omax/(nfft/8), the last one just past Omax = fs/(2·Maximum RPM/60), which is the highest order the sample rate can carry.

Parameters

  • Maximum RPM – the highest shaft speed the run will reach. It sets Omax, the angle grid (8·Omax samples per revolution) and the order axis. ⚠ MATLAB takes this from the record (max(rpm)), which a stream has not seen; the block is orderspectrum exactly when this value is the run's maximum. A speed above 3.75× it is clamped, because past that a fifteenth of a sample would owe more than one angle sample.
  • Sample Rate (Hz) – fs, the rate the two streams arrive at.
  • Window Length – L, the frame length in angle samples, 4 to 1024. It sets the order resolution, ENBW(window)·8·Omax/L. MATLAB's own default resolution picks 967 for a flat top window (385 for Hann, 350 for Hamming, 256 for rectangular) whatever the speed and rate, which is why 967 is this block's default.
  • Window – the taper on each frame: Flat Top (rpmordermap's default, and this block's), Hann, Hamming or Rectangular. Each is divided by its own sum first, as rpmordermap does, so a sinusoid's amplitude is read off directly.
  • Overlap Percent – how much of a frame the next one repeats, 0 to 99; the hop is L − min(ceil(percent·L/100), L−1). 50 is MATLAB's default and this block's.
  • Amplitude – what an entry means.
    • RMS – the root mean square of the frames' magnitudes; orderspectrum's default and this block's.
    • Peak – the same, scaled by √2 so a sinusoid reads its amplitude.
    • Power – the mean of the squared magnitudes, not its root.
  • Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.

What it does per sample

Every input sample is interpolated to 15 points by a 301-tap zero-phase filter – MATLAB's resample(x, 15, 1), which reads 10 samples ahead, so the block runs 10 samples behind the input. The tachometer is interpolated the same way and integrated into revolutions; whenever the shaft passes the next grid angle, one angle sample is interpolated and pushed into the frame. A completed frame is windowed, transformed at nfft and accumulated; the published spectrum is the running root-mean-square, and it holds between frames. Before the first complete frame it is all zeros.

Code export

All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. The 301 interpolation taps and every constant are computed at export time; the windows and the transform's sines and cosines are computed in the emitted core, which keeps the emitted file small whatever the frame length. Every loop has a fixed bound – 15 upsampled points per sample, at most one angle sample each, at most one frame each – so the core's worst case per sample is known at export time. Nothing is a tunable parameter: every setting changes the grid, the window or the accumulators.

The three HDL targets are simulation-only: they carry the arithmetic in real and quantize only at the port boundary. An angular resampler divides by a run-time phase increment and a spectrum spans several decades, neither of which belongs in a Q16.16 datapath. VHDL runs the whole sample in an emitted function over a record of state, because a clocked process has three scratch variables and this needs arrays.

Simulink bridge

No equivalent (Support::None), so nothing crosses in either direction and no parity testbench is owed. orderspectrum and rpmordermap are Signal Processing Toolbox functions, that toolbox ships no Simulink library, and no library block resamples a signal onto shaft angle. Code export verification still covers the block across all ten languages.

Notes

  • Stateful and inherently discrete (setDiscreteOnlyBlock(true)): an input delay line, a tachometer delay line, the phase, the angle-domain frame and one accumulator per order, all advancing once per sample. Its period comes from its own "Sampling Time (s)", or the model's global sampling time when that is zero or less.
  • It runs 10 samples behind, because the interpolation reads that far ahead. That is resample's own filter, not an approximation of it.
  • Three departures from the batch function, all of them stated above: Maximum RPM is a parameter rather than the record's maximum; the answer is the spectrum of the frames completed so far, so it is a running estimate rather than one answer at the end; and the frames MATLAB builds out of a record's last ten samples – where its own resampling pads with zeros – are frames a stream never reaches. Measured on a 600-sample run-up (1200 to 3000 rpm, fs = 1000): every frame's order map agrees with rpmordermap to 1.0×10−14, the running spectrum over the same frames to 1.1×10−15, and the whole-record answers differ by 0.38–0.60 % where the stream is 1 to 5 frames short of MATLAB's count – and by 1.1×10−15 where it is not.
  • ⚠ "Maximum RPM" is not a formality. On that same run – whose speed peaks at 2942.6 rpm – setting the parameter to a round 3000 instead moved the answer by 3.5 % to 24 %, because it is what sets the angle grid and the order axis. Give it the run's maximum, not a nameplate figure.
  • An order spectrum needs a run-up: at a constant speed it is a frequency spectrum with a relabelled axis. It is the speed CHANGING that separates a shaft-order component from a fixed-frequency one.
  • No state space. An angular resampler followed by a magnitude spectrum is not linear.
  • Related blocks. Vibration / Time-Synchronous Average sharpens what is synchronous with the shaft in the time domain and makes the same substitution for the period; Spectral Measurements / Welch PSD is the fixed-frequency counterpart of this measurement.

Code facts#

FactValue
registered typeControl_Systems/Vibration/Order_Spectrum
familyControl_Systems/Vibration
solver environment classICoreBlock_0_Control_Systems_1_Vibration_2_Order_Spectrum
sourcesrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Vibration/Order_Spectrum/ICoreBlock_0_Control_Systems_1_Vibration_2_Order_Spectrum.cpp
headersrc/ICoreBlocks/ICoreBlockLibrary/Blocks/Control_Systems/Vibration/Order_Spectrum/ICoreBlock_0_Control_Systems_1_Vibration_2_Order_Spectrum.h
default size on canvas150 × 86 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
1inICoreDoublex
2inICoreDoublerpm
3outICoreDoublespec

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 variableDefaultSimulink parameter
Maximum RPM3000—
Sample Rate (Hz)1000—
Window Length967—
WindowFlat Top%~%Hann%~%Hamming%~%Rectangular~~Flat Top—
Overlap Percent50—
AmplitudeRMS%~%Peak%~%Power~~RMS—

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::None
Simulink path—
port-count rulePortsParam::None
SampleTime parameteryes

Caveat (shown to the user): no Simulink equivalent. orderspectrum and rpmordermap are Signal Processing Toolbox MATLAB functions, not blocks; that toolbox ships no Simulink library, and no library block resamples a signal onto shaft angle from a tachometer

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

Order Spectrum -- MATLAB's orderspectrum(rpmordermap(x, fs, rpm, ...)) as a streaming block A component of a rotating machine sits at a fixed ORDER of the shaft -- a multiple of its rotation rate -- and therefore SMEARS across a frequency spectrum whenever the speed moves. The order spectrum removes that by measuring the signal against SHAFT ANGLE instead of time:

Omax = fs / (2 . maxrpm/60) the highest order the sample rate can carry fsp = 4 . (2 . Omax) samples per revolution of the angle grid xu = resample(x, 15, 1) a 301-tap zero-phase interpolation, 10 samples of lookahead -- the block's only latency phase = cumtrapz(rpmUp / (60 . 15 . fs)) revolutions, trapezoid by trapezoid xp(k) = interp1(phase, xu, k/fsp) the signal on a CONSTANT-ANGLE grid frame j = xp(j.hop .. j.hop+L-1), windowed, transformed at nfft = max(256, L) map(m, j) = |X| . (sqrt2 on every bin but DC and Nyquist) . (sqrt2 again for 'peak') spectrum(m) = sqrt( mean_j map(m, j)^2 ) 'power': mean_j map(m, j)

and the orders kept are those at most Omax, plus one, which is nfft/8 + 2 of them.

⚠ EVERY LINE OF THAT WAS READ OUT OF R2026a's OWN SOURCES AND THEN MEASURED AGAINST THEM. orderspectrum.m calls rpmordermap, which is private/rpmmap.m: toConstantSamplesPerCycle does the 15x resample, the linear interpolation of the tachometer, the cumulative trapezoid and the constant-angle interp1; the window is normalised by its own sum; nOverlap is ceil(op/100 . L) capped at L-1; nfft is max(256, length(win)); and the amplitude scaling is rpmmap's mapAmplitudeScale. A Python transcription of the statements below -- the block's own filter taps, windows, per-frame twiddles and accumulators -- was run against a 600-sample run-up (1200 to 3000 rpm with a wobble, fs = 1000) in four configurations:

hann L 64 rms 51 frames map worst 5.4e-15 running spectrum vs MATLAB's own flattop L 967 rms 2 frames map worst 1.5e-15 map over the SAME frames: 2.2e-16, hamming L 40 peak 82 frames map worst 1.0e-14 1.1e-15, 2.2e-16, 5.6e-16 rectwin L 32 power 206 frames map worst 8.0e-15

⚠ THE ONE PLACE A STREAM CANNOT BE THE BATCH FUNCTION IS THE END OF THE RECORD, and it is measured rather than waved at. resample reads ten input samples PAST the sample it is interpolating, so the stream runs ten samples behind and the frames MATLAB builds out of a record's last ten samples (where its own resample pads with zeros) are frames this block has not reached. Over the run above that is 1 to 5 frames of 52, 84 and 211, and the whole-record answers differ by 0.38 % to 0.60 %; where the stream does reach the last frame -- the flattop case, 2 frames of 2 -- the two agree to 1.1e-15. Against MATLAB's own map over the frames the block HAS completed, the agreement is 1e-15 in every configuration.

Sample results#

Order Spectrum — Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sampleOrder Spectrum — 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-0out ICoreDouble-Out-0 [122x1] entry 0
tin ICoreDouble-Out-0in ICoreDouble-Out-0out ICoreDouble-Out-0 [122x1] entry 0
0-2-2[0, 0, 0, 0]…
0.40.50.5[0, 0, 0, 0]…
0.8-2-2[0, 0, 0, 0]…
1.20.50.5[0, 0, 0, 0]…
1.6-2-2[0, 0, 0, 0]…
20.50.5[0, 0, 0, 0]…
2.4-2-2[0, 0, 0, 0]…
2.80.50.5[0, 0, 0, 0]…
3.2-2-2[0, 0, 0, 0]…
3.60.50.5[0, 0, 0, 0]…
4-2-2[0, 0, 0, 0]…
4.40.50.5[0, 0, 0, 0]…
4.8-2-2[0, 0, 0, 0]…
5.20.50.5[0, 0, 0, 0]…

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
rampRamp: slope 1 from t = 00 … 0
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias0 … 0
stepStep: 0 -> 1 at t = 1 s0 … 0

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 23d8841c6561ca4bb64cd9b5b64da9638de12629 · produced by docsSample --out <folder> --blocks Fixed_Wing_Point_Mass Kernel_Classifier_Predictor Kernel_Regression_Predictor Rotor Rotor_With_Flap_Effects Multirotor Multirotor_With_Flap_Effects Dynamic_Inflow_3_State Kurtogram Empirical_Mode_Decomposition Modal_FRF Order_Spectrum --steps 60 · data docs/generated/samples/Control_Systems__Vibration__Order_Spectrum.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).