漫谈Simulink:真假代数环

Դ未知

ߣ老铁SEO

12

2019-08-02 07:45:06

All comments and opinions expressed on Zhihu are mine alone and do not necessarily reflect those of my employers, past or present.
本文内容所有内容仅代表本人观点,和Mathworks无关

为什么要尽量避免代数环的出现?这是因为:

  • 代码生成不支持代数环
  • Simulink的仿真引擎并不能求解所有的代数环
  • 代数环的存在会影响仿真的速度

现在,我们可以继续深入的分析一下Simulink中的几类各种代数环,包括它们的成因以及解决方案。因为文中涉及到的各种Simulink的细节会非常多,所以我尽量点到为止,不会对细枝末节进行展看。有问题的话请回帖留言,我尽量解答。

Disclaimer: 本文的所有内容都是基于官方的文档, 如有冲突,以官方文档为准。本文所给出的例子,都是基于MATLAB 2015b。一些类型的代数环有可能会在新的版本中被消除。

一 、 预备知识

为了更好地说明代数环,我们先来解释几个基本概念:

Sorted Execution order:

在仿真的每一步,Simulink会依次对每个(non-virtual) 的模块进行操作,包括计算输出信号,更新状态等等。因此,每一个模块会有一个唯一对应的Sorted Execution order,即在每一步仿真的时候被执行的顺序。例如,

 

在这个vdp模型中,每个模块的右上角显示的就是它的执行顺序:最先被执行的是最右边的积分器,然后是Out1,以此类推。注意这个执行顺序包括两个数字。冒号左边的数字表示的是这些模块所处的level。在这个例子里, 所有的模块都处于level - 0.

 

Virtual and non-virtual:

在Simulink中,有的元素(包括模块和信号)是虚的(virtual), 有的是实的(non-virtual)。简单来讲,虚的东西在仿真的时候是不占内存的,它的出现只是为了提高模型的视觉效果而已。比如一个virtual subsystem, 它的作用只是把一堆模块放到它内部而已。但是,注意两点: 1. 它里面的所有的模块和外面的模块是处于同一个level的。2. virtual subsystem是没有sorted execution order的,因为它不会被执行。相反的,non-virtual的元素都是会影响到仿真的进行的。

Atomic Subsystem:

Atomic Subsystem 是一个non-virtual的subsystem. Simulink在仿真的时候,会把Atomic Subsystem当成一个单独的模块来执行。Atomic Subsystem里面的所有的子模块的和外面的模块是不在一个level上的。在仿真过程中,一旦Simulink执行到Atomic Subsystem的时候,会先依次执行这个Atomic Subsystem里面的所有的模块,然后再去执行Atomic Subsystem外面的其他模块。

Direct Feed-through:

所有的non-virtual subsystem的每个输入端口都会有一个direct feed-through的属性,它表示在当前时刻,这个模块有没有任何一个输出是依赖于这个输入端口的信号的。如果我门用一个状态空间模型来表示一个模块。那么这个模块的D矩阵如果有非零项,此模块必然为direct feed-through (请思考反之是否成立?) 如果一个环路里所有的模块都是Direct Feed-through的,那么这个环路就形成了一个代数环。


二、真的代数环

现在我们来看看各种Real Algebraic Loop。这些代数环是模型自身的结构造成的。

例 2.1 基本代数环

以上是一个最简单的例子。Gain和Sum两个模块都是Direct Feed-Through的,所以他们构成的环路必然是代数环。注意到Sum模块是被黄色填充的,而且周边是红色环绕的。这是因为这个模块被Simulink引擎当做为Algebraic Variable (这里就不展开讲了). 

这个模型在仿真的过程中,会出现错误信息或者警告信息。当然了,你可以设置仿真的参数,让Simulink不提示这些问题。但是,请注意代数环的存在会造成本文开篇所提到的三个方面的问题。


例 2.2 无解代数环

 

这个代数环是无解的,因为 x= 1, 同时 x = 2*x.

对于这样的代数环,Simulink会直接报错。要解决这个问题,只能在环路里面加入一个non-direct feedthrough的模块,例如一个延时模块,memory模块,或者一个low-pass filter (1/(s+1) 这样的传递函数)等等。这样做的副作用是会改变模型的动态。


例 2.3 多解代数环

假如我就是要引入一个代数环,并且希望通过Simulink给我求解这个代数方程。那么,你当然可以这样做(个人觉得这是比较高级的玩法,不推荐初学者采用),但是要注意这个代数方程是否一定有解,或者是否会有多个解。在例2.3中,这个代数方程是 x*x*x = x. 显然解有三个 x=0, x=1, x = -1. 如果直接运行这个模型,会发现Simulink找到的解是x=0. 假如我所期望的解是x=-1,那应该怎么做呢?

 

一个简单的办法是提供一个初值给Simulink, 让它通过这个初值来搜索。为此,你可以考虑引入IC (Initial Condition)模块,给出一个接近-1的初始信号,来让Simulink进行搜索。有关Simulink求解代数环的算法,请见 Algebraic Loops 。 



三、假的代数环

 

谈完了真的代数环,我们来看看假的代数环,或者叫人工代数环(Artificial Algebraic Loop). 之所以要这样叫,是因为这些拓扑结构在数学上看并不是代数环,但是在Simulink的执行过程中,被当成了代数环。

例 3.1 执行顺序造成的代数环

 

这个例子里面的Subsystem是atomic subsytem, 但是这里其实并没有代数环。因为积分器不是Direct Feed-through的(状态空间D矩阵为0)。但是在默认情况下Simulink确会提示存在代数环。这个成因和Simulink引擎的算法有关系,因此就不解释了。要消除这个代数环,只需要打开此子系统模块的Parameters对话框,勾上 “Minimized algebraic loop occurrences” 即可。当然了,如果没有必要用atomic subsystem的话,可以把该系统变成virtual的来消除这个代数环。

例 3.2 一个模块只能执行一次

上图中,Simulink会认为存在代数环,这是因为在每一步的仿真中,每个模块只能被执行一次。为什么这会造成问题呢?因为按照我们直观的理解,这个信号流的顺序是这样的

A -> B ->D -> B ->C

注意到B模块理论上应该出现两次。但是Simulink目前不支持这样的执行方式。所以B模块只能被执行一次,而且这一次的执行需要提供Out1和Out2两个模块的输出。这样就造成了一个人工引入的环路。解决这样的问题,最好的方法就是不要引入这样的结构。或者采用virtual subsystem.

例 3.3 Direct Feed-Through是输入端口的属性

这个模型里存在一个环路,但是这个环路不应该是代数环,因为环路里有一个积分器。但是Simulink会认为这是代数环。在这个例子里,输入端口Subsystem/In1和Subsystem/Out1之间是Direct feedthrough, 和Subsystem/Out2之间不是Direct feedthrough。 但是因为Direct Feed-Through是输入端口Subsystem/In1的属性而且是一个标量不是向量,所以它只能是true or false. 在这种情况下,它只能是true. 由此造成环路里的所有模块都是Direct feedthrough, 变成了一个人工的代数环。

四 、总结

本文给出了一些典型的代数环的例子。另外的成因还包括且不限于捆绑的信号,block reduction等等 。

本文的目的是想说明这样一个问题:遇到代数环的时候,不必先急着加delay,可以尝试着先分析一下代数环的成因,然后再采取相应的对策。

佭ϴý Ѷ Media8ý

在线客服

外链咨询

扫码加我微信

微信:juxia_com

返回顶部