MATLAB Simulink 中的过零检测与代数环

本次教程基于 MATLAB R2020a

1 一般定义

过零检测指的是在交流系统中,当波形从正半周向负半周转换时,经过零位时,系统作出的检测。可作开关电路或者频率检测。

2 MATLAB中的过零检测

当SIMULINK仿真一个动态系统的时候,其在每一个时间步使用过零检测技术来检测系统状态变量的间断点。如果检测到不连续的点(前后两个采样点的值变化大),则找到发生不连续的精确时间点,并且在该时间点前后增加附加的时间步(缩小采样步长)

即:可变步长求解器可动态调整时间步大小,使其在某个变量缓慢变化时增加,在该变量迅速变化时减小。此行为使求解器在不连续点的附近执行许多小的时间步,因为该变量在此区域中迅速变化。这可以提高精确性,但可能会导致过多的仿真时间。

作用: Simulink使用过零检测技术来精确定位不连续点,以免仿真时步长过小导致仿真时间太长,一般情况下能够提高仿真速度,但有可能使得仿真到达规定时间长度之前就停止。当采用变步长解算方法仿真时,如果遇到步长自动变得很小导致仿真时间很长或基本没有进度,可以考虑勾选开启过零检测功能。

一句话概括: Simulink® 使用一种称为过零检测的技术来准确定位不连续性,无需借助于过小的时间步。通常这种方法可以缩短仿真运行时间,但它可能会导致某些仿真在预期完成时间之前停止。

——Mathworks 中国

详细可参考:https://ww2.mathworks.cn/help/simulink/ug/zero-crossing-detection.html

2.1 Simulink中过零检测的工作原理

一个模块能够通过Simulink注册一些列的过零变量,每一份变量就是一个状态变量(含有不连续点)的函数。当相应的不连续发生之后,过零函数从正值或负值传递零值。每一个仿真步结束时,Simulink通过调用每一个注册了过零变量的模块来更新变量。然后Simulink检测是否有变量的符号发生改变(相对于上一仿真时间点的结果),如果有改变就说明当前时间步有不连续发生。如果检测到零点, Simulink 就会在每一个发生符号改变的变量的前一时刻值和当前值之间插入新值以评估过零点的个数,然后逐步增加内插点数目并使其值依次越过每一个过零点

2.2 代数环

详细请参考:https://ww2.mathworks.cn/help/simulink/ug/algebraic-loops.html

在数字计算中,输入信号决定输出信号,同时输出信号也决定输入信号,由于数字计算的时序性,导致没有输出信号无法计算输入信号,没有输入信号又反过来无法计算输出信号,形成一个死锁(deadlock)或死循环,这就是代数环。

在 Simulink® 模型中,当存在信号环并且信号环中只存在直接馈通模块时,将出现代数环直接馈通表示 Simulink 需要模块输入信号的值来计算当前时间步的输出。这种信号循环会在同一时间步中产生模块输出和输入的循环依存关系。这会导致一个需要在每个时间步求解的代数方程,从而增加仿真的计算成本。

—— Mathworks 中国

简单地说,代数环其实就是一个输入信号包含输出信号,同时输出信号也包含输入信号的特殊反馈回路。在Simulink 中,这是由于直通模块(无延时的模块)的原因造成的,Simulink 中大部分的模块都是直通模块,因此很容易形成代数环。在整个回路中,只包含直通模块就会形成代数环,反馈回路有延时模块就会消除代数环。

示例:

MATLAB Simulink 中的过零检测与代数环_第1张图片

上图是代数环的一个示例。Sum 模块是一个代数变量 x a xa xa ,该变量必须等于第一个输入 u u u 减去 x a xa xa(例如 x a = u – x a xa = u – xa xa=uxa)。

此简单循环的解为 x a = u / 2 xa = u/2 xa=u/2

2.3 展示过零检测实例1——双积分器单弹球系统

在 MATLAB 命令行里输入:

>> example_bounce_two_integrators

出现如下:

在这里插入图片描述

点击下划线上的内容,系统打开文件如下,这是一个球在平面上弹跳的仿真:

MATLAB Simulink 中的过零检测与代数环_第2张图片

我们可以看到:它使用两个单个积分器来计算仿真过程中球的垂直速度和位置。

关于积分器:

我们双击积分器出现下图

  1. 复位

    在这里可以设置外部复位为none,rising,falling,either或者level。复位就是将积分器清零,选择none,将永远不对积分器清零,rising则表示在上升沿触发时,清零积分器。

    MATLAB Simulink 中的过零检测与代数环_第3张图片

  2. 积分器初始值

    积分器积分时都从一个初始值开始。可以选择内部设置初始值(internal),也可以选择外部设置。一般来说外部设置方式更为方便。

    MATLAB Simulink 中的过零检测与代数环_第4张图片

  3. 积分器限幅

    在这里你可以设置你的积分器输出的上下限,使得你的积分器输出不会超过该值。

    MATLAB Simulink 中的过零检测与代数环_第5张图片

  4. 饱和状态

    这个端口用以提供输出饱和信息,0表示输出没有达到饱和值,1表示输出已经达到饱和值,用该输出口从0~1的跳变可作为积分器的复位信号.

    MATLAB Simulink 中的过零检测与代数环_第6张图片

  5. 使能过零检测 (Enable zero-crossing detection)

  6. 状态端口

    state port的输出与output port的输出相同,但是在复位时,state port的输出要比output port的输出要早,因此当要采用积分器的输出来进行复位时,就可以采用状态口的输出作为复位信号以避免代数环。

    MATLAB Simulink 中的过零检测与代数环_第7张图片

