本页对应的英文页面已更新,但尚未翻译。 若要查看最新内容,请点击此处访问英文页面。

过零检测

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

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

Simulink 为此使用两种算法:非自适应算法和自适应算法。有关这些方法的信息,请参阅Zero-Crossing Algorithms

展示过多过零检测的影响

此示例提供三个说明过零行为的模型:example_bounce_two_integratorsexample_doublebounceexample_bounce

example_bounce_two_integrators 模型演示了在不使用自适应算法的情况下,过多的过零点如何导致仿真在预期完成时间之前停止。

example_bounce 模型使用的模型设计优于 example_bounce_two_integrators

example_doublebounce 模型说明了自适应算法如何使用两个不同的过零要求成功解算复杂的系统。

example_bounce_two_integrators 模型为例。它使用两个单个积分器来计算仿真过程中球的垂直速度和位置。

  1. 通过在命令行运行 open_system('example_bounce_two_integrators') 打开模型。

  2. 出现模块图后,将模型配置参数的 Solver 窗格中的 Solver details > Zero-crossing options > Algorithm 参数设置为 Nonadaptive。将模型的停止时间设置为 20 秒。您可以在 Simulink 工具条或模型配置参数的 Solver 窗格中更改此设置。

  3. 对模型进行仿真。

现在,您可以查看和分析仿真结果。

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

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

Simulink will stop the simulation of model 'example_bounce_two_integrators' because the 2 zero crossing signal(s) identified below caused 1000 consecutive zero crossing events in time interval between 20.357636989536076 and 20.357636990631594.
 --------------------------------------------------------------------------------
Number of consecutive zero-crossings : 1000
           Zero-crossing signal name : RelopInput
                          Block type : RelationalOperator
                          Block path : 'example_bounce_two_integrators/Compare To Zero/Compare'
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Number of consecutive zero-crossings : 500
           Zero-crossing signal name : IntgLoLimit
                          Block type : Integrator
                          Block path : 'example_bounce_two_integrators/Position'
--------------------------------------------------------------------------------
 

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

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

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

example_bounce 模型使用 Second-Order Integrator 模块对弹球的动态建模。从求解器性能方面来说,这是首选的球动态二重积分建模方法。要比较 example_bounce_two_integratorsexample_bounce 的求解器性能,请尝试在两个模型上运行 Solver Profiler。有关两种模型的详细比较,请参阅弹球的仿真

有关自适应和非自适应过零检测算法的并排比较,请参阅Double Bouncing Ball: Use of Adaptive Zero-Crossing Location

防止过多过零

可以使用下表帮助您防止模型中出现过多过零错误。

更改类型更改过程优势

增加允许的过零数量

增加 Configuration Parameters 对话框中 Solver 窗格上 Number of consecutive zero crossings 选项的值。

这可能会给您的模型提供足够多的时间来解决过零情况。

放宽 Signal threshold

在 Configuration Parameters 对话框的 Solver 窗格上,从 Algorithm 下拉列表中选择 Adaptive,并增加 Signal threshold 选项的值。

求解器需要较少的时间来准确定位过零点。这可以缩短仿真时间,并消除过多的连续过零错误数。不过,放宽 Signal threshold 可能会降低精度。

使用 Adaptive 算法

在 Configuration Parameters 对话框的 Solver 窗格上,从 Algorithm 下拉列表中选择 Adaptive

此算法会动态调整过零阈值,这可提高准确性,并减少检测到的连续过零点数。借助该算法,您可以同时指定 Time toleranceSignal threshold

对特定模块禁用过零检测

  1. 清除模块参数对话框上的 Enable zero-crossing detection 复选框。

  2. 在 Configuration Parameters 对话框的 Solver 窗格上,从 Zero-crossing control 下拉列表中选择 Use local settings

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

对整个模型禁用过零检测

在 Configuration Parameters 对话框的 Solver 窗格上,从 Zero-crossing control 下拉列表中选择 Disable all

这可防止在您模型中的任意位置检测到过零点。结果是您的模型将无法再受益于过零检测所提供的更高准确性。

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

在 Configuration Parameters 对话框的 Solver 窗格上,从 Maximum order 下拉列表中选择一个值。

有关详细信息,请参阅 Maximum order

减小最大步长大小

在 Configuration Parameters 对话框的 Solver 窗格上,为 Max step size 选项输入一个值。

求解器可以采用足够小的步长来解决过零情况。但是,减小步长大小可能会增加仿真时间,在使用自适应算法时很少有必要这么做。

仿真器如何错过过零事件

弹球的仿真Double Bouncing Ball: Use of Adaptive Zero-Crossing Location中的弹球和双弹球模型显示了有关不连续性的高频率波动(震颤)可能会导致仿真过早停止。

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

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

以弹球模型的双积分器实现为例。

使用 Solver Profiler 对仿真的最后 0.5 秒进行探查显示,仿真在 Compare To Zero 模块检测到 44 个过零事件,在 Position 模块的输出端检测到 22 个事件。

