Generated reference › Watchdog Timer — Robotics/Safety Supervision
kind: generated#block#robotics-safety-supervision

Watchdog Timer — Robotics/Safety Supervision

Robotics/Safety_Supervision/Watchdog_Timer · 1 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.

Watchdog Timer

Robotics / Safety Supervision

Reports a signal that has stopped moving. With frozen = ( |u[k] − u[k−1]| ≤ Freeze Tolerance ), the block counts consecutive frozen samples – count ← frozen ? min(count + 1, Stuck Samples) : 0 – and drives ok to 0 once that run reaches Stuck Samples.

A dead sensor rarely reports an impossible number: a frozen encoder, a CAN frame repeating its last payload and an unplugged input all hold a perfectly plausible value. Checking the LEVEL cannot see any of them, which is what this block adds to the Model Verification family.

Ports

  • u – the monitored signal, a scalar [1,1]: a wheel speed, a joint angle, a pressure, a battery voltage. To watch several, use one block per signal – the run length is per signal and cannot be shared.
  • ok – a scalar [1,1]: 1 while the signal is considered live, 0 once it has been frozen for Stuck Samples consecutive samples. Ready to drive an enable, a switch or an Assertion.
  • count – a scalar [1,1]: how many consecutive samples the input has been frozen for, saturating at Stuck Samples. Useful as a health margin – it climbs before ok falls.

Parameters

  • Freeze Tolerance – a scalar ≥ 0: how much movement between consecutive samples still counts as frozen. Size it above the signal's quantization step (an encoder's LSB, an ADC count) and below its smallest real motion; at exactly 0 only a bit-identical repeat counts, which a noisy analogue input will never produce.
  • Stuck Samples – a whole number ≥ 1: how many consecutive frozen samples raise the alarm. It is a count, not a time – at a 10 ms rate 50 samples is half a second.
  • Initial Input – a scalar: the value that stands in for u[−1], since the first sample has no predecessor. It decides only whether the run starts at 0 or 1.
  • 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. Every parameter is baked into the body at export time; there is no tunable parameter object.

The three HDL targets are genuine synthesizable Q16.16: one subtraction, one absolute value, two comparisons and an increment, with no division and nothing transcendental. The counter is carried as a fixed-point whole number and compared against one, so it never has to be converted out of fixed point.

Simulink bridge

None. Nothing in the installed libraries latches on signal staleness: the Model Verification blocks assert on a value against a bound, and Detect Change reports the single sample on which a signal differs from its previous one rather than accumulating a run of samples on which it did not. The watchdog blocks that do exist ship in toolboxes this machine does not carry. The bridge entry therefore reports the block with that reason instead of dropping it silently, and no parity testbench is owed – the documented consequence of Support::None. Code export verification still covers all ten languages.

Notes

  • Stateful and inherently discrete (setDiscreteOnlyBlock(true)): "the previous sample" only means anything per sample, and there is no derivative to integrate.
  • It does not latch. ok returns to 1 on the first sample that moves, because a watchdog reports current health. To hold a fault until an operator clears it, feed ok into Emergency Stop Ramp, whose latch is exactly that; for a hard stop, feed it into Assertion.
  • The counter saturates at Stuck Samples rather than running free – nothing downstream needs a larger number, and an unbounded counter would leave the fixed-point range on the HDL targets after a few minutes of a genuinely dead signal.
  • Nonlinear, and deliberately carries no state space. The comparison and the counter are not describable by A/B/C/D, so model reduction correctly refuses the block.
  • On the HDL targets the comparison is made in Q16.16, so a sample whose movement sits within one quantum (about 1.5e−5) of Freeze Tolerance can be classified the other way from the software targets. The consequence is a run length off by one, which can move ok by a sample – a decision output, not a rounding error, exactly as in Argmax Decision. Choose a tolerance the signal's own steps do not sit on top of.
  • Choosing the pair is the whole design. A tolerance below the signal's own noise floor never fires; one above its slowest real motion fires on a healthy signal held briefly at a limit. Read count on a healthy run before choosing either.

Code facts#

FactValue
registered typeRobotics/Safety_Supervision/Watchdog_Timer
familyRobotics/Safety_Supervision
solver environment classICoreBlock_0_Robotics_1_Safety_Supervision_2_Watchdog_Timer
sourcesrc/ICoreSDK/ICoreBlockLibrary/Blocks/Robotics/Safety_Supervision/Watchdog_Timer/ICoreBlock_0_Robotics_1_Safety_Supervision_2_Watchdog_Timer.cpp
headersrc/ICoreSDK/ICoreBlockLibrary/Blocks/Robotics/Safety_Supervision/Watchdog_Timer/ICoreBlock_0_Robotics_1_Safety_Supervision_2_Watchdog_Timer.h
default size on canvas132 × 80 px
ports at insert1 in, 2 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDoubleu
2outICoreDoubleok
3outICoreDoublecount

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
Freeze Tolerance1e-6
Stuck Samples10
Initial Input0

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 available: nothing in the installed libraries latches on signal STALENESS. The Model Verification blocks assert on a value against a bound, and Detect Change reports the one sample on which a signal differs from its previous value rather than counting a run of samples on which it did not; the watchdog blocks that do exist belong to toolboxes not installed on this machine. Rebuild it on the Simulink side from a Unit Delay, an Abs, a Compare To Constant and a counter, keeping the saturating count this block documents

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.

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

Watchdog Timer — is this sensor still alive? It watches how far the input MOVES, not what it is worth:

frozen = ( |u[k] - u[k-1]| <= Freeze Tolerance ) count = frozen ? min(count + 1, Stuck Samples) : 0 ok = ( count >= Stuck Samples ) ? 0 : 1

A frozen encoder, a repeated CAN frame and an unplugged ADC all hold a PLAUSIBLE value, so no amount of range checking sees them. That is the gap this block fills, and it is why the Model Verification family (which asserts on levels) is not this block.

Three properties, each load-bearing:

  1. NO DIVISION, NO TRANSCENDENTAL, AND NO CONVERSION OUT OF FIXED POINT. One subtraction, one

absolute value, two comparisons and an increment -- so the three HDL targets are genuine synthesizable Q16.16. The counter is held as a fixed-point WHOLE NUMBER and compared against one, so §4's fx_to_int is not needed here at all.

  1. THE COUNTER SATURATES at Stuck Samples. Nothing downstream needs "frozen for 40,000

samples" rather than "frozen for 40", and a free-running counter leaves Q16.16's range in about five minutes at 10 ms -- passing on the bench and wrapping NEGATIVE in the field.

  1. THE PREVIOUS-SAMPLE SEED IS A CONFIG. There is no sample before the first one, so

something has to stand in for it, and only a config is visible to the user.

⚠ It does NOT latch: ok recovers on the first sample that moves. Latching until an operator clears the fault belongs to Emergency_Stop_Ramp, and duplicating it here would put the same behaviour in two blocks that a diagram is likely to hold at once.

Sample results#

Watchdog Timer — Step: 0 -> 1 at t = 1 sWatchdog Timer — Step: 0 -> 1 at t = 1 s0510012345t (s)in 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 … 1
rampRamp: slope 1 from t = 01 … 1
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias1 … 1
tableRepeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample1 … 1

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