基本旋转组件

在这一节中,我们将介绍如何为一维转动系统创建基本组件。我们将以此前对旋转连接器的讨论为基础,展示如何将连接器应用于定义基本旋转组件的接口。最后,我们将展示如何将这些旋转部件可以被组装成系统模型。这里的系统模型将与第一章内的以方程为基础的旋转系统模型有着相同的行为。

组件模型

在第一章中,我们严格地利用方程式(即无组件模型)去建模了机械示例。在本节中,我们将通过使用组件重新开始系统模型。要做到这一点,我们首先要定义需要的基本组件模型。这些将包括惯性、弹簧、阻尼器和机械地面的模型。

正如上一节,我们将首先通过累赘的方法定义组件模型。然后,我们将重新审视这些定义,并尝试将公共代码分解出来,以避免在组件模型里的重复。

坐标系

创建这些模型的方法与我们在传热和电气域上创建组件模型时的方法非常类似。但是,在开始建立组件模型之前,我们应该首先讨论与机械系统相关的一个复杂性:坐标系。

在机械领域,我们研究是守恒量是动量。与此前介绍了的守恒量热量和电荷不同,动量有方向性。我们在这里仅考虑一维的情况。因此,这个方向性的后果是,动量是一个带符号的量(即动量可正可负)。

考虑一个转动惯量为\(J\)的转动质量元件。如果在惯量元件的角位置由\(\varphi\)表示,则惯量的角速度\(\omega\)就定义为:

\[\omega = \dot{\varphi}\]

显然,正的\(\omega\)值将导致\(\varphi\)随着时间的推移增加。此外,惯量元件的角加速度\(\alpha\)定义为:

\[\alpha = \dot{\omega}\]

和角速度一样,我们可以看到,正的\(\alpha\)将导致角速度增加。最后,惯量元件的角动量被定义为\(J \omega\)。我们从欧拉运动定律可以知道(假设J为常数):

\[J \frac{\mathrm{d}\omega}{\mathrm{d}t} = \tau\]

显然由此关系可得,正的转矩\(\tau\)将增加存储在转动质量元件里的动量。

之所以展示所有这些关系,是为了强调与\(\varphi\)\(\omega\)\(\alpha\)以及\(\tau\)相关的符号规则。这些规则都与角位移正负的基本定义有关。\(\varphi\)增加的方向就是正速度、正加速度、正转矩的方向

转动惯量元件

我们已经讨论正负号规则以及坐标系。现在,我们就可以开始创建组件模型。首先,我们创建惯量模型:

within ModelicaByExample.Components.Rotational.VerboseApproach;
model Inertia "Rotational inertia without inheritance"
  parameter Modelica.SIunits.Inertia J;
  Modelica.Mechanics.Rotational.Interfaces.Flange_a flange_a
    annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
  Modelica.Mechanics.Rotational.Interfaces.Flange_b flange_b
    annotation (Placement(transformation(extent={{90,-10},{110,10}})));
protected
  Modelica.SIunits.Angle phi_rel;
  Modelica.SIunits.Torque tau;
  Modelica.SIunits.AngularVelocity w;
