再探速度测量¶
回想一下我们前面对速度的测量的讨论。讨论发生在我们引入构建可重用组件方法之前。这样一来,为不同的速度测量技术相关添加方程颇为麻烦。
本节中,我们将重新审视该主题,并再次讨论所有不同的速度估测技术。和之前一样,我们假设“受控对象”模型(我们希望进行测速的系统)已经存在。但这一次,我们将为不同的速度估测算法创建可重用的组件模型,并将其以图形组件形式添加到受控模型里。
受控对象模型¶
我们首先处理“受控对象模型”。模型行为和在此前讨论速度的测量时的版本一致。系统示意图如下:
相应的Modelica模型源代码为:
within ModelicaByExample.Components.SpeedMeasurement.Examples;
model Plant "The basic plant model"
extends ModelicaByExample.Components.Rotational.Examples.SMD;
Components.IdealSensor idealSensor
annotation (Placement(transformation(extent={{-10,-10},{10,10}},
rotation=90, origin={-20,30})));
equation
connect(idealSensor.flange, inertia1.flange_a) annotation (Line(
points={{-20,20},{-20,0},{-10,0}}, color={0,0,0},
smooth=Smooth.None));
annotation(experiment(StopTime=10, Tolerance=1e-006));
end Plant;
在本节剩余部分,我们将创建使用不同估算方法的模型,对受控对象模型的inertia1
组件进行测速。
我们在观察不同的速度近似方法前,让我们先看看受控对象模型的实际响应速度。
请注意,该响应与我们首次讨论此话题时的一模一样。
取样保持传感器¶
此前,我们讨论了取样保持的测速方法。在这里,我们将再次讨论这个话题。不过,我们会把速度估测封装为可重用的传感器模型。下面模型实现了速度测量的“采样保持”近似:
within ModelicaByExample.Components.SpeedMeasurement.Components;
model SampleHold "A sample-hold ideal speed sensor"
extends Interfaces.SpeedSensor;
parameter Modelica.SIunits.Time sample_rate;
initial equation
w = der(flange.phi);
equation
when sample(0, sample_rate) then
w = der(flange.phi);
end when;
end SampleHold;
Behaviorally, there is no difference between this estimation technique and our previous implementation of 取样保持. But our approach is different this time because we have wrapped that estimation technique in a reusable component model.
我们再次用技巧免去一些麻烦。这里,我们通过利用partial
模型来表示各种传感器模型内的通用代码。我们可以从SpeedSensor
模型的定义里发现:
within ModelicaByExample.Components.SpeedMeasurement.Interfaces;
partial model SpeedSensor "The base class for all of our sensor models"
extends Modelica.Mechanics.Rotational.Interfaces.PartialAbsoluteSensor;
Modelica.Blocks.Interfaces.RealOutput w "Sensed speed"
annotation (Placement(transformation(extent={{100,-10},{120,10}})));
end SpeedSensor;
我们可以从SpeedSensor
模型中看到,输出信号命名为w
。但是,我们也看到SpeedSensor
是继承自Modelica标准库的另一个模型PartialAbsoluteSensor
。PartialAbsoluteSensor
模型定义为:
partial model PartialAbsoluteSensor
"Partial model to measure a single absolute flange variable"
extends Modelica.Icons.RotationalSensor;
Flange_a flange "Flange from which speed will be measured"
annotation(Placement(transformation(extent={{-110,-10},{-90,10}}, rotation=0)));
equation
0 = flange.tau;
end PartialAbsoluteSensor;
除了提供一个很好的图标外,PartialAbsoluteSensor
模型还带有旋转连接器flange
。此外,该模型假定传感器模型完全是被动的(即传感器对其所测系统无影响)。因此,模型对连接点施加零转矩。
为了测试这个模型,我们只是从Plant
模型进行扩展,加上SampleHold
传感器的实例,并将传感器连接到inertia
上,如:
within ModelicaByExample.Components.SpeedMeasurement.Examples;
model PlantWithSampleHold "Comparison between ideal and sample-hold sensor"
extends Plant;
Components.SampleHold sampleHold(sample_rate=0.125)
annotation (Placement(transformation(extent={{-10,-10},{10,10}},
rotation=90, origin={20,30})));
equation
connect(sampleHold.flange, inertia1.flange_b) annotation (Line(
points={{20,20},{20,0},{10,0}}, color={0,0,0},
smooth=Smooth.None));
annotation (experiment(StopTime=10, Tolerance=1e-006));
end PlantWithSampleHold;
组装后,我们最终的系统看起来如下:
如果我们对此系统仿真5秒钟,我们可以比较传感器返回的信号与惯性元件的实际速度:
这些结果与我们此前在对取样保持方法的讨论里的相一致。
间隔测量¶
现在让我们转而关注间隔测量方法。同样,我们会从Sensor
模型扩展创建出一个可重用的组件模型。这次,传感器实现将使用齿间的时间来估算速度:
within ModelicaByExample.Components.SpeedMeasurement.Components;
model IntervalMeasure
"Estimate speed by measuring interval between encoder teeth"
extends Interfaces.SpeedSensor;
parameter Integer teeth;
Real next_phi, prev_phi;
Real last_time;
protected
parameter Modelica.SIunits.Angle tooth_angle=2*Modelica.Constants.pi/teeth;
initial equation
next_phi = flange.phi+tooth_angle;
prev_phi = flange.phi-tooth_angle;
last_time = time;
equation
when {flange.phi>=pre(next_phi),flange.phi<=pre(prev_phi)} then
w = tooth_angle/(time-pre(last_time));
next_phi = flange.phi+tooth_angle;
prev_phi = flange.phi-tooth_angle;
last_time = time;
end when;
end IntervalMeasure;
向受控对象模型添加上述传感器很容易。只要创建以下的Modelica模型:
within ModelicaByExample.Components.SpeedMeasurement.Examples;
model PlantWithIntervalMeasure
"Comparison between ideal and an interval measuring sensor"
extends Plant;
Components.IntervalMeasure intervalMeasure(teeth=200)
annotation (Placement(transformation(
extent={{-10,-10},{10,10}}, rotation=90,
origin={20,30})));
equation
connect(intervalMeasure.flange, inertia1.flange_b) annotation (Line(
points={{20,20},{20,0},{10,0}}, color={0,0,0},
smooth=Smooth.None));
annotation (experiment(StopTime=10, Tolerance=1e-006));
end PlantWithIntervalMeasure;
组装后,我们的系统看起来如下:
对上述系统进行仿真,我们得到估测速度的如下结果:
正如我们此前在对间隔测量方法中的讨论所看到的一样,估测信号的质量随着齿数减少会严重降低。上图使用的传感器每圈有200齿。如果我们绘制轴的转角以及与其相邻的齿角度,我们会看到,轴在不触发测量的前提下不能移动很远:
另一方面,如果将每圈的齿数降到20,我们会得到以下的结果:
绘制轴的转角以及与其相邻的齿角度,我们会看到测量触发的次数变得更少了。其结果是测量的准确度大幅度降低:
上述结果与此前对间隔测量的讨论内的结果相一致。因此,我们同样可以验证这些面向组件传感器实现的正确性。
脉冲计数器¶
最后是脉冲计数方法。同样,我们可将上述估测方法展现为扩展自Sensor
模型的可重用组件。
within ModelicaByExample.Components.SpeedMeasurement.Components;
model PulseCounter "Compute speed using pulse counting"
extends Interfaces.SpeedSensor;
parameter Modelica.SIunits.Time sample_time;
parameter Integer teeth;
Modelica.SIunits.Angle next_phi, prev_phi;
Integer count;
protected
parameter Modelica.SIunits.Angle tooth_angle=2*Modelica.Constants.pi/teeth;
initial equation
next_phi = flange.phi+tooth_angle;
prev_phi = flange.phi-tooth_angle;
count = 0;
algorithm
when {flange.phi>=pre(next_phi), flange.phi<=pre(prev_phi)} then
next_phi := flange.phi + tooth_angle;
prev_phi := flange.phi - tooth_angle;
count := pre(count) + 1;
end when;
when sample(0,sample_time) then
w := pre(count)*tooth_angle/sample_time;
count := 0 "Another equation for count?";
end when;
end PulseCounter;
然后将其添加到我们的Plant
总模型:
within ModelicaByExample.Components.SpeedMeasurement.Examples;
model PlantWithPulseCounter
"Comparison between ideal and pulse counting sensor"
extends Plant;
Components.PulseCounter pulseCounter(sample_time=0.125, teeth=200)
annotation (Placement(transformation(
extent={{-10,-10},{10,10}}, rotation=90,
origin={20,30})));
equation
connect(pulseCounter.flange, inertia1.flange_b) annotation (Line(
points={{20,20},{20,0},{10,0}}, color={0,0,0},
smooth=Smooth.None));
annotation (experiment(StopTime=10, Tolerance=1e-006));
end PlantWithPulseCounter;
生成的系统显示如下:
对上述系统进行仿真,我们看到结果与此前对脉冲计数的讨论内的结果相一致: