Reputation: 13
I am currently implementing a second order low-pass filter employing Tustin discretization as embedded function within a Simulink model. The function has currently deployed as follows:
function y = SecondOrderLowpassFilterTustin(u,fn,dn,Ts)
persistent xs
if isempty(xs)
xs = [u 0]';
end
% Convert frequency from Hz to rad/s
wn = fn*2*pi;
% Construct state-space matrices in continuous time
A = [0 1 ; -wn^2 -2*dn*wn];
B = [0 ; wn^2];
C = [1 0];
D = 0;
% Construct equivalent state-space matrices in discrete time
I = eye(size(A));
K1 = (I + 0.5*A*Ts);
K2 = (I - 0.5*A*Ts)^-1;
Ad = K1*K2;
Bd = K2*B*Ts;
Cd = C*K2;
Dd = (0.5*Ts*C*K2*B) + D;
% Calculate output
xs = Ad*xs + Bd*u;
y = Cd*xs + Dd*u;
end
I am then calling such function from within another function which looks like this:
function u1 = fcn(u,fn,dn,Ts)
u1 = SecondOrderLowpassFilterTustin(u(1),fn,dn,Ts);
In all those cases when I call the function a single time, as in the case
y1 = SecondOrderLowpassFilterTustin(u1,fn,dn,Ts);
the results are ok
However, as soon as I would like to filter multiple signals concurrently, as in the following case
function [u1,u2,u3] = fcn(u,fn,dn,Ts)
u1 = SecondOrderLowpassFilterTustin(u(1),fn,dn,Ts);
u2 = SecondOrderLowpassFilterTustin(u(2),fn,dn,Ts);
u3 = SecondOrderLowpassFilterTustin(u(3),fn,dn,Ts);
the results are poor as in Figure 2.
I believe that it has to do with the persistent state variable xs
, which should undergo a reset or initialization as soon as the SecondOrderLowpassFilterTustin(u,fn,dn,Ts)
is being called.
I have tried different things out, unfortunately with little success. Therefore, your suggestions are highly appreciated.
Upvotes: 1
Views: 65
Reputation: 6863
Indeed, the persistent variable is not reset when calling the filter function the second and third time, and thus the initial xs
is not set correctly. Since you want to use the function for multiple signals, the persistent variable cannot be inside SecondOrderLowpassFilterTustin
.
You can however let this function output xs
and take xs
as input argument, and keep this persistent in fcn
.
function [y, xs] = SecondOrderLowpassFilterTustin(u,fn,dn,Ts,xs)
if isempty(xs)
xs = [u 0].';
end
% Convert frequency from Hz to rad/s
wn = fn*2*pi;
% continue with the rest...
end
And fcn
would look like:
function [u1,u2,u3] = fcn(u,fn,dn,Ts)
persistent x1 x2 x3
% x1, x2 and x3 will be [] on first iteration, thus xs will be set to [u 0].'
[u1,x1] = SecondOrderLowpassFilterTustin(u(1),fn,dn,Ts,x1);
[u2,x2] = SecondOrderLowpassFilterTustin(u(2),fn,dn,Ts,x2);
[u3,x3] = SecondOrderLowpassFilterTustin(u(3),fn,dn,Ts,x3);
end
BTW, don't think you expect any complex output, but just in case '
is not transpose, .'
is.
Upvotes: 2