Varying Transfer Function — Control Systems/Linear Parameter Varying
Control_Systems/Linear_Parameter_Varying/Varying_Transfer_Function · 4 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.
Varying Transfer Function
Control Systems / Linear Parameter Varying
A first-order continuous transfer function whose coefficients are signals, not settings:
y = (b0·s + b1) / (s + a1) · u
b0, a1 and b1 are read afresh at every step, so a scheduling signal can retune the filter while it runs. It is realized in the observer canonical form:
dx/dt = −a1·x + (b1 − a1·b0)·u, y = x + b0·u
That is not an arbitrary choice among equivalent forms. Any realization of the same transfer function agrees while the coefficients are constant, but once they vary the state means a different thing in each and the outputs diverge. This is the form Simulink's own block uses, which is why the two agree exactly rather than approximately.
Ports
- u – the input signal, of any size [p,m].
- b0 – the numerator's s coefficient, a scalar. It is also the block's direct feedthrough: at b0 = 0 the filter is strictly proper.
- a1 – the denominator's constant term, a scalar. The pole is at s = −a1, so a positive a1 is the stable half and the filter's time constant is 1/a1.
- b1 – the numerator's constant term, a scalar.
- Output – y, the same size as u.
The three coefficient ports must each carry a scalar: the block is first order, and a vector there is a mis-wired signal rather than a per-entry coefficient set. It is reported once the model's port sizes have settled. The filter itself runs element-wise – every entry of u gets its own state, driven by the same three coefficients.
Parameters
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period. It does not cross to Simulink (that block has no rate parameter), but it is the step the exported core integrates with – see Code export.
There is deliberately no initial-condition parameter: the Simulink counterpart has none either, and inventing one would be a semantic the reference does not have. The state starts at zero.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text.
Only the entry count is fixed at export time; b0, a1 and b1 are read from their signals every step, so the core carries no tunable parameter at all – the coefficient ports stay live on the deployed core.
The exported core integrates with forward Euler, x ← x + Ts·(−a1·x + u). A filter whose coefficients are signals cannot be discretized ahead of time the way Transfer Function is, because they are not known until the step runs. The core is therefore first-order accurate in Ts: choose a period short against 1/a1, the filter's own time constant.
Simulink bridge
Import and export, mapped to cstblocks/Linear Parameter Varying/Varying Transfer Function.
The rate does not cross: this block defines no rate parameter of any
name – not SampleTime, and not the Ts its
Discrete sibling carries – so "Sampling Time (s)" stays on the ICore side.
Emitting either would be a hard set_param error that aborts the
whole generated script.
Two Simulink parameters are always implied: N = 1, since
this block is first order and N is what moves the coefficient ports, and
Feedthrough = on, which is what makes b0 a port at all.
Neither has a config behind it because no config value here can add or remove a
port.
Notes
- Continuous and stateful: one state per entry of u, integrated by the solver.
- No state space, deliberately, as everywhere in this family: linear at every instant, time-varying overall, so model reduction is right to refuse it rather than merge a snapshot of whatever the coefficient ports happened to carry. For a filter that genuinely does not vary, use Transfer Function.
- The pole is at −a1, and nothing here constrains its sign – a schedule that drives a1 negative makes the filter genuinely unstable, which is the block faithfully doing what it was asked.
Code facts#
| Fact | Value |
|---|---|
| registered type | Control_Systems/Linear_Parameter_Varying/Varying_Transfer_Function |
| family | Control_Systems/Linear_Parameter_Varying |
| solver environment class | ICoreBlock_0_Control_Systems_1_Linear_Parameter_Varying_2_Varying_Transfer_Function |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Linear_Parameter_Varying/Varying_Transfer_Function/ICoreBlock_0_Control_Systems_1_Linear_Parameter_Varying_2_Varying_Transfer_Function.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Linear_Parameter_Varying/Varying_Transfer_Function/ICoreBlock_0_Control_Systems_1_Linear_Parameter_Varying_2_Varying_Transfer_Function.h |
| default size on canvas | 130 × 100 px |
| ports at insert | 4 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | u |
| 2 | in | ICoreDouble | b0 |
| 3 | in | ICoreDouble | a1 |
| 4 | in | ICoreDouble | b1 |
| 5 | out | ICoreDouble | — |
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.
Simulink bridge#
| support | Support::Both |
| Simulink path | cstblocks/Linear Parameter Varying/Varying Transfer Function |
| port-count rule | PortsParam::None |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| always set | N = 1, Feedthrough = on |
Caveat (shown to the user): the coefficients are signals on both sides, so nothing about them is a parameter to carry; the order is fixed at one (N = 1), since N is what moves the coefficient ports and no config value here can add or remove a port
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).
Varying Transfer Function -- the first-order CONTINUOUS LPV filter y = (b0*s + b1) / (s + a1) * u, with b0, a1 and b1 arriving on INPUT PORTS.
Realized in Simulink's OBSERVER canonical form, dx/dt = -a1*x + (b1 - a1*b0)*u, y = x + b0*u -- element-wise over u's [p,m] entries, one state each. The header explains why that choice is observable here and must not be "simplified" to the controllable form.
Code export: all ten targets, integrating with FORWARD EULER at the block's sampling period. A coefficient that arrives as a signal cannot be pre-discretized, so this is forced rather than chosen -- the same call its sibling Varying State Space makes, with the same consequence stated in the description.
Sample results#
The same rig also ran:
| Stimulus | What it is | Output range |
|---|---|---|
impulse | Impulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair) | 0 … 1.008 |
ramp | Ramp: slope 1 from t = 0 | 0 … 7.622 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | 0 … 4.762 |
table | Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample | -1.027 … 9.564 |
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/Control_Systems__Linear_Parameter_Varying__Varying_Transfer_Function.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).