我花了很多时间尝试使用两种方法模拟一个简单的SISO系统:
1)在MATLAB中使用lsim() 2)通过自己写下差分方程并在循环中迭代它们。
我从来没有能够从这两种方法得到相同的模拟结果,我不知道我做错了什么。
我将代码堆叠在一个m文件中,因此更容易理解。这是代码:
function main()
clear all
clc
simulateUsing_lsim()
simulateUsing_loop()
end
%%%%%% Simulating using lsim %%%%%%%
function simulateUsing_lsim()
% Define the continuous-time closed-loop system
P = getContPlant();
[Kp,Ki,Kd] = get_PIDgains();
C = pid(Kp,Ki,Kd);
clSys_cont = feedback(C*P,1);
% Define the discrete-time closed-loop system
hk = get_sampling_time();
clSys_disc = c2d(clSys_cont,hk);
% Generate the reference signal and the time vector
[r,t] = getReference(hk);
%% Simulate and plot using lsim
figure
lsim(clSys_disc,r,t)
%% Finding and plotting the error
y = lsim(clSys_disc,r);
e = r - y;
figure
p = plot(t,e,'b--');
set(p,'linewidth',2)
legend('error')
xlabel('Time (seconds)')
ylabel('error')
% xlim([-.1 10.1])
end
%%%%%% Simulating using loop iteration (difference equations) %%%%%%%
function simulateUsing_loop()
% Get the cont-time ol-sys
P = getContPlant();
% Get the sampling time
hk = get_sampling_time();
% Get the disc-time ol-sys in SS representation
P_disc = ss(c2d(P,hk));
Ad = P_disc.A;
Bd = P_disc.B;
Cd = P_disc.C;
% Get the PID gains
[Kp,Ki,Kd] = get_PIDgains();
% Generate the reference signal and the time vector
[r,t] = getReference(hk);
%% Perform the system simulation
x = [0 0]'; % Set initial states
e = 0; % Set initial errors
integral_sum = 0; % Set initial integral part value
for i=2:1:length(t)
% Calculate the output signal "y"
y(:,i) = Cd*x;
% Calculate the error "e"
e(:,i) = y(:,i) - r(i);
% Calculate the control signal vector "u"
integral_sum = integral_sum + Ki*hk*e(i);
u(:,i) = Kp*e(i) + integral_sum + (1/hk)*Kd*(e(:,i)-e(:,i-1));
% Saturation. Limit the value of u withing the range [-tol tol]
% tol = 100;
% if abs(u(:,i)) > tol
% u(:,i) = tol * abs(u(:,i))/u(:,i);
% else
% end
% Calculate the state vector "x"
x = Ad*x + Bd*u(:,i); % State transitions to time n
end
%% Subplots
figure
plot(t,y,'b',t,r,'g--')
%% Plotting the error
figure
p = plot(t,e,'r');
set(p,'linewidth',2)
legend('error')
xlabel('Time (seconds)')
ylabel('error')
end
function P = getContPlant()
s = tf('s');
P = 1/(s^2 + 10*s + 20);
end
function [Kp,Ki,Kd] = get_PIDgains()
Kp = 350;
Ki = 300;
Kd = 50;
end
function hk = get_sampling_time()
hk = 0.01;
end
function [r,t] = getReference(hk)
[r,t] = gensig('square',4,10,hk);
end
我从this页面获得了工厂模型P
及其PID控制器(参见等式10),其中系统是根据步进参考进行模拟的,结果看起来与{{{ 1}}结果(仅适用于单步峰值)。
但是,使用lsim()
模拟系统的结果是:
然而,使用for循环,我得到了这个性能:
我非常感谢任何帮助或澄清为什么我会得到不同的结果。