我被分配了一个现有的应用程序项目。我应该为无故障控制器实现 Simulink 模型。 Simulink 模型适用于我给出的每个输入,但仅限于使用我的测试文件进行操作时。
在主文件中给出模型的传递函数 Gs、tau 值、u_min 和 u_max 的值。控制器应该获取变量,对其进行调节,然后返回 u、修正后的 w 和修正后的 e。但是模拟陷入了循环,我什么也做不了。它崩溃了,我就是这么做的:
simOut = sim('Deadbeatregler.slx','SimulationMode','normal');
它工作了一段时间。不记得改变过任何东西。
我将展示我的召回功能的应用程序设计器代码。我把其他代码放在pastebin链接中。
回调函数:
% Button pushed function: StartButton
function StartButtonPushed(app, event)
%Löschen aller Text- und Diagramm-Inhalte
app.StreckeTextArea.Value = '';
app.DeadBeatReglerTextArea.Value = '';
app.MesswerteTable.Data = {};
cla(app.RegelAxes);
cla(app.StellAxes);
%Streckenübertragungsfunktion in die Funktion holen
Gs = evalin('base','Gs');
%Entscheidung, welche Strategie gewählt wird
% IT2_Strecke = 0 -> PT2 oder IT2_Strecke = 1 -> IT2
%Teststrecke
%IT2_Strecke = 0;
%PT2 = tf(3, [0.1 0.7 1]);
%IT2 = tf(10, [0.02 0.3 1 0]);
%Eingabewerte auslesen und übergeben
assignin('base','u_max',app.U_maxEditField.Value);
assignin('base','u_min',app.U_minEditField.Value);
assignin('base','tau',app.AbtastzeitEditField.Value);
%assignin('base','IT2',0);
IT2_Strecke = evalin('base','IT2_Strecke');
%auswahlModi = app.RegelstrategieButtonGroup.Text;
u_max = evalin('base','u_max');
u_min = evalin('base','u_min');
if IT2_Strecke < 1
%%%%%%%%%%%%%%%
% PT2-Strecke %
%%%%%%%%%%%%%%%
%gs = PT2;
tau = evalin('base', 'tau');
gz = c2d(Gs, tau); % kontinuierliche Strecke diskretisieren
[numerator, denominator] = tfdata(gz); % Koeffizienten der diskretiesierten Strecke extrahieren
% Zähler
b2 = numerator{1}(1);
b1 = numerator{1}(2);
b0 = numerator{1}(3); % niedrigster Exponent
% Nenner
a2 = denominator{1}(1);
a1 = denominator{1}(2);
a0 = denominator{1}(3); % niedrigster Exponent
assignin('base','b2',b2);
assignin('base','b1',b2);
assignin('base','b0',b0);
assignin('base','a2',a2);
assignin('base','a1',a1);
assignin('base','a0',a0);
else
%%%%%%%%%%%%%%%
% IT2-Strecke %
%%%%%%%%%%%%%%%
%gs = IT2;
tau = evalin('base', 'tau');
gz = c2d(Gs, tau); % kontinuierliche Strecke diskretisieren
[numerator, denominator] = tfdata(gz); % Koeffizienten der diskretiesierten Strecke extrahieren
% Zähler
b2 = numerator{1}(2);
b1 = numerator{1}(3);
b0 = numerator{1}(4); % niedrigster Exponent
% Nenner
a2 = denominator{1}(2);
a1 = denominator{1}(3);
a0 = denominator{1}(4); % niedrigster Exponent
assignin('base','b2',b2);
assignin('base','b1',b2);
assignin('base','b0',b0);
assignin('base','a2',a2);
assignin('base','a1',a1);
assignin('base','a0',a0);
end
%Debug
%gs = evalin('base', 'gs');
%app.DebugTextArea.Value = gs;
%Werte aus Simulation holen
simOut = sim('Deadbeatregler.slx','SimulationMode','normal');
Sollwert_korr_w = simOut.get('Sollwert_korr_w');
Sollwert_korr_e = simOut.get('Sollwert_korr_e');
Sollwert_korr_u = simOut.get('Sollwert_korr_u');
Sollwert_Regelgroesse = simOut.get('Sollwert_Regelgroesse');
Sollwert_Stellgroesse = simOut.get('Sollwert_Stellgroesse');
Abtastzeit_Regelgroesse = simOut.get('Abtastzeit_Regelgroesse');
Abtastzeit_Stellgroesse = simOut.get('Abtastzeit_Stellgroesse');
%Debug
assignin('base',"Sollwert_Stellgroesse",Sollwert_Stellgroesse);
assignin('base',"Abtastzeit_Stellgroesse",Abtastzeit_Stellgroesse);
assignin('base',"Sollwert_korr_u",Sollwert_korr_u);
assignin('base',"Sollwert_korr_w",Sollwert_korr_w);
assignin('base',"Sollwert_korr_e",Sollwert_korr_e);
if IT2_Strecke < 1
% Ausgabe der Streckenübertragungsfunktion Gz
app.StreckeTextArea.Value = sprintf('\t%.5fz + %.5f\nGz(z) = ―――――――――――――――――― \n\t%.5fz² + %.5fz',b2,b1,a2,a1);
% Ausgabe des Dead-Beat-Reglers Gz
app.DeadBeatReglerTextArea.Value = sprintf('\tz² + %.5fz + %.5f\nGr(z) = ―――――――――――――――――――――― \n\t%.5fz³ + %.5fz² + %.5fz',a1,a2,b1+b2,-b1,-b2);
else
% Ausgabe der Streckenübertragungsfunktion Gz
app.StreckeTextArea.Value = sprintf('\t%.5fz² + %.5fz + %.5f\nGz(z) = ―――――――――――――――――― \n\tz³ + %.5fz² + %.5fz + %.5f',b1,b2,b3,a1,a2,a3);
% Ausgabe des Dead-Beat-Reglers Gz
app.DeadBeatReglerTextArea.Value = sprintf('\tz³ + %.5fz² + %.5fz + %.5f\nGr(z) = ―――――――――――――――――――――― \n\t%.5fz³ + %.5fz² + %.5fz + %.5f',a1,a2,a3,b1+b2+b3,-b1,-b2,-b3);
end
% Ausgabe Ausregelschritte und Gesamtregeldauer
letzter_zeitpunkt = app.AbtastzeitEditField.Value(end);
if IT2_Strecke == 0
app.kEditField.Value = 1;%countervariable;
app.TrsEditField.Value = 1;%zeitvariable;
else
app.kEditField.Value = 1;%countervariable;
app.TrsEditField.Value = 1;%zeitvariable;
end
%Tabelle für U, W, E
%Wenn Abtastzeit
%Wenn Sollwert
%Wenn Keine
tabellenzeit = Sollwert_korr_u.time;
values1 = Sollwert_korr_u.signals.values;
values2 = Sollwert_korr_w.signals.values;
values3 = Sollwert_korr_e.signals.values;
Data = table(tabellenzeit, values1, values2, values3);
uitable_data = table2cell(Data);
app.MesswerteTable.Data = uitable_data;
% Plot der Stellgröße
if app.SollwertkorrekturButton.Value
stairs(app.StellAxes, Sollwert_Stellgroesse.time, Sollwert_Stellgroesse.signals.values, "LineWidth", 1.5);
elseif app.AbtastzeitButton.Value
stairs(app.StellAxes, Abtastzeit_Stellgroesse.time, Abtastzeit_Stellgroesse.signals.values, "LineWidth", 1.5);
elseif app.keineButton.Value %für 'keine' wird der Graph für Sollwertkorrektur verwendet
stairs(app.StellAxes, Sollwert_Stellgroesse.time, Sollwert_Stellgroesse.signals.values, "LineWidth", 1.5);
end
%Plot der Regelgröße
if app.SollwertkorrekturButton.Value == 1
plot(app.RegelAxes, Sollwert_Regelgroesse.time, [Sollwert_Regelgroesse.signals.values], "LineWidth", 1.5);
elseif app.AbtastzeitButton.Value == 1
plot(app.RegelAxes, Abtastzeit_Regelgroesse.time, [Abtastzeit_Regelgroesse.signals.values], "LineWidth", 1.5);
else app.keineButton.Value%für 'keine' wird der Graph für Sollwertkorrektur verwendet
plot(app.RegelAxes, Sollwert_Regelgroesse.time, [Sollwert_Regelgroesse.signals.values], "LineWidth", 1.5);
end
%% Fehlerausgabe
if app.AbtastzeitEditField.Value <= 0
app.StreckeTextArea.Value = 'Abtastzeit muss größer als 0 sein!';
app.DeadBeatReglerTextArea.Value = 'Abtastzeit muss größer als 0 sein!';
elseif app.U_maxEditField.Value < app.U_minEditField.Value
app.StreckeTextArea.Value = 'U_max muss größer als U_min sein!';
app.DeadBeatReglerTextArea.Value = 'U_max muss größer als U_min sein!';
elseif app.U_maxEditField.Value <= 0
app.StreckeTextArea.Value = 'U_max muss positiv sein!';
app.DeadBeatReglerTextArea.Value = 'U_max muss positiv sein!';
elseif app.U_minEditField.Value > app.U_maxEditField.Value
app.StreckeTextArea.Value = 'U_min muss größer als U_max sein!';
app.DeadBeatReglerTextArea.Value = 'U_min muss größer als U_max sein!';
elseif app.U_minEditField.Value >= 0
app.StreckeTextArea.Value = 'U_min muss negativ sein!';
app.DeadBeatReglerTextArea.Value = 'U_min muss negativ sein!';
end
end
完整的应用程序设计器代码:
https://pastebin.com/X6hcpV0i
PID DesignerMod:(我只添加了从第 412 行到第 442 行
https://pastebin.com/B3JXxyQj
控制器的 Simulink 代码:
控制器 1:
https://pastebin.com/Pk20zNax
控制器2:
https://pastebin.com/4ap72Jys
我希望有人能找到我忽略的东西或者丢失或错误的东西。
尝试过chatgpt、同事、论坛文章...
测试功能应该是:
扎勒:3
嫩纳:0.1 0.7 1
传递函数 Gs:30/((s+5)(s+1)
好的,前面提到的问题已经解决了: 犯了错误。我输入:
assignin('base','b2',b2);
assignin('base','b1',b2);
assignin('base','b0',b0);
而不是:
assignin('base','b2',b2);
assignin('base','b1',b1);
assignin('base','b0',b0);