调节器的自动调节
导言
为控制系统设置调节器是一项经典任务,作为TAU课程的一部分进行研究。 但是,本课程中研究的所有方法都需要花费大量时间。 在本出版物中,我们将介绍优化算法的应用,以加快和自动化控制设置。
我们将使用stepfun模型进行演示。:
筹备工作
我们将需要两个库:ControlSystemBase和Optim。 让我们安装它们:
import Pkg
Pkg.add(["ControlSystemsBase","Optim"])
现在,让我们创建一个函数来模拟模型。 仿真结果将从ControlSystemBase传递给stepinfo()函数。 该函数计算过渡过程的特征,并生成一个可以可视化的StepInfo类型对象。 我们将返回这样的对象:
gr()
engee.load(joinpath(@__DIR__,"stepfun.engee"))
using ControlSystemsBase
function sim_parameterized()
simres = engee.run("stepfun")
y = collect(simres["y"]);
u = collect(simres["u"]);
yv = reshape(y.value,(1,length(y.value)))
rt = ControlSystemsBase.SimResult(yv,y.time,yv,u.value,ss(tf([1.0],[1.0, 0.0])))
si = stepinfo(rt)
return si
end
开始行动
让我们来看看系统如何使用控制器的默认设置。:
engee.set_param!("stepfun/reg","P"=>1.0)
engee.set_param!("stepfun/reg","I"=>1.0)
si = sim_parameterized()
ref = plot(si)
display(ref)
让我们通过遍历参数来探索系统
迭代参数是研究参数对系统行为的影响的一种相当常见的方法。 这种方法的缺点是遍历参数需要很长时间。 即使我们并行搜索,我们也会等待大样本上的结果令人无法接受的长时间。 如果参数变化很大,分析的质量就会下降。 但即使这可以帮助我们的任务。 让我们看看调节器积分环节中增益因子的变化会产生什么影响。:
par_variation_l = 10;
param = collect(range(0.5,4.5,par_variation_l));
using ControlSystemsBase
# mySystem = feedback(tf([1.0],[1.0,1.0])*tf([1.0],[1.0, 0.0]))
K = 1.0
overshoot = zeros(par_variation_l);
setting_time = zeros(par_variation_l);
rise_time = zeros(par_variation_l);
for i in 1:par_variation_l
engee.set_param!("stepfun/reg","I"=>"$(param[i])")
si = sim_parameterized()
overshoot[i] = si.overshoot;
setting_time[i] = si.settlingtime;
rise_time[i] = si.risetime;
end
让我们检查遍历参数的结果
探索任何数据的最简单方法是通过他们的眼睛来看待它。 让我们来看看过冲(overshoot)、上升时间(rise_time)和设定点时间(setting_time)图。
p1 = plot(param, overshoot,label="overshoot")
p2 = plot(param,rise_time,color=:red,label="rise_time")
p3 = plot(param,setting_time,color=:green,label="setting_time")
plot(p1,p2,p3,layout=(3,1))
这里重要的不是定量结果,而是系统的行为方式。 我们看到,随着积分环节的增益增加,过冲和设定点时间也会增加。 因此,我们可以说期望的最佳系数应该小于1.5。 如果我们对起始环节进行这样的分析,那么我们也将能够对其加固系数提出要求。
自动调整调节器参数
我们将使用优化方法自动调整调节器。
要应用优化,您需要创建一个目标函数,我们将寻找最小值。 让我们使用StepInfo对象从结果中获取过渡过程的特征,函数将返回这些特征乘以权重的总和。 权重是根据过渡过程的要求分配的. 假设我们希望减少设定点时间,同时最大限度地减少过冲,但上升时间对我们来说并不重要。 然后,我们的目标函数将采取以下形式:
function cost_fun(p::Vector{Float64})
engee.set_param!("stepfun/reg","P"=>p[1])
engee.set_param!("stepfun/reg","I"=>p[2])
si = sim_parameterized()
return 2*si.overshoot + 0.5*si.risetime + 10*si.settlingtime
end
在您可以开始优化和调整控制器之前,您需要调整优化本身。 我们想限制对参数的搜索,因为我们发现参数的值小于1.5。 它们的下界将是0.5。 接下来,我们需要限制算法本身。
优化任务将同时使用两种算法-Fminbox作为"外部"算法,梯度下降作为"内部"算法。 在外部算法的每个步骤中,都会运行内部算法的几个步骤,如果我们不限制两种算法的步数,那么优化将花费很长时间甚至冻结。 有关设置的更详细说明,请参阅[文档](https://engee.com/helpcenter/stable/ru-en/julia/Optim/user/config.html )。
完成所有设置后,我们将开始优化。:
using Optim
lowbound = [0.5, 0.5];
highbound = [1.5, 1.5];
opt = Optim.Options(
iterations = 5,
outer_iterations = 25,
f_abstol = 1e-5,
f_reltol = 1e-2,
show_trace = true);
res = optimize(cost_fun, lowbound, highbound, [1.0, 1.0], Fminbox(GradientDescent()),opt)
发现了以下值。
optimal_params = Optim.minimizer(res)
让我们为初始稳压器和配置稳压器构建瞬态图。:
engee.set_param!("stepfun/reg","P"=>optimal_params[1])
engee.set_param!("stepfun/reg","I"=>optimal_params[2])
si = sim_parameterized()
fin = plot(si)
plot(ref,fin,layout=(2,1))
结论
我们研究了自动调整调节器的过程。 通过迭代参数,获得调节器的参数所在的边界,然后找到它们的确切值。
.png)
.png)
.png)