高级旋转组件

在上一节中,我们讨论了基本旋转组件并展示了如何构建基本组件的系统模型。在这一节中,我们将演示如何加入事件处理。我们将在模拟齿隙时使用到这个功能。此外,我们还将展示如何使用参数值来实现组件的接口。

建模齿隙

让我们从旋转齿隙元素开始对高级旋转组件模型的探索。齿隙模型的方程非常简单:

\[\begin{split}\tau = \left\{ \begin{array}{cc} c (\Delta \varphi - \frac{b}{2}) \ \ &\mathrm{if}\ \Delta \varphi>\frac{b}{2} \\ c (\Delta \varphi + \frac{b}{2}) \ \ &\mathrm{if}\ \Delta \varphi<-\frac{b}{2} \\ 0 \ \ &\mathrm{otherwise} \end{array} \right.\end{split}\]

该组件可以用Modelica描述如下:

within ModelicaByExample.Components.Rotational.Components;
model Backlash "A rotational backlash model"
  parameter Modelica.SIunits.RotationalSpringConstant c;
  parameter Modelica.SIunits.Angle b(final min=0) "Total lash";
  extends ModelicaByExample.Components.Rotational.Interfaces.Compliant;
equation
  if phi_rel>b/2 then
    tau = c*(phi_rel-b/2);
  elseif phi_rel<-b/2 then
    tau = c*(phi_rel+b/2);
  else
    tau = 0 "In the lash region";
  end if;
end Backlash;

我们可以将齿隙模型的实例加入此前的模型里。将其与弹簧及阻尼器相并联,即:

若我们使用的Modelica的继承机制,由此产生的Modelica模型会很简单:

within ModelicaByExample.Components.Rotational.Examples;
model SMD_WithBacklash "The spring-mass-damper system with backlash"
  extends SMD(inertia2(phi(fixed=true, start=0)), inertia1(phi(fixed=true, start=0), w(start=5)));
  Components.Backlash backlash(c=1000, b(displayUnit="rad") = 0.5)
    annotation (Placement(transformation(extent={{-50,-10},{-30,10}})));
equation
  connect(inertia1.flange_b, backlash.flange_a) annotation (Line(
      points={{-70,0},{-50,0}},
      color={0,0,0},
      smooth=Smooth.None));
  connect(backlash.flange_b, inertia2.flange_a) annotation (Line(
      points={{-30,0},{-10,0}},
      color={0,0,0},
      smooth=Smooth.None));
end SMD_WithBacklash;

在这种情况下,如果inertia1inertia2之间的相对角度超过0.5弧度(即我们的齿隙实例里b的值),那么齿隙元件会带来转矩。

如果对该模型进行仿真,我们就可以看到,齿隙的存在对系统的响应的影响:

../../../_images/SMD_WB.png

Another thing worth looking at (which we will delve into much more in the next topic) is the force felt by the mechanical ground element. Looking at our schematic, it is clear that the role of the mechanical ground element is to fix the angular position on one side of our system. An equation to constrain the motion (or lack of motion, in this case) of a point in the system is called a kinematic constraint.

当一个运动约束施加在系统上时,该施加约束的组件必须产生某种作用力或力矩,以此影响系统的运动。这就是所谓的反作用力或反作用转矩。

下面的图显示的反作用转矩,就是该机械地面元件为了固定角位置所必须施加给系统的:

../../../_images/SMD_WB_RT.png

地面扭矩与反作用扭矩

正如我们在前面的例子中所看到的,机械地面元件必须对系统施加反作用转矩来约束其运动。在本节中,我们将稍进一步研究这个效应。

为了演示运动学约束的某些复杂性,我们需要创建一个机械齿轮模型。在这个模型中,我们将忽略齿轮元件的惯量、齿轮间的效率损失以及可能在齿轮齿之间存在的任何齿隙。回想一下我们在本章前面对进一步研究讨论内容,我们提到的组件模型应侧重于单个的物理效应。同样的原则也适用于这里。惯性、摩擦和齿隙都可以建模成单独的效应(正如我们在本章所看到的)。我们没有必要所有效应都放入齿轮模型里。相反,我们将只专注于齿轮输入速度与输出速度间的关系。

在典型的系统动力学类里,描述齿轮行为的方程推导如下。首先,我们必须理解,该齿轮引入了输入速度与输出速度间的关系,即:

\[\omega_a = R \omega_b\]

其中\(R\)是齿轮比。记得我们假设了齿轮效率为1。这意味着齿轮的输入功率必须等于输出功率。这可以在数学上表示为:

\[\tau_a \omega_a + \tau_b \omega_b = 0\]

请注意,我们在这使用了Modelica的正负号约定。因此,守恒量的流为正意味着其正在流入组件内。在这种情况下,\(\tau_a \omega_a\)是从flange_a流入齿轮的机械功率。而\(\tau_b \omega_b\)则从flange_b流出齿轮的机械功率。因此,两者的总和必须为零。因为,我们的齿轮模型不包括齿轮元件的惯性。其结果就是齿轮模型内不可能储存能量或动力。

鉴于这两个事实,我们可以将速度关系代入到功率关系。由此可以得到:

\[\tau_a R \omega_b + \tau_b \omega_b = 0\]

这让我们从方程消去了\(\omega_b\)。重新组织方程我们可以得到:

\[\tau_b = -R \tau_a\]

这样的推导对大多数工程师看起来可能会很熟悉。但是,一定要意识到这里还差了些什么。更具体而言,推理的一些隐含假定并不一定合理。

要理解这个问题,让我们先考虑欧拉第二定律:

\[J \ddot{\varphi} = \sum_i \tau_i\]

换言之,施加在物体上扭矩的总和应等于新累积的角动量。回想我们的齿轮模型并不包括齿轮元件的惯性。因此,模型无法以存储能量或角动量。在这种情况下,先前的方程简化为:

\[\sum_i \tau_i = 0\]

我们的齿轮只有两个外部扭矩\(\tau_a\)\(\tau_b\)。应用之前推导出的关系,我们知道其总和为:

\[\tau_a + \tau_b = \tau_a - R \tau_a = \tau_a (1-R) = 0\]

这个方程意味着对任何不等于1.0的齿轮比\(R\)flange_a上转矩(以及由此推出转矩flange_b也)必须为零。但是,若我们的齿轮能提供齿轮功能的话,这就不可能是正确的。

为了显示上述数学关系向我们展示了系统的一种怎样的物理特性,我们可以观察从下列等式。该等式更清楚地表明了系统的属性。

\[\tau_a - R \tau_a = 0\]

第一项\(\tau_a\),是从flange_a进入齿轮的扭矩。第二项\(\tau_b\),是从flange_b进入齿轮的扭矩。这个等式告诉我们,这两个扭矩的总和绝不会为零(对于\(R \neq 1\))。我们看起来在数学上证明了\(\tau_a=0\)。但实际上,我们实际上证明了公式里并不平衡。这种不平衡由于我们在列式中忘记一些东西。这里缺少了反作用扭矩

如果你还不熟悉这个问题,你可能会感到困惑。这个反作用扭矩从何而来?毕竟,我们对齿轮只有两个机械连接。而我们也把这两个点的扭矩表示了出来。但一直以来,这里有一个隐含的假设,即齿轮的外壳与地面相连。在现实中,一个齿轮有三个机械连接。第三个连接是在齿轮的外壳与齿轮安装的安装位置之间。如果壳体被连接到机械地面,那么目前为止我们的方程是正确的。因为我们可以用如下方式描述(接地)齿轮的行为:

within ModelicaByExample.Components.Rotational.Components;
model GroundedGear "An ideal non-reversing gear with grounded housing"
  parameter Real ratio "Ratio of phi_a/phi_b";
  extends Interfaces.TwoFlange;
equation
  ratio*flange_a.tau + flange_b.tau = 0 "No storage";
  flange_a.phi = ratio*flange_b.phi "Kinematic constraint";
  annotation (Icon(graphics={
        Rectangle(
          extent={{-100,10},{-40,-10}},
          lineColor={0,0,0},
          fillPattern=FillPattern.HorizontalCylinder,
          fillColor={192,192,192}),
        Rectangle(
          extent={{-40,20},{-20,-20}},
          lineColor={0,0,0},
          fillPattern=FillPattern.HorizontalCylinder,
          fillColor={192,192,192}),
        Rectangle(
          extent={{-40,100},{-20,20}},
          lineColor={0,0,0},
          fillPattern=FillPattern.HorizontalCylinder,
          fillColor={192,192,192}),
        Rectangle(
          extent={{-20,70},{20,50}},
          lineColor={0,0,0},
          fillPattern=FillPattern.HorizontalCylinder,
          fillColor={192,192,192}),
        Rectangle(
          extent={{20,80},{40,39}},
          lineColor={0,0,0},
          fillPattern=FillPattern.HorizontalCylinder,
          fillColor={192,192,192}),
        Rectangle(
          extent={{20,40},{40,-40}},
          lineColor={0,0,0},
          fillPattern=FillPattern.HorizontalCylinder,
          fillColor={192,192,192}),
        Rectangle(
          extent={{40,10},{100,-10}},
          lineColor={0,0,0},
          fillPattern=FillPattern.HorizontalCylinder,
          fillColor={192,192,192}),
        Text(
          extent={{-100,140},{100,100}},
          lineColor={0,0,0},
          fillColor={255,255,255},
          fillPattern=FillPattern.Solid,
          textString="ratio=%ratio"),
        Text(
          extent={{-100,-40},{100,-80}},
          lineColor={0,0,0},
          fillColor={255,255,255},
          fillPattern=FillPattern.Solid,
          textString="%name")}));
end GroundedGear;

请注意在GroundedGear模型使用的关系不再是\(\omega_a=R\omega_b\),而是\(\varphi_a=R\varphi_b\)。这实际上更为准确。因为,在组装后,齿轮的齿确实限制了两轴的角位置。此外,在一些应用里(例如步进电机)保留位置关系而非仅保留速度关系可能会非常重要。

使用GroundedGear模型,我们可以创建如下系统模型:

请注意,此系统有两种实现。第一种使用我们刚刚开发的齿轮模型。第二个将齿轮、惯量元件总成替换为单个惯量元件。这个惯量元件的值特别设定为上述总成的“有效惯量”。因此,在我们模拟这个系统时,我们看到inertia2inertia3有相同的相应:

../../../_images/SMD_GG.png

比较

正如前面所提到的,GroundedGear模型的问题在于和地面相连这一隐含假定。这种假设可能不总是合理的(例如,汽车的变速器中的齿轮通常连接到可形变的支架上)。我们希望了解连接地面与否会对系统的响应有多大的影响。因此,我们将首先创建一个不隐含连接地面的更完整的齿轮模型。然后,将其性能与连接地面的齿轮一并比较。

没有了齿轮外壳连接地面这一隐含的假设,两个轴和壳体之间的运动学关系能更完整地表示为:

\[(1-R)\varphi_h = \varphi_a - R \varphi_b\]

虽然这已经超出了本文的讨论范围,我们可以用能量守恒和动量守恒得出以下两个等式:

\[\tau_b = -R \tau_a \tau_h = -(1-R) \tau_a\]

将这些关系结合在一起,并增加机械连接器去表示壳体后,我们可以得到以下理想齿轮的Modelica模型:

within ModelicaByExample.Components.Rotational.Components;
model UngroundedGear "An ideal non-reversing gear with a free housing"
  parameter Real ratio "Ratio of phi_a/phi_b";
  extends Interfaces.TwoFlange;
  Modelica.Mechanics.Rotational.Interfaces.Flange_b housing
    "Connection for housing"
    annotation (Placement(transformation(extent={{-10,-110},{10,-90}})));
equation
  (1-ratio)*housing.phi = flange_a.phi - ratio*flange_b.phi;
  flange_b.tau = -ratio*flange_a.tau;
  housing.tau = -(1-ratio)*flange_a.tau;
end UngroundedGear;

现在,让我们一起建立是用上述三种不同机制的系统模型。在各机构齿轮、惯性、弹簧和阻尼器的参数都是相同的。唯一的区别是,我们是使用隐式连接地面齿轮、显式连接地面齿轮或不直接连接到地面上而是连接在硬支架上的齿轮。我们的系统示意图如下所示:

我们可以预期的第一件事是,隐式和显示连接地面的齿轮机构造成的响应应该是相同的。这在以下的图中得到证实:

../../../_images/SMD_GC_g.png

但此前的问题仍然存在。如果我们假定齿轮和地面隐式连接,而实际上不是的时候,这会造成多大的差异呢?问题在下图中得到清晰的解答:

../../../_images/SMD_GC_u.png

可选地面连接器

到目前为止,在对转动系统的讨论里,我们已经创建了两个不同的齿轮模型。GroundedGear 为隐式连接地面。而UngroundedGear则包括了壳体的机械连接器。其实,两个部件的方程式非常相似。其代码中有相当一部分是共同代码。正如我们之前谈到这样,这样的冗余应该避免。

在这种情况下,我们避免冗余的一种方法是组合这两个模型。这似乎是这是不切实际的。既然两模型有很不同的基本假设。更重要的是,它们的接口不同(即带有不同的连接器)。不过,我们也可以通过利用所谓的有条件声明去统一两个模型。

请考虑以下的ConfigurableGear模型:

within ModelicaByExample.Components.Rotational.Components;
model ConfigurableGear
  "An ideal non-reversing gear which can be free or grounded"
  parameter Real ratio "Ratio of phi_a/phi_b";
  parameter Boolean grounded(start=false) "Set if housing should be grounded";
  extends Interfaces.TwoFlange;
  Modelica.Mechanics.Rotational.Interfaces.Flange_b housing(phi=housing_phi,
  tau = -flange_a.tau-flange_b.tau) if not grounded "Connection for housing"
    annotation (Placement(transformation(extent={{-10,-110},{10,-90}})));
protected
  Modelica.SIunits.Angle housing_phi;
equation
  if grounded then
    housing_phi = 0;
  end if;
  (1-ratio)*housing_phi = flange_a.phi - ratio*flange_b.phi;
  flange_b.tau = -ratio*flange_a.tau;
end ConfigurableGear;

特别要注意housing声明结尾带有if no grounded。若if出现在声明的结尾,则表明该变量只会在if后的条件表达式为真时存在。所以,若grounded参数为真,模型中就不存在housing连接器。此外,housing声明包括的方程,如修改语句(即phi=housing_phi以及tau=-flange_a.tau-flange_b.tau),也会随着声明消失。

同时,equation区域中,我们看到if语句在模型连接地面时提供了一条额外的方程housing_phi=0。这是必要的。原因是变量housing_phi总是存在(即在其声明的结尾没有if)。所以该变量必须对应一条公式。

要了解更多的彻底理解是怎么回事,我们要记得一点。组件模型所需的方程数目等于所有组件内连接器的流变量数目+在模型中声明的(非参数)变量的数目。

下表总结了分别为grounded值的真假两种情况总结了上述量的关系:

grounded==true grounded==false

flow变量总数

2 3

变量数

1(housing_phi

1(housing_phi

所需方程数

3 4

声明内的方程数

0

2(housing内)

equation区域的方程数

3 2

提供的方程数

3 4

当使用条件声明时,非常重要的一点是确保在所有情况下,提供的方程数和所需方程数相等。在这里,我们只有两个条件需要考虑。而我们可以清楚地从该表中看到,两种情况下要求均满足。

下面的模型展示了我们如何将ConfigurableGear模型用在隐式、显式接地齿轮的情况:

Example using a configurable gear

而且,如我们所料,inertia1inertia4的响应相同:

../../../_images/SMD_CG.png