将 fminimax
与 Simulink 模型结合使用
此示例显示如何调整 Simulink ® 模型的参数。运行此示例时,将包含模型 optsim
。该模型包括一个以 Simulink 框图建模的非线性过程工厂。
执行器饱和的工厂
该设备是一个具有执行器限制的欠阻尼三阶模型。执行器的限制是饱和限制和斜率限制。执行器饱和限制会切断大于 2 个单位或小于 -2 个单位的输入值。执行器的斜率限制为 0.8 单位/秒。系统对阶跃输入的闭环响应如闭环响应所示。您可以通过打开模型(在命令行中输入 optsim
或单击模型名称)并从仿真菜单中选择运行来查看此响应。响应绘制在范围内。
闭环响应
问题是设计一个反馈控制回路来跟踪系统的单位阶跃输入。闭环设备是按照设备和执行器位于分层 Subsystem 块中的块来输入的。Scope 块显示设计过程中的输出轨迹。
闭环模型
为了优化这个系统,最小化任意时间输出的最大值 在 0 到 100 之间。(相反,在示例 lsqnonlin 与 Simulink 模型 中,解涉及最小化输出和输入信号之间的误差。)
本示例的代码包含在本示例 末尾的辅助函数 runtrackmm
中。目标函数只是 sim
命令返回的输出 yout
。但是,最小化所有时间步骤中的最大输出可能会迫使输出在某些时间步骤中远低于 1。为了在前 20 秒后保持输出高于 0.95,约束函数 trackmmcon
包含从 t = 20
到 t = 100
的约束 yout >= 0.95
。因为约束必须采用 形式,所以函数中的约束为 g = -yout(20:100) + 0.95
。
trackmmobj
和 trackmmcon
都使用从 sim
得出的结果,该结果根据当前 PID 值计算得出。为了避免两次调用模拟,runtrackmm
具有嵌套函数,以便 yout
的值在目标函数和约束函数之间共享。仅当当前点发生变化时才会调用模拟。
调用 runtrackmm
。
[Kp,Ki,Kd] = runtrackmm
Objective Max Line search Directional Iter F-count value constraint steplength derivative Procedure 0 5 0 1.11982 1 11 1.184 0.07978 1 0.482 2 17 1.012 0.04285 1 -0.236 3 23 0.9996 0.00397 1 -0.0195 Hessian modified twice 4 29 0.9996 3.464e-05 1 0.000687 Hessian modified 5 35 0.9996 2.274e-09 1 -0.0175 Hessian modified twice Local minimum possible. Constraints satisfied. fminimax stopped because the predicted change in the objective function is less than the value of the function tolerance and constraints are satisfied to within the value of the constraint tolerance.
Kp = 0.5894
Ki = 0.0605
Kd = 5.5295
输出的 Objective value
列中的最后一个值表明所有时间步长的最大值略小于 1。具有此结果的闭环响应如图使用 fminimax 的闭环响应所示。
该解与在 lsqnonlin 与 Simulink 模型 中获得的解不同,因为您正在求解不同的问题表示。
使用 fminimax
实现闭环响应
辅助函数
以下代码创建 runtrackmm
辅助函数。
function [Kp, Ki, Kd] = runtrackmm optsim % initialize Simulink(R) pid0 = [0.63 0.0504 1.9688]; % a1, a2, yout are shared with TRACKMMOBJ and TRACKMMCON a1 = 3; a2 = 43; % Initialize plant variables in model yout = []; % Give yout an initial value pold = []; % tracks last pid opt = simset('solver','ode5','SrcWorkspace','Current'); options = optimset('Display','iter',... 'TolX',0.001,'TolFun',0.001); pid = fminimax(@trackmmobj,pid0,[],[],[],[],[],[],... @trackmmcon,options); Kp = pid(1); Ki = pid(2); Kd = pid(3); function F = trackmmobj(pid) % Track the output of optsim to a signal of 1. % Variables a1 and a2 are shared with RUNTRACKMM. % Variable yout is shared with RUNTRACKMM and % RUNTRACKMMCON. updateIfNeeded(pid) F = yout; end function [c,ceq] = trackmmcon(pid) % Track the output of optsim to a signal of 1. % Variable yout is shared with RUNTRACKMM and % TRACKMMOBJ updateIfNeeded(pid) c = -yout(20:100)+.95; ceq=[]; end function updateIfNeeded(pid) if ~isequal(pid,pold) % compute only if needed Kp = pid(1); Ki = pid(2); Kd = pid(3); [~,~,yout] = sim('optsim',[0 100],opt); pold = pid; end end end