Generated reference › Discrete Varying State Space — Control Systems/Linear Parameter Varying
kind: generated#block#control-systems-linear-parameter-varying

Discrete Varying State Space — Control Systems/Linear Parameter Varying

A B C D

Control_Systems/Linear_Parameter_Varying/Discrete_Varying_State_Space · 5 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.

Discrete Varying State Space

Control Systems / Linear Parameter Varying

A discrete state-space system whose matrices are signals, not settings:

x[k+1] = A[k]·x[k] + B[k]·u[k]
y[k] = C[k]·x[k] + D[k]·u[k]

A, B, C and D are read afresh on every sample, so a scheduling signal can move the system while it runs – the linear parameter-varying (LPV) realization. At any one instant the block is exactly the ordinary Discrete State Space; across instants it is not, which is what the varying matrices buy and what the Notes below say the cost of is.

Ports

  • u – the input vector, [m,1].
  • A – the state matrix, [n,n]. Its size is what defines n: the state count is taken from this port, not from any parameter.
  • B – the input matrix, [n,m].
  • C – the output matrix, [p,n].
  • D – the feedthrough matrix, [p,m].
  • y – the output vector, [p,1], from the current state.
  • x – the current state x[k], [n,1].
  • x+ – the next state x[k+1], [n,1], the same value this block will use itself on the following sample.

The five sizes must agree with one another exactly – A square, B and D sharing u's width m, C and D sharing y's height p – and a disagreement is reported with the two offending shapes once the model's port sizes have settled. Nothing is scalar-expanded here: these are matrices with a meaning, and a silent expansion would hide a mis-wired schedule.

Parameters

  • Initial State Vector – x[0]. A scalar is used for every state, which is how Simulink's own initial condition behaves and the only form that can be written before n is known; an [n,1] vector sets each state separately. Defaults to 0.
  • 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.

Nothing about the system is baked into the generated core except its dimensions: n, m and p are fixed at export time, so every loop is statically sized, while A, B, C and D are read from their input signals on every step exactly as they are in simulation. There is consequently no tunable parameter on the exported core – retuning is what the coefficient ports are for, and they remain live on the deployed core. Only the initial state is emitted as a constant, since it is consumed once before the first sample.

The three HDL targets carry the recursion in Q16.16 fixed point and are fully synthesizable. Note that a coefficient arriving on a port is already quantized to one Q16.16 quantum (1.5×10-5) before the block sees it, so a schedule that relies on finer coefficient resolution than that will not survive an HDL export, however exactly the software targets reproduce it.

Simulink bridge

Import and export, mapped to cstblocks/Linear Parameter Varying/Discrete Varying State Space, with "Initial State Vector" going to InitialCondition as a pass-through value.

The rate crosses under a different name. This Simulink block calls its rate parameter Ts, not SampleTime, so the catalog entry names it explicitly. Emitting the usual name would not degrade gracefully: a set_param for a parameter a block does not define is a hard MATLAB error that aborts the entire generated script.

Four Simulink parameters are always implied rather than offered as a choice, because each of them moves ports and no config value here can add or remove one: Feedthrough = on (the D input), OutputX = on and OutputDX = on (the x and x+ outputs), and InitialConditionSource = internal. The four external-initial-value inputs (InputX0, InputDX0, InputU0, InputY0) stay off for the same reason.

Notes

  • Discrete only, and stateful: the state is the [n,1] vector x.
  • No state space, deliberately. The block is linear at every instant but time-varying overall, so there is no single A/B/C/D to hand to model reduction or the linear-analysis commands, and they report it as unmergeable. That is the correct answer rather than a limitation: a state space seeded from whatever the coefficient ports happened to carry would be a snapshot, and merging it into a neighbouring plant would produce a model that is wrong the moment the schedule moves. For a system that genuinely does not vary, use Discrete State Space, which carries a real one.
  • x+ is not a preview of a re-read. The x+ output is the same value the block stores, computed from the current state and the current coefficients, so feeding it back into a schedule cannot disagree with what the block does next.

