嵌入式函数中的持久状态问题
Problem with persistent states within embedded function
我目前正在实施二阶低通滤波器,该滤波器采用 Tustin 离散化作为 Simulink 模型中的嵌入式函数。该功能目前已部署如下:
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
然后我从另一个函数中调用这样的函数,如下所示:
function u1 = fcn(u,fn,dn,Ts)
u1 = SecondOrderLowpassFilterTustin(u(1),fn,dn,Ts);
在所有那些我调用函数一次的情况下,如
y1 = SecondOrderLowpassFilterTustin(u1,fn,dn,Ts);
结果还可以
但是,一旦我想同时过滤多个信号,如下例
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);
结果很差,如图 2 所示。
我认为它与持久状态变量 xs
有关,一旦调用 SecondOrderLowpassFilterTustin(u,fn,dn,Ts)
,它应该进行重置或初始化。
我尝试了不同的方法,不幸的是收效甚微。因此,非常感谢您的建议。
的确,在第二次和第三次调用过滤函数时,持久变量没有被重置,因此初始的xs
设置不正确。由于要将函数用于多个信号,因此持久变量不能在 SecondOrderLowpassFilterTustin
内。
然而你可以让这个函数输出 xs
并把 xs
作为输入参数,并在 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
而 fcn
看起来像:
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
顺便说一句,不要认为您期望任何复杂的输出,但以防万一 '
不是转置,.'
是。
我目前正在实施二阶低通滤波器,该滤波器采用 Tustin 离散化作为 Simulink 模型中的嵌入式函数。该功能目前已部署如下:
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
然后我从另一个函数中调用这样的函数,如下所示:
function u1 = fcn(u,fn,dn,Ts)
u1 = SecondOrderLowpassFilterTustin(u(1),fn,dn,Ts);
在所有那些我调用函数一次的情况下,如
y1 = SecondOrderLowpassFilterTustin(u1,fn,dn,Ts);
结果还可以
但是,一旦我想同时过滤多个信号,如下例
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);
结果很差,如图 2 所示。
我认为它与持久状态变量 xs
有关,一旦调用 SecondOrderLowpassFilterTustin(u,fn,dn,Ts)
,它应该进行重置或初始化。
我尝试了不同的方法,不幸的是收效甚微。因此,非常感谢您的建议。
的确,在第二次和第三次调用过滤函数时,持久变量没有被重置,因此初始的xs
设置不正确。由于要将函数用于多个信号,因此持久变量不能在 SecondOrderLowpassFilterTustin
内。
然而你可以让这个函数输出 xs
并把 xs
作为输入参数,并在 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
而 fcn
看起来像:
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
顺便说一句,不要认为您期望任何复杂的输出,但以防万一 '
不是转置,.'
是。