在昨天对热风枪工作电压与出口风温度建立三阶线性模型的时候,遇到一个奇怪的问题:同样的离散时间系统函数,在MATLAB中和Python环境中对应的单位阶跃响应结果居然不一样!一个是稳定的系统输出,另一个则是发散的系统输出。
使用MATLAB中的系统建模工具对热风枪Chirp激励和输出数据建立三阶模型,并输出该模型的离散系统传递函数:tf2。
基于Chirp信号激励下系统数据数据建模响应曲线
在MATLAB中显示 tf2 的数据。可以得到该离散时间系统函数有理多项式对应的分子和分母的系数:
在MATLAB中使用step(tf2)可以获得该系统的单位冲击响应,如下图所示,这是一个稳定的系统。
但是,如果使用上述系数a,b数值,直接调用python语音中系统IIR滤波器命令scipy.signal.lfilter,来获得该系统在单位阶跃信号下的相应,就会发现该系统的输出则会指数发散。
out = scipy.signal.lfilter(b, a, x)
上面命令中,x是取值为常量1的序列,表示系统的输入是单位阶跃信号。下图是系统的输出。
为什么同一个系统函数在MATLAB中,使用step命令可以获得稳定输出,而在python中使用lfilter,则结果发散呢?
一开始对此百思不得其解,后来想到这方面的原因就在于MATLAB中,显示系统函数信息的时候,对于多项式系数显示小数的有效位数太少了,造成系数出现微小的误差,这就会使得原本稳定的系统,变得不稳定。
在MATLAB,使用 format long命令,设置显示数字的有效位数增加。
使用tf2.Numerator, tf2.Denominator分别显示系统函数有理分式的分子和分母系数分别如下:
a = [1.000000000000000
-2.910740864813083
2.823137168435703
-0.912385540445608]
b=[0 0.000435011287573652
-0.000429964660727815]
使用上述高精度的系数,在Python中使用lfilter命令获得系统单位阶跃响应,它就是稳定的输出的。如下图所示:
由于传递函数系数的有效数字减小,这使得对应有理多项式系数发生小的改变,由此引起系统从原来稳定变到不稳定。从这个现象说明该系统具有靠近单位圆的极点,微小的移动,会使得这些极点从单位圆内,移动到单位圆外,从而使得系统变得不稳定。
在MATLAB中,使用iopzplot命令,可以绘制出离散时间系统的零极点分布图。
对于数字系统系数取高精度数值时,它具有三个极点和两个零点,都位于单位圆内。零极点分布如下图所示,由于所有的零点和极点都位于单位圆内,所以该离散时间系统为最小相位稳定系统。
局部放大靠近(1,0)处,可以看到三个极点的分布情况,其中有两个极点非常靠近单位圆。
当离散系统传递函数系数的有效数字降低后,相应的零极点就会有改变,特别是哪两个靠近单位圆的极点,就有可能移动到单位圆外。
下图显示了在上述只有四个有效数字系数时,对应系统函数零极点的分布位置。其中原来两个单位圆内的极点已经移动到单位圆外。此时系统已经不稳定了,对应系统的输出将会呈现指数增长。
下图显示了对于不同有效数字个数时系统函数对应的零极点的位置变化。当有效数字小于等于4个时,有一对共轭极点移动到单位圆外,此时系统就不再是稳定的系统了。
下图显示了对于不同有效数字个数时对应系统的单位冲激响应。当有效数字小于等于4个时,原来稳定的系统就会变得发散了。
本学期很快就到了最后的几周了,这学期的信号与系统课程也进入了后半程。下周就开始讲解线性时不变系统在变换域内的分析,其中一个主要内容,就是利用系统函数来分析系统的动态特性和稳态特性。本文中对数字滤波器的零极点分析就是课程这部分内容的具体应用。
到了本月底,自动化系的学生将迎来自己的学生节。本次学生节的名字叫做“脉冲响应”,与自动化系学科倒是显得非常贴切,不知道这是谁的脑洞。
这次学生节演出中,不仅有丰富多彩的学生文艺演出作品,同时还准备了令人兴奋的现场抽奖活动。看到这些奖品就能知道自动化系外联部吐血拉赞助是多么的辛苦了。
阶跃响应,正半轴上,
八十八个三等奖散落大礼堂每一行!
冲激响应,咬定一方,
万元清空购物车 锁定观众席正中央!
受迫响应,激励独享,
信号发生示波器新鲜出炉等你来抢!
脉冲响应,即将登场,
难道不来领取奖券中属于你的那张?