Relative tolerance 参数的值增加到 1e-2,而不是默认的 1e-3。您可以在 Configuration Parameters 对话框的 Solver 窗格的 Solver Details 部分更改此参数,或使用 set_paramRelTol 指定为 '1e-2'

用求解器的新相对容差对仿真的最后 0.5 秒进行探查,结果表明,它仅在 Compare To Zero 模块上检测到 24 个过零事件,在 Position 模块的输出端检测到 12 个事件。

模块中的过零检测

模块可以记录一系列过零变量,其中每个变量都是关于可能出现不连续点的状态变量的函数。当出现不连续点时,过零函数会发生由正值或负值穿过零值的相应情况。记录的过零变量将在每个仿真步的末尾更新,符号有变化的任何变量都将视为出现了过零事件。

如果检测到任何过零点,Simulink 软件会在符号有变化的每个变量的上一个值和当前值之间进行插值,以估计过零(即不连续点)时间。

注意

过零检测算法只能包含 double 数据类型的信号的过零事件。

记录过零点的模块

下表列出了记录过零点的模块,并解释了模块如何使用过零点。

模块过零检测次数

Abs

一个:用于检测输入信号在上升或下降方向上过零的情况。

Backlash

两个,一个用于检测达到上阈值的情况,一个用于检测达到下阈值的情况。

Compare To Constant

一个:用于检测信号等于常量的情况。

Compare To Zero

一个:用于检测信号等于零的情况。

Dead Zone

两个:一个用于检测进入死区(输入信号减去下限)的情况,一个用于检测退出死区(输入信号减去上限)的情况。

Enable

一个:如果 Enable 端口位于 Subsystem 模块内,它会提供过零检测功能。有关详细信息,请参阅使用使能子系统

From File

一个:用于检测输入信号在上升或下降方向上出现不连续点的情况。

From Workspace

一个:用于检测输入信号在上升或下降方向上出现不连续点的情况。

Hit Crossing

一个或两个。如果没有任何输出端口,则只存在一个过零点,用于检测输入信号达到阈值的情况。如果有一个输出端口,将使用第二个过零点以便将输出从 1 恢复为 0,从而创建类似于脉冲的输出。

If

一个:用于检测满足 If 条件的情况。

Integrator

如果存在重置端口,则检测发生重置的情况。

如果输出是有限的,则存在三个过零点:一个用于检测达到饱和上限的情况,一个用于检测达到饱和下限的情况,另一个用于检测不再处于饱和状态的情况。

MinMax

一个:对于输出向量的每个元素,用于检测输入信号是新的最小值或最大值的情况。

Relational Operator

一个:用于检测满足指定关系的情况。

Relay

一个:如果中继处于关闭状态,则检测接通点。如果中继处于打开状态,则检测断开点。

Saturation

两个,一个用于检测达到或离开上限的情况,一个用于检测达到或离开下限的情况。

Second-Order Integrator

五个,两个用于检测达到状态 x 上限或下限的情况,两个用于检测达到状态 dx/dt 上限或下限的情况,一个用于检测离开饱和状态的情况。

Sign

一个:用于检测输入跨越零点的情况。

Signal Editor

一个:用于检测输入信号在上升或下降方向上出现不连续点的情况。

Step

一个:用于检测步长时间。

Switch

一个:用于检测发生开关条件的情况。

Switch Case

一个:用于检测满足 case 条件的情况。

Trigger

一个:如果 Triggered 端口位于 Subsystem 模块内,它会提供过零检测功能。有关详细信息,请参阅使用触发子系统

Enabled and Triggered Subsystem

两个,一个用于使能端口,一个用于触发端口。有关详细信息,请参阅:使用使能触发子系统

注意

过零检测还适用于使用连续时间模式的 Stateflow® 图。有关详细信息,请参阅 Configure a Stateflow Chart for Continuous-Time Simulation (Stateflow)

实现示例:Saturation 模块

Saturation 模块是注册了过零的 Simulink 模块的一个示例。过零检测可以在 Saturation 模块中标识以下状态事件:

  • 输入信号达到上限。

  • 输入信号离开上限。

  • 输入信号达到下限。

  • 输入信号离开下限。

定义自己的状态事件的 Simulink 模块被视为具有内部过零点使用 Hit Crossing 模块接收过零事件的显式通知。请参阅记录过零点的模块,获取包含过零点的模块列表。

状态事件检测取决于内部过零信号的构造。模块图无法访问此信号。对于 Saturation 模块,用于检测上限过零点的信号是 zcSignal = UpperLimit - u,其中 u 是输入信号。

过零信号具有方向特性,它可包含下列值:

  • rising - 当信号上升到零或通过零时,或信号离开零并变为正值时,将出现一个过零事件。

  • falling - 当信号下降到零或通过零时,或信号离开零并变为负值时,将出现一个过零事件。

  • either - 无论是发生上升还是下降情况,都出现过零事件。

对于 Saturation 模块的上限,过零的方向是 either。这样可以使用同一过零信号检测进入和离开饱和状态的事件。

相关主题