则我们回到原来那幅图:

MATLAB Simulink 中的过零检测与代数环_第8张图片

  • 观察系统模块构建:

    1. Velocity 积分模块初始速度为15( x 0 x_0 x0

    2. 恢复系数(Coefficient of Restitution):

      恢复系数(e)是碰撞前后两物体沿接触处法线方向上的分离速度与接近速度之比,只与碰撞物体的材料有关。弹性碰撞时e=1;完全非弹性碰撞时e=0。

    3. 关于 Initial value,详情查看下面官方描述

      https://ww2.mathworks.cn/help/simulink/slref/ic.html

    4. 则我们可以推出,第一个积分器初始值为15,表示小球以15m/s的速度上抛,后面落到地面每次当距离地面为0的时候以相反的速度方向,即-0.8的恢复系数向上弹起,初始位置为距离地面十米,重力加速度的值为9.81,方向向下

  • 观察仿真结果:

    点击仿真,我们看到如下图表

    MATLAB Simulink 中的过零检测与代数环_第9张图片

    仔细检查仿真的最后一部分,您将看到速度略高于零。

    将仿真 Stop time 更改为 25 秒,然后对模型进行仿真。由于 Compare To Zero 和 Position 模块连续发生过多的过零事件,仿真将停止并显示错误。

    MATLAB Simulink 中的过零检测与代数环_第10张图片

    虽然可以通过调整 Model Configuration Parameters > Solver > Number of consecutive zero crossings 参数来增加此限制,但进行此更改后仍不能使仿真持续 25 秒。

    将模型配置参数的 Solver 窗格中的 Solver details > Zero-crossing options > Algorithm 参数更改为 Adaptive,并再次仿真该模型 25 秒。

MATLAB Simulink 中的过零检测与代数环_第11张图片

放大仿真的最后 5 秒,您可以看到结果更完整,更接近弹球动态的预期解析解。您看到的震颤量是系统状态接近零时的效果,这在数值仿真的预期之内。

MATLAB Simulink 中的过零检测与代数环_第12张图片

为何会出现上面错误?仿真器如何错过过零事件?

小球与地面发生碰撞的时候,它的位置会发生急剧的变化。不连续常常会导致动态系统的显著变化,因此对不连续点进行精确的仿真非常重要,否则会导致仿真得到错误的系统行为。

到了后面,小球会与地面发生震颤,如果不能合理选择过零点时间,则会检测不到零点导致仿真结果错误。

  • 弹球的仿真显示了有关不连续性的高频率波动(震颤)可能会导致仿真过早停止。

  • 如果求解器误差容限太大,求解器还可能会完全错过过零点。这可能是因为过零检测方法会检查信号值在主时间步之后是否发生变化。符号变化指示出现过零,然后过零算法将搜索精确的过零时间。但是,如果某个时间步内发生过零,但该时间步开始和结尾的值没有指示符号变化,则求解器将越过过零而不检测它。

  • 下图显示过零的信号。在第一个实例中,积分器越过该事件,因为符号在时间步之间没有变化。在第二实例中,求解器检测到符号变化,因此检测过零事件。

    MATLAB Simulink 中的过零检测与代数环_第13张图片

如何避免过多过零错误?

  1. 增加允许的过零数量

    增加 Configuration Parameters 对话框中 Solver 窗格上 Number of consecutive zero crossings 选项的值。这可能会给您的模型提供足够多的时间来解决过零情况。

  2. 放宽 Signal threshold

    在 Configuration Parameters 对话框的 Solver 窗格上,从 Algorithm 下拉列表中选择 Adaptive,并增加 Signal threshold 选项的值。求解器需要较少的时间来准确定位过零点。这可以缩短仿真时间,并消除过多的连续过零错误数。不过,放宽 Signal threshold 可能会降低精度。

  3. 使用 Adaptive 算法

    在 Configuration Parameters 对话框的 Solver 窗格上,从 Algorithm 下拉列表中选择 Adaptive。此算法会动态调整过零阈值,这可提高准确性,并减少检测到的连续过零点数。借助该算法,您可以同时指定 Time toleranceSignal threshold

  4. 对特定模块禁用过零检测

    清除模块参数对话框上的 Enable zero-crossing detection 复选框。在 Configuration Parameters 对话框的 Solver 窗格上,从 Zero-crossing control 下拉列表中选择 Use local settings

    在本地禁用过零检测可以防止特定模块由于出现过多连续过零点而停止仿真。所有其他模块将继续受益于过零检测所提供的更高准确性。

  5. 对整个模型禁用过零检测

    在 Configuration Parameters 对话框的 Solver 窗格上,从 Zero-crossing control 下拉列表中选择 Disable all。这可防止在您模型中的任意位置检测到过零点。结果是您的模型将无法再受益于过零检测所提供的更高准确性。

  6. 如果使用 ode15s 求解器,请考虑调整数值微分公式的阶次

    在 Configuration Parameters 对话框的 Solver 窗格上,从 Maximum order 下拉列表中选择一个值。有关详细信息,请参阅 Maximum order。

  7. 减小最大步长大小

    在 Configuration Parameters 对话框的 Solver 窗格上,为 Max step size 选项输入一个值。求解器可以采用足够小的步长来解决过零情况。但是,减小步长大小可能会增加仿真时间,在使用自适应算法时很少有必要这么做。

2.4 展示过零检测实例2——双弹球系统

同理,详细可参考:https://ww2.mathworks.cn/help/simulink/slref/double-bouncing-ball-use-of-adaptive-zero-crossing-location.html

你可能感兴趣的:(MATLAB,Simulink,学习笔记,simulink,matlab)