Generated reference › Time Delay Estimator — System Identification/Correlation
kind: generated#block#system-identification-correlation

Time Delay Estimator — System Identification/Correlation

System_Identification/Correlation/Time_Delay_Estimator · 2 input / 2 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.

Time Delay Estimator

System Identification / Correlation

Estimates the transport delay between two signals by running cross-correlation. Each step it correlates the current y against every recent sample of uR[i] ← λ·R[i] + y[k]·u[k−i] for each lag i from 0 to the maximum – and reports the lag whose correlation is largest in magnitude. For y = g·u[k−d] that lag is d.

Ports

  • u – the reference signal, scalar. It is what fills the history, so every lag is this one signal delayed.
  • y – the delayed signal, scalar. What u is being correlated against.
  • delay – the estimated delay in SAMPLES, scalar, always a whole number in [0, Maximum Lag]. Multiply by the sampling time for seconds.
  • peak – the SIGNED correlation at that lag, scalar. Its sign is the sign of the plant gain; its magnitude is what the search ranked by.

Parameters

  • Maximum Lag (samples) – the largest delay the block can report, a whole number of 0 or more. The search covers every lag from 0 to this value inclusive, so a delay beyond it is reported as whichever lag inside the window happens to correlate best – size it above the delay you expect.
  • Forgetting Factor – λ, how fast old products are discounted, in (0,1]. Values just below 1 (0.9–0.99) track a delay that changes; 1 makes the correlations plain growing sums, which never settle and drift without bound, so it is offered but not recommended.
  • Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.

Notes

  • Ties go to the LOWEST lag. The search scans upward and replaces the best only on a strictly greater magnitude, so when two lags tie the smaller one wins. This is the same convention as Machine Learning / Preprocessing / Argmax Decision, and it is spelled identically in all ten export targets.
  • The search ranks by magnitude, the output carries the sign. A plant with negative gain correlates most strongly negatively, so ranking by the signed value would report the wrong lag for it entirely. Ranking by |R| fixes that, and the signed value still leaves on the peak port.
  • The peak is a RAW correlation, not a normalized coefficient. It is comparable between lags of the same run, but not between runs at different signal levels – it scales with the amplitudes of u and y. Normalizing it would take a square root and a division per sample, which would make the HDL exports simulation-only; that trade was made in favour of synthesizable hardware. Divide it downstream if an absolute confidence is wanted.
  • Stateful and discrete only. The state is the u history and the correlations. There is no warm-up: the history starts at zeros, which is exactly u[k] = 0 for k < 0, and an all-zero correlation set reports lag 0 by the tie rule above. The estimate is meaningless until enough data has accumulated, which is a property of the statistic rather than a state the block guards.
  • No state space, deliberately. Correlating two signals multiplies two things that both move, and the argmax is a discontinuous selection, so no A/B/C/D is true of it. Model reduction reports the block as unmergeable, which is the honest answer.
  • This is the natural pre-step to any identification with unknown dead time, and the calibration measurement for the two transport-delay blocks.

Code export

All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. The maximum lag and λ are fixed at export time, so every array bound is a compile-time constant.

The three HDL targets are genuinely synthesizable Q16.16 – the recursion is multiply-accumulate and the search is a comparison chain, with no division anywhere. One caveat inherited from Argmax Decision: two lags whose correlations sit within a fixed-point quantum of each other can rank the other way round in hardware, and because the output is an index that moves the answer by a whole sample rather than by a small amount. It matters only when two lags are genuinely tied, which for a real delay in a well-excited signal they are not.

Simulink bridge

Neither direction. The System Identification Toolbox is not installed on this machine, so a bridge could not be verified against the real block even if it were written; the bridge reports this block with that reason rather than silently dropping it.

Code facts#

FactValue
registered typeSystem_Identification/Correlation/Time_Delay_Estimator
familySystem_Identification/Correlation
solver environment classICoreBlock_0_System_Identification_1_Correlation_2_Time_Delay_Estimator
sourcesrc/ICoreSDK/ICoreBlockLibrary/Blocks/System_Identification/Correlation/Time_Delay_Estimator/ICoreBlock_0_System_Identification_1_Correlation_2_Time_Delay_Estimator.cpp
headersrc/ICoreSDK/ICoreBlockLibrary/Blocks/System_Identification/Correlation/Time_Delay_Estimator/ICoreBlock_0_System_Identification_1_Correlation_2_Time_Delay_Estimator.h
default size on canvas100 × 70 px
ports at insert2 in, 2 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDouble
2inICoreDouble
3outICoreDouble
4outICoreDouble

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 Lag (samples)8
Forgetting Factor0.98

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): the System Identification Toolbox is not installed on this machine, so a bridge could not be verified against the real block even if it were written

Catalog contract: src/ICoreSDK/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.

Sample results#

Time Delay Estimator — Step: 0 -> 1 at t = 1 sTime Delay Estimator — Step: 0 -> 1 at t = 1 s0102030012345t (s)in ICoreDouble-Out-0in ICoreDouble-Out-0out ICoreDouble-Out-0out ICoreDouble-Out-1

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
tableRepeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample0 … 0

Plotted: step — Step: 0 -> 1 at t = 1 s

Category dynamic · sample time 0.1 · 60 steps · commit ccf005c8 · produced by docsSample --out <folder> --steps 60 · data docs/generated/samples/System_Identification__Correlation__Time_Delay_Estimator.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).