滞回¶
在本节中,我们将讨论滞回。这是为了理解某些特定的建模类型所必须的一个重要概念。还记得前面在状态事件的处理的讨论中,我们看到了抖动的例子。在那些例子里,我们可以使用noEvent
运算符来解决抖动的问题。这是因为前述抖动的情况纯粹是由数值噪音产生的。那与行为的突然变化毫无关系。
在本节中,我们将考虑一个稍微极端的例子。请考虑以下模型:
model ChatteringControl "A control strategy that will 'chatter'"
type HeatCapacitance=Real(unit="J/K");
type Temperature=Real(unit="K");
type Heat=Real(unit="W");
type Mass=Real(unit="kg");
type HeatTransferCoefficient=Real(unit="W/K");
Boolean heat "Indicates whether heater is on";
parameter HeatCapacitance C=1.0;
parameter HeatTransferCoefficient h=2.0;
parameter Heat Qcapacity=25.0;
parameter Temperature Tamb=285;
parameter Temperature Tbar=295;
Temperature T;
Heat Q;
initial equation
T = Tbar+5;
equation
heat = T<Tbar;
Q = if heat then Qcapacity else 0;
C*der(T) = Q-h*(T-Tamb);
end ChatteringControl;
倘若我们对模型进行仿真,便会得到下列结果:

然而,从开始仿真到产生上述结果却需要很长的时间。读者可以通过观察加热器在仿真中的输出,以进一步了解性能不佳的原因。
你会看到,在0.2秒左右之后,加热器不断地打开和关闭。这发生得如此频繁,以致于你要将图放大多次后才能看到这些转换。大量的状态转换让结果在正常比例下像一个填充满了的矩形。
这实际上是在控制系统中的现实问题。如果你仔细观察家里电炉的工作方式便会发现,电炉不会在高于或低于设定的室内温度时就不停地打开关闭。相反,电炉会等到温度变得高于或低于设定温度一定额度后,才会开始作出反应。
围绕着设定温度周围引入的“带”就叫做滞回。ChatteringControl
模型的问题就在于它并没有任何滞回。相反,该模型不停地开关加热器以响应微乎其微的温度变化。
要建模滞回必须考虑一个棘手的问题,也就是滞回是“有状态的”。那么要确定系统的行为我们必须知道系统的历史。因此,我们并不能简单地使用if
语句。其原因是if
语句除去考虑系统的当前状态外,并不会考虑别的因素。为了实现滞回,我们需要用到when
语句。考虑下列模型:
model HysteresisControl "A control strategy that doesn't chatter"
type HeatCapacitance=Real(unit="J/K");
type Temperature=Real(unit="K");
type Heat=Real(unit="W");
type Mass=Real(unit="kg");
type HeatTransferCoefficient=Real(unit="W/K");
Boolean heat(start=false) "Indicates whether heater is on";
parameter HeatCapacitance C=1.0;
parameter HeatTransferCoefficient h=2.0;
parameter Heat Qcapacity=25.0;
parameter Temperature Tamb=285;
parameter Temperature Tbar=295;
Temperature T;
Heat Q;
initial equation
T = Tbar+5;
heat = false;
equation
Q = if heat then Qcapacity else 0;
C*der(T) = Q-h*(T-Tamb);
when {T>Tbar+1,T<Tbar-1} then
heat = T<Tbar;
end when;
end HysteresisControl;
仔细观察上面的when
语句,我们可以知道仅当 T>Tbar+1
或者 T<Tbar-1
变为真时,系统才会有响应。请注意,若上述表达式变为假,系统并不会有响应。这就是为何if
语句在此并不适用。使用if
语句或者if
表达式时,只要条件表达式的值发生了变化,系统的行为就会改变。而使用when
语句时,仅仅当条件为真时,when
语句内的代码才会被激活。如果我们对该模型进行仿真并观察其温度,那么我们会看到温度保持在期望温度的滞环带内。

更重要的是,我们观察系统输出的热量时便会发现,与先前例子不同的是,解热器的开与关之间有些许的时间间隔。

通过使用algorithm
区域可以让实现滞回的逻辑变得更显然(正如我们前面在速度估测方法的讨论一样)。
model HysteresisControlWithAlgorithms "Control using algorithms"
type HeatCapacitance=Real(unit="J/K");
type Temperature=Real(unit="K");
type Heat=Real(unit="W");
type Mass=Real(unit="kg");
type HeatTransferCoefficient=Real(unit="W/K");
Boolean heat "Indicates whether heater is on";
parameter HeatCapacitance C=1.0;
parameter HeatTransferCoefficient h=2.0;
parameter Heat Qcapacity=25.0;
parameter Temperature Tamb=285;
parameter Temperature Tbar=295;
Temperature T;
Heat Q;
initial equation
T = Tbar+5;
heat = false;
equation
Q = if heat then Qcapacity else 0;
C*der(T) = Q-h*(T-Tamb);
algorithm
when T<Tbar-1 then
heat :=true;
end when;
when T>Tbar+1 then
heat :=false;
end when;
end HysteresisControlWithAlgorithms;
注意这两个条件表达式是如何被分成两个独立的when
语句的。如此这般,热源开闭的缘由也就显而易见了。由于这两个when
语句都是对同一个变量heat
进行赋值,因此两句都是在algorithm
区域里定义的。