equation
  // Variables
  phi_rel = flange_a.phi-flange_b.phi;
  tau = flange_a.tau;
  w = der(flange_a.phi);

  // Conserviation of angular momentum (includes storage)
  J*der(w) = flange_a.tau + flange_b.tau;

  // Kinematic constraint (inertia is rigid)
  phi_rel = 0;
  annotation ( Icon(graphics={
          extent={{-100,90},{100,50}},

Inertia模型包括两个“法兰”,两端各一个。这些法兰的意义是可以更清楚地从Inertia模型的图标看出:

换言之,Inertia模型在每一端都有一个法兰。你可以把这个模型看作两端都有接口的轴。

现在,Inertia模型所需要表示的基本公式为:

  J*der(w) = flange_a.tau + flange_b.tau;

这表达的基本事实为,惯量元素内储存的动量增加率等于施加其上的转矩之和。回想一下,在之前对非因果连接的讨论里,我们所规定的连接器流变量(这里为flange_a.tauflange_b.tau)的符号规则:正值表示保守量的流在进入到组件模型。flange_aflange_b有相同的符号约定这一点,意味着Inertia模型是对称的(即可以在翻转后保持行为不变)。

不过,这个等式引用了内部变量w(代表\(\omega\))和tau。所以我们也需要包含这些变量的声明和定义。

弹簧模型

接下来,让我们考虑一个弹簧模型的定义:

within ModelicaByExample.Components.Rotational.VerboseApproach;
model Spring "Rotational spring without inheritance"
  parameter Modelica.SIunits.RotationalSpringConstant c;
  Modelica.Mechanics.Rotational.Interfaces.Flange_a flange_a
    annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
  Modelica.Mechanics.Rotational.Interfaces.Flange_b flange_b
    annotation (Placement(transformation(extent={{90,-10},{110,10}})));
protected
  Modelica.SIunits.Angle phi_rel;
  Modelica.SIunits.Torque tau;
equation
  // Variables
  phi_rel = flange_a.phi-flange_b.phi;
  tau = flange_a.tau;

  // No storage of angular momentum
  flange_a.tau + flange_b.tau = 0;

  // Hooke's law
  tau = c*phi_rel;
end Spring;

弹簧模型的图标如下所示:

Inertia模型一样,Spring模型有两个连接器,一端各一个。模型还定义了许多相同的内部变量。最终,弹簧的行为可以总结为如下公式:

  // Hooke's law
  tau = c*phi_rel;
end Spring;

事实上,除了上述方程和参数c以外,Spring模型的内容与Inertia模型内容大部分是一样的。

阻尼器模型

Damper模型也和Spring模型非常相似。同样,主要区别是参数(这里是d),以及一个方程:

within ModelicaByExample.Components.Rotational.VerboseApproach;
model Damper "Rotational damper without inheritance"
  parameter Modelica.SIunits.RotationalDampingConstant d;
  Modelica.Mechanics.Rotational.Interfaces.Flange_a flange_a
    annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
  Modelica.Mechanics.Rotational.Interfaces.Flange_b flange_b
    annotation (Placement(transformation(extent={{90,-10},{110,10}})));
protected
  Modelica.SIunits.Angle phi_rel;
  Modelica.SIunits.Torque tau;
equation
  // Variables
  phi_rel = flange_a.phi-flange_b.phi;
  tau = flange_a.tau;

  // No storage of angular momentum
  flange_a.tau + flange_b.tau = 0;

  // Damping relationship
  tau = d*der(phi_rel);
end Damper;

Damper模型的图标如下所示:

DRY组件模型

我们已经有了惯性元件、弹簧和阻尼器的模型。要完成此前的双弹簧质量阻尼系统唯一缺少的模型就是机械地面的模型了。但在此之前,让我们花一点时间来重新审视这些模型。我们的目标是抽取出这些模型之间的大量共同代码。和上节一样,让我们慢慢来去实践DRY(不要重复)原则。

共同代码

值得一提的是,由于Modelica的标准库拥有大量的旋转部件,几乎从一开始,标准库就要处理冗余代码的问题。不过,我们不会在这里使用Modelica标准库的partial模型。原因简单,这些模型都在设计时都考虑了许多与本节讨论不相关的其他情况。因此,这些(虽然必要的)复杂性使得上述模型不适用于教学。

但我们将从Modelica的标准库学习一点。这就是多个partial模型的必要性。这是因为,不像此前讨论的电气部件,我们的转动组件模型彼此间共享不同的代码。

一个相同点在于,所有模型均带有两个法兰连接器flange_aflange_b 。然而,虽然Inertia模型能够存储角动量,但SpringDamper模型则不能。其结果是,这些组件之间有不同的守恒方程。

让我们从所有三种模型共有的元素开始。共有元素由以下的TwoFlange模型表示:

within ModelicaByExample.Components.Rotational.Interfaces;
partial model TwoFlange
  "Definition of a partial rotational component with two flanges"

  Modelica.Mechanics.Rotational.Interfaces.Flange_a flange_a
    annotation (Placement(transformation(extent={{-110,-10},{-90,10}})));
  Modelica.Mechanics.Rotational.Interfaces.Flange_b flange_b
    annotation (Placement(transformation(extent={{90,-10},{110,10}})));
protected
  Modelica.SIunits.Angle phi_rel;
equation
  phi_rel = flange_a.phi-flange_b.phi;
end TwoFlange;

除了定义的两个法兰flange_aflange_b外,这个模型还定义了两法兰间的相对角度,即phi_rel。当然,这种模型也被标记为partial。因为模型缺少对组件行为的任何描述。

所有的三种模型都可以继承上述模型。但是,SpringDamper模型之间仍会有一些冗余的方程式。因此,我们将转而创建TwoFlange模型的一个稍为特别的版本。这个版本表示不存储动量的可压缩模型:

within ModelicaByExample.Components.Rotational.Interfaces;
partial model Compliant "A compliant rotational component"
  extends ModelicaByExample.Components.Rotational.Interfaces.TwoFlange;
protected
  Modelica.SIunits.Torque tau;
equation
  tau = flange_a.tau;
  flange_a.tau + flange_b.tau = 0
    "Conservation of angular momentum (no storage)";
end Compliant;

Compliant模型加上额外的内部变量(以代表从flange_a进入该组件然后传递到flange_b的转矩)。另外,模型也加入了方程,以表示组件不会存储任何角动量。

有了这些定义的基类,让我们快速重构各个组件模型的定义。这就可以看出继承能减少多少冗余。

转动惯量元件

凭借TwoFlanges模型,我们的Inertia模型可以简化为:

within ModelicaByExample.Components.Rotational.Components;
model Inertia "A rotational inertia model"
  parameter Modelica.SIunits.Inertia J;
  extends ModelicaByExample.Components.Rotational.Interfaces.TwoFlange;
  Modelica.SIunits.AngularVelocity w "Angular Velocity"
    annotation(Dialog(group="Initialization", showStartAttribute=true));
  Modelica.SIunits.Angle phi "Angle"
    annotation(Dialog(group="Initialization", showStartAttribute=true));
equation
  phi = flange_a.phi;
  w = der(flange_a.phi) "velocity of inertia";
  phi_rel = 0 "inertia is rigid";
  J*der(w) = flange_a.tau + flange_b.tau
    "Conservation of angular momentum with storage";
end Inertia;

弹簧模型

用相同的方式继承了Compliant模型后,Spring模型可以更紧凑地表示为:

within ModelicaByExample.Components.Rotational.Components;
model Spring "A rotational spring component"
  parameter Modelica.SIunits.RotationalSpringConstant c;
  extends ModelicaByExample.Components.Rotational.Interfaces.Compliant;
equation
  tau = c*phi_rel "Hooke's Law";
end Spring;

阻尼器模型

同样,Damper模型也类似地简化为:

within ModelicaByExample.Components.Rotational.Components;
model Damper "A rotational damper"
  parameter Modelica.SIunits.RotationalDampingConstant d;
  extends ModelicaByExample.Components.Rotational.Interfaces.Compliant;
equation
  tau = d*der(phi_rel) "Damping relationship";
end Damper;

机械地面

最后,我们可以完成双弹簧质量阻尼系统里唯一剩余的模型了。机械地面模型定义如下:

within ModelicaByExample.Components.Rotational.Components;
model Damper "A rotational damper"
  parameter Modelica.SIunits.RotationalDampingConstant d;
  extends ModelicaByExample.Components.Rotational.Interfaces.Compliant;
equation
  tau = d*der(phi_rel) "Damping relationship";
  annotation (Icon(graphics={

双弹簧质量阻尼系统

最后,我们已经得到了重建第一章内例子所需的所有部件。使用本节中定义的各个组件,我们基于组件的系统模型其Modelica代码如下:

within ModelicaByExample.Components.Rotational.Examples;
model SMD
  Components.Ground ground annotation (Placement(transformation(
        extent={{-10,-10},{10,10}},
        rotation=90,
        origin={76,0})));
  Components.Damper damper2(d=1)
    annotation (Placement(transformation(extent={{30,10},{50,30}})));
  Components.Spring spring2(c=5)
    annotation (Placement(transformation(extent={{28,-30},{48,-10}})));
  Components.Inertia inertia2(
    J=1,
    phi(fixed=true, start=1),
    w(fixed=true, start=0))
    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));
  Components.Damper damper1(d=0.2)
    annotation (Placement(transformation(extent={{-50,10},{-30,30}})));
  Components.Spring spring1(c=11)
    annotation (Placement(transformation(extent={{-50,-30},{-30,-10}})));
  Components.Inertia inertia1(
    J=0.4,
    phi(fixed=true, start=0),
    w(fixed=true, start=0))
          annotation (Placement(transformation(extent={{-90,-10},{-70,10}})));
equation
  connect(ground.flange_a, damper2.flange_b) annotation (Line(
      points={{70,0},{66,0},{66,0},{60,0},{60,20},{50,20}},
      color={0,0,0},
      smooth=Smooth.None));

  connect(ground.flange_a, spring2.flange_b) annotation (Line(
      points={{70,0},{60,0},{60,-20},{48,-20}},
      color={0,0,0},
      smooth=Smooth.None));
  connect(damper2.flange_a, inertia2.flange_b) annotation (Line(
      points={{30,20},{20,20},{20,0},{10,0}},
      color={0,0,0},
      smooth=Smooth.None));
  connect(spring2.flange_a, inertia2.flange_b) annotation (Line(
      points={{28,-20},{20,-20},{20,0},{10,0}},
      color={0,0,0},
      smooth=Smooth.None));
  connect(inertia2.flange_a, damper1.flange_b) annotation (Line(
      points={{-10,0},{-20,0},{-20,20},{-30,20}},
      color={0,0,0},
      smooth=Smooth.None));
  connect(inertia2.flange_a, spring1.flange_b) annotation (Line(
      points={{-10,0},{-20,0},{-20,-20},{-30,-20}},
      color={0,0,0},
      smooth=Smooth.None));
  connect(damper1.flange_a, inertia1.flange_b) annotation (Line(
      points={{-50,20},{-60,20},{-60,0},{-70,0}},
      color={0,0,0},
      smooth=Smooth.None));
  connect(spring1.flange_a, inertia1.flange_b) annotation (Line(
      points={{-50,-20},{-60,-20},{-60,0},{-70,0}},
      color={0,0,0},
      smooth=Smooth.None));
end SMD;

模型的简图如下所示

../../../_images/SMD.png

以此完成了我们对基本旋转组件的讨论。但在下一节高级旋转组件,我们还会进一步深入探讨旋转组件。