Simulin金宝appk上的Guy

金宝appSimulink &基于模型的设计

为什么你不应该打破一个连续的代数循环与内存块

我见过许多用户在求解代数循环时遇到麻烦,所以这周我想解释为什么你永远不应该打破一个连续代数循环与一个内存块

这个问题

假设我有一个带有控制循环的简单模型:

简单示例Simulink模型金宝app

如果植物模型是直接馈通的,这将导致一个代数循环。虽然Simu金宝applink在大多数情况下可以求解代数循环,但它通常会降低模拟速度,当求解无法收敛时,可能会导致如下错误:

代数循环误差

用内存块打破循环

为了打破代数循环,需要在循环中插入一个非直接馈通块。大多数用户想到的第一件事是单位延迟或内存块。

如果代数循环中的块具有离散的采样时间,插入一个单位延迟通常是最好的解决方案。当然,这将改变系统的动态,这是您需要评估的内容,看看这是否适合您的应用程序。

如果循环中的块有连续的采样时间,许多用户尝试插入内存块。内存块在某种意义上类似于单元延迟块,它将输入延迟一个时间步长,但是它使用可变步长信号。让我们看看它对我们的模型有什么作用。

使用内存打破代数循环

至少,现在模型模拟完成了,我们可以看看结果:

代数循环打破使用内存-输出

然而,在模拟模型时,我们很快注意到它的模拟速度非常慢。如果我从模型中记录数据,我可以看到,模拟这个模型需要超过500,000个步骤,只有两秒钟!

步骤数

如果我们绘制可变步长求解器所采取的步骤,我们可以看到,在输入步长后,求解器开始采取大约1e-6秒的步长,并卡在那里。

步长

为什么会这样?这是因为内存块的输出不是连续的,它正在驱动一个具有连续状态的块,即State-Space块。每次内存块的输出改变时,求解器都需要重置,强制执行我们观察到的小步长。我们知道这种情况是有问题的,我们有一个Model Advisor检查它:检查驱动衍生端口的非连续信号

Model Advisor检查

解决方案:使用传递函数块打破循环

正如Model Advisor所建议的,打破这个代数循环的推荐方法是使用连续块。我更喜欢一阶反应传递函数。像内存块一样,这将在系统中引入一个新的动态。诀窍是使传递函数的时间常数足够小,不会显著影响系统的动态。在这种情况下,我使用1e-6。

使用传递函数打破循环

通过这种改变,模型给出了类似的结果,但模拟几乎立即完成,只需要633个时间步:

步骤数

现在轮到你了

如果您对如何处理代数循环有经验或建议,请留下这里的评论

***重要更新

在发表这篇文章后,一些用户联系我,提到一些Simulink演示使用内存块来打破代数循环。金宝app因此,我决定添加这个更新来强调这样一个事实,即只有当循环是连续的时,用内存块打破代数循环才有问题。让我们看看其中的几个例子,并解释为什么,因为循环不是连续的,所以可以用内存块来打破它们。

sldemo_clutch:在此模型中,离合器逻辑采用如下模式:

sldemo_clutch

您可以注意到,我启用了端口数据类型和采样时间显示,以突出显示此循环采用固定的小步骤采样时间,并且所涉及的信号的数据类型是布尔型。该子系统实现了一种离散组合逻辑,根据两个输入和之前的状态来决定离合器是否应该锁定。由于循环是离散的,内存块是可行的方法。

sldemo_bounce:在这个模型中,我们可以看到一个代数循环被一个Memory块打破:

sldemo_bounce

乍一看,这个循环有一个连续的采样时间,并且是双数据类型。为什么我不认为它是连续的呢?因为循环是活动的。让我们看看这里的逻辑。首先,我们需要注意的是,Integrator被配置为当x达到饱和时重置dx/dt:

sldemo_bounce配置

一旦积分器进入饱和,我们想要施加一个新的速度,这个速度是它进入饱和时速度的80%,但是方向相反,让它脱离饱和。这意味着循环的输出不会被积分器连续使用。它只用于一个时间步骤,在一个不连续,当进入饱和触发过零事件。

我希望这些澄清能让你更清楚,当我建议用传递函数打破代数循环时,我说的是连续的代数循环,其中(如果使用了内存块)内存块的输出将驱动一个派生端口,可以通过上面提到的Model Advisor检查检测到。

|

评论

如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。