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 中大部分的模块都是直通模块,因此很容易形成代数环。在整个回路中,只包含直通模块就会形成代数环,反馈回路有延时模块就会消除代数环。
示例:
上图是代数环的一个示例。Sum 模块是一个代数变量 xaxaxa ,该变量必须等于第一个输入 uuu 减去 xaxaxa(例如 xa=u–xaxa = u – xaxa=u–xa)。
此简单循环的解为xa=u/2xa = u/2xa=u/2。
2.3 展示过零检测实例1——双积分器单弹球系统
在 MATLAB 命令行里输入:
>> example_bounce_two_integrators
出现如下:
点击下划线上的内容,系统打开文件如下,这是一个球在平面上弹跳的仿真:
我们可以看到:它使用两个单个积分器来计算仿真过程中球的垂直速度和位置。
关于积分器:
我们双击积分器出现下图
复位
在这里可以设置外部复位为none,rising,falling,either或者level。复位就是将积分器清零,选择none,将永远不对积分器清零,rising则表示在上升沿触发时,清零积分器。
积分器初始值
积分器积分时都从一个初始值开始。可以选择内部设置初始值(internal),也可以选择外部设置。一般来说外部设置方式更为方便。
积分器限幅
在这里你可以设置你的积分器输出的上下限,使得你的积分器输出不会超过该值。
饱和状态
这个端口用以提供输出饱和信息,0表示输出没有达到饱和值,1表示输出已经达到饱和值,用该输出口从0~1的跳变可作为积分器的复位信号.
使能过零检测 (Enable zero-crossing detection)
状态端口
state port的输出与output port的输出相同,但是在复位时,state port的输出要比output port的输出要早,因此当要采用积分器的输出来进行复位时,就可以采用状态口的输出作为复位信号以避免代数环。
则我们回到原来那幅图:
观察系统模块构建:
Velocity 积分模块初始速度为15( x0x_0x0 )
恢复系数(Coefficient of Restitution):
恢复系数(e)是碰撞前后两物体沿接触处法线方向上的分离速度与接近速度之比,只与碰撞物体的材料有关。弹性碰撞时e=1;完全非弹性碰撞时e=0。
关于 Initial value,详情查看下面官方描述
https://ww2.mathworks.cn/help/simulink/slref/ic.html
则我们可以推出,第一个积分器初始值为15,表示小球以15m/s的速度上抛,后面落到地面每次当距离地面为0的时候以相反的速度方向,即-0.8的恢复系数向上弹起,初始位置为距离地面十米,重力加速度的值为9.81,方向向下
观察仿真结果:
点击仿真,我们看到如下图表
仔细检查仿真的最后一部分,您将看到速度略高于零。
将仿真 Stop time 更改为 25 秒,然后对模型进行仿真。由于 Compare To Zero 和 Position 模块连续发生过多的过零事件,仿真将停止并显示错误。
虽然可以通过调整 Model Configuration Parameters > Solver > Number of consecutive zero crossings 参数来增加此限制,但进行此更改后仍不能使仿真持续 25 秒。
将模型配置参数的 Solver 窗格中的 Solver details > Zero-crossing options > Algorithm 参数更改为
Adaptive
,并再次仿真该模型 25 秒。
放大仿真的最后 5 秒,您可以看到结果更完整,更接近弹球动态的预期解析解。您看到的震颤量是系统状态接近零时的效果,这在数值仿真的预期之内。
为何会出现上面错误?仿真器如何错过过零事件?
小球与地面发生碰撞的时候,它的位置会发生急剧的变化。不连续常常会导致动态系统的显著变化,因此对不连续点进行精确的仿真非常重要,否则会导致仿真得到错误的系统行为。
到了后面,小球会与地面发生震颤,如果不能合理选择过零点时间,则会检测不到零点导致仿真结果错误。
弹球的仿真显示了有关不连续性的高频率波动(震颤)可能会导致仿真过早停止。
如果求解器误差容限太大,求解器还可能会完全错过过零点。这可能是因为过零检测方法会检查信号值在主时间步之后是否发生变化。符号变化指示出现过零,然后过零算法将搜索精确的过零时间。但是,如果某个时间步内发生过零,但该时间步开始和结尾的值没有指示符号变化,则求解器将越过过零而不检测它。
下图显示过零的信号。在第一个实例中,积分器越过该事件,因为符号在时间步之间没有变化。在第二实例中,求解器检测到符号变化,因此检测过零事件。
如何避免过多过零错误?
增加允许的过零数量
增加 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 tolerance 和 Signal threshold。
对特定模块禁用过零检测
清除模块参数对话框上的 Enable zero-crossing detection 复选框。在 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
选项输入一个值。求解器可以采用足够小的步长来解决过零情况。但是,减小步长大小可能会增加仿真时间,在使用自适应算法时很少有必要这么做。
2.4 展示过零检测实例2——双弹球系统
同理,详细可参考:https://ww2.mathworks.cn/help/simulink/slref/double-bouncing-ball-use-of-adaptive-zero-crossing-location.html
MATLAB Simulink 中的过零检测与代数环相关推荐
- Simulink-过零检测与代数环
过零检测 过零检测即通过Simulink为模块注册若干过零函数,当模块变化趋势剧烈时,过零函数将会发生符号变化.每个采样点仿真结束时,Simulink检测过零函数是否有符号变化,如果检测到过零点,则S ...
- matlab三角波发生器精度改为定点型,关于matlab simulink中三角波模块的问题!
问题描述: 关于matlab simulink中三角波模块的问题! 为什么我把时间参数换一下,产生的三角波会越来越乱,最后干脆不产生了? 1个回答 分类: 综合 2014-11-20 问题解答: 我来 ...
- Matlab simulink中找不到s函数
Matlab simulink中找不到s函数 问题 Error in S-function 'benchmark/Bioreactor_4/Bioreactor_4': S-Function 'asm ...
- Matlab/Simulink中信号线拉成斜线的方法
Matlab/Simulink中模块间的信号线默认为水平或竖直的连接线,将其拉成斜线的方法为:按住Shift键再用鼠标在该线处单击一下,线的两端会出现折点圆圈,拖动该折点即可将直线改为斜线,如图所示:
- MATLAB/Simulink中的S函数报错
关于MATLAB/Simulink中的S函数报错: Output returned by S-function 'xxx' in 'xxx' during flag=3 call must be a ...
- 伯德图 matlab,Matlab/Simulink中bode图的画法
在Matlab中,大多时候,我们都是用M语言,输入系统的传递函数后,用bode函数绘制bode图对系统进行频率分析,这样做,本人觉得效率远不如Simulink建模高.如何在Matlab/Simulin ...
- Matlab/Simulink中PMSM模型的反电动势系数和转矩系数
Matlab/Simulink中PMSM模型的反电动势系数和转矩系数 在PMSM仿真中常常会用到永磁磁链ψ\psiψ,但是电机的参数手册中却不会直接给出永磁磁链ψ\psiψ,给出的是反电动势系数Ke和 ...
- matlab全搜索运动估计,全零检测的部分失真搜索运动估计算法
运动估计是视频压缩中的关键技术,能够有效消除帧间的时间冗余,提高压缩比.在现有的各类运动估计方法中,块匹配算法(block-matchingalgorithm,BMA)因具有简单.实用的特点而得到广泛 ...
- matlab/simulink中代数环的问题及解决措施
一.代数环的问题 在数字计算中,输入信号决定输出信号,同时输出信号也决定输入信号,由于数字计算的时序性,导致没有输出信号无法计算输入信号,没有输入信号又反过来无法计算输出信号,形成一个死锁(deadl ...
- matlab memory 代数环,matlab/simulink中代数环的问题及解决措施
一.代数环的问题 在数字计算中,输入信号决定输出信号,同时输出信号也决定输入信号,由于数字计算的时序性,导致没有输出信号无法计算输入信号,没有输入信号又反过来无法计算输出信号,形成一个死锁(deadl ...
最新文章
- 干货丨机器学习傻瓜指南
- postgresql 数据库远程访问
- 以太坊源码linux下如何编译,以太坊教程:搭建环境、编写编译一个智能合约
- 基于VS的连连看小游戏
- 【HTML】前端性能优化之CDN和WPO的比较
- linux svn cleanup 用法,SVN命令之清理命令(clean up)的功能及使用技巧
- win8 oracle10g,win7/win8 下安装oracle10g的方法
- 生产环境几个实用的命令整理(一)
- 【Java从0到架构师】个人简历项目实战
- Android Studio - 如何更改Android SDK路径
- ESP32-SPI接口bl0942驱动
- FIT2CLOUD飞致云被权威研究机构评选为中国混合云管理软件领导者
- rxj热血江hsf湖私服_如何使用RxJ进行React性思考和动画化移动对象
- 关于STM32中的引脚重映射
- springboot启动banner图片
- IBM服务器RAID5
- Activity切换闪屏问题
- 购买Blender cloud支援今年官方开源电影Gooseberry
- tf.round(): 四舍六入五取偶
- postgresql 执行sql文件