Code facts#

FactValue
registered typeControl_Systems/Linear_Parameter_Varying/Discrete_Varying_State_Space
familyControl_Systems/Linear_Parameter_Varying
solver environment classICoreBlock_0_Control_Systems_1_Linear_Parameter_Varying_2_Discrete_Varying_State_Space
sourcesrc/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Linear_Parameter_Varying/Discrete_Varying_State_Space/ICoreBlock_0_Control_Systems_1_Linear_Parameter_Varying_2_Discrete_Varying_State_Space.cpp
headersrc/ICoreSDK/ICoreBlockLibrary/Blocks/Control_Systems/Linear_Parameter_Varying/Discrete_Varying_State_Space/ICoreBlock_0_Control_Systems_1_Linear_Parameter_Varying_2_Discrete_Varying_State_Space.h
default size on canvas150 × 120 px
ports at insert5 in, 3 out
code generators implementedPython, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text

Ports#

#DirectionSignal typeDescription label
1inICoreDoubleu
2inICoreDoubleA
3inICoreDoubleB
4inICoreDoubleC
5inICoreDoubleD
6outICoreDoubley
7outICoreDoublex
8outICoreDoublex+

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
Initial State Vector0InitialCondition

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 pathcstblocks/Linear Parameter Varying/Discrete Varying State Space
port-count rulePortsParam::None
SampleTime parameteryes
rate parameter nameTs
always setFeedthrough = on, OutputX = on, OutputDX = on, InitialConditionSource = internal, InputX0 = off, InputDX0 = off, InputU0 = off, InputY0 = off
ICore configSimulink parameterValue translation
Initial State VectorInitialConditionpasses through

Caveat (shown to the user): the coefficient matrices are signals on both sides, so nothing about them is a parameter to carry; the four external initial-value inputs (InputX0, InputDX0, InputU0, InputY0) are not supported, since each adds an input port in Simulink and no config value here can add or remove a port

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 1 port label(s) this tool cannot resolve

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

Discrete Varying State Space block -- the discrete LPV realization x[k+1] = A[k] x[k] + B[k] u[k], y[k] = C[k] x[k] + D[k] u[k], where A, B, C and D arrive on INPUT PORTS instead of living in config. Five inputs (u, A, B, C, D), three outputs (y, x[k], x[k+1]), matching cstblocks/Linear Parameter Varying/Discrete Varying State Space port for port and label for label.

Why this is not just Discrete State Space with a different config The DIMENSIONS are fixed at build time and the VALUES are not. n, m and p come off the coefficient ports once the port-size convergence loop settles, so every generated loop is still statically sized -- but the coefficients themselves are read fresh on every step, which is the whole difference from Discrete State Space and the reason none of the ten generators can bake a literal into the arithmetic.

That also decides the state space question: see the header. The block is linear at every instant and time-varying overall, so it carries NO ICoreStateSpace at all rather than a snapshot that model reduction would merge as if it were the system.

Code export (all ten targets) Structurally identical to the in-app simulation, and to Discrete State Space's exports except that A/B/C/D are read from the input signals rather than emitted as constants: y[k] = C x[k] + D u[k] (output from the CURRENT state) x[k+1] = A x[k] + B u[k] (state update, from that same x[k]) x is the only persistent state, seeded from "Initial State Vector".

Sample results#

Discrete Varying State Space — Step: 0 -> 1 at t = 1 sDiscrete Varying State Space — Step: 0 -> 1 at t = 1 s02040012345t (s)in ICoreDouble-Out-0in ICoreDouble-Out-0in ICoreDouble-Out-0out ICoreDouble-Out-0out ICoreDouble-Out-1out ICoreDouble-Out-2

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 = 00 … 5.695e24
sineSine Wave: amplitude 1, 2 rad/s, no phase, no bias-0.004824 … 5.322
tableRepeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample-53 … 54

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