欢迎光临散文网 会员登陆 & 注册

为什么永远不要用 Memory 块打破连续代数循环

2022-09-24 10:19 作者:__牛油果__  | 我要投稿

我看到很多用户在解决代数循环时遇到了麻烦,所以这周我想解释为什么你永远不应该用一个Memory 块来打破一个连续的代数循环。

问题

假设我有一个带有控制回路的简单模型:

如果工厂模型是直接馈通,这将导致代数环。虽然 Simulink 在大多数情况下都可以求解代数环,但它通常会减慢仿真速度,并且当求解无法收敛时,可能会导致如下错误:



用内存块打破循环

要打破代数循环,您需要在循环中插入一个非直接馈通块。大多数用户首先想到的是单元延迟或内存块。

如果代数循环中的模块具有离散的采样时间,则插入 Unit Delay 通常是最佳解决方案。当然,这会改变系统的动态,这是您需要评估的,看看这是否适合您的应用程序。

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

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


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


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


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


解决方案:使用 Transfer Function 模块中断循环

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


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


参考文献:

https://blogs.mathworks.com/simulink/2015/07/18/why-you-should-never-break-an-algebraic-loop-with-with-a-memory-block/











为什么永远不要用 Memory 块打破连续代数循环的评论 (共 条)

分享到微博请遵守国家法律