Reputation: 172
I have a discrete transfer function whose numerator and denominator are coming from an input port. At every sample time these numerator and denominator vectors change.
E.g.
@ t == 0
den == [1 0 -1]
@ t == 1
den == [1 0 0 -1]
What do I have to do in order for the transfer function to work with this?
I have tried:
SIMULINK did not like this and refused to run, complaining that the discrete transfer function block could not handle variable sized input.
This led to periodic spikes in the signal. Additionally, Simulink does not let you do this if you enter the values by hand, rather than as an input, so I don't think this is the way to do it either.
Any help is much appreciated.
Upvotes: 2
Views: 1390
Reputation: 1622
This is solved trivially with a single Simulink S-Function file sfuntvf.m
, like this.
In there, a custom fixed vector state with y
and u
s history is saved, and the time varying part is simply applied over the time history (depicted in cyan and yellow); here a FIR Filter with a random order (depicted in magenta).
Other build-in implementations shall consider the sucessive initial conditions between calls, and require the verification of the initial condition structure. The shown implementation is the easiest to deploy and understand.
The A
and B
vectors can be modified accordingly.
function [sys,x0,str,ts] = sfuntvf(t,x,u,flag)
N=20;
n=randi(N-2)+1;
A=[1;zeros(N-1,1)];
B=[1/n*ones(n,1);zeros(N-n,1)];
switch flag,
case 0, [sys,x0,str,ts] = mdlInitializeSizes(N);
case 2, sys = mdlUpdate(t,x,u,N,A,B);
case 3, sys = mdlOutputs(t,x,u,N,n);
case 9, sys = [];
otherwise DAStudio.error('Simulink:blocks:unhandledFlag',num2str(flag));
end
function [sys,x0,str,ts] = mdlInitializeSizes(N)
sizes = simsizes;
sizes.NumContStates = 0;
sizes.NumDiscStates = 2*N;
sizes.NumOutputs = 2;
sizes.NumInputs = 1;
sizes.DirFeedthrough = 0;
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);
x0 = zeros(2*N,1);
str = [];
ts = [1 0];
function sys = mdlUpdate(t,x,u,N,A,B)
un=x(1:N,1);
yn=x(N+1:2*N,1);
y=-A(2:end)'*yn(2:end)+B'*un;
sys = [u;un(1:end-1);y;yn(1:end-1)];
function sys = mdlOutputs(t,x,u,N,n)
sys = [x(N+1);n];
Upvotes: 0