使用Python3进行信号处理和分析(一):使用类Matlab的方式绘制波特图(Bode Plot)

Preface

该系列文章是笔者复习研究生入学考试专业课,为辅助理解使用Python进行实验时所写。要求读者有电子信息方向本科大二及以上的基础知识,包括模数电、信号与系统以及数字信号处理等。因此部分细节性的知识不再详述。
本文使用的环境为Matlab R2018b以及Python 3.7.1(由Anaconda管理)

波特图

注意:此波特(Bode)非彼波特(Baud),后者是通信中的概念。

波特图是线性非时变系统的传递函数对频率的半对数坐标图,利用波特图可以看出系统的频率响应。又称幅频响应和相频响应曲线图。

以上摘自百度百科,波特图在模拟系统的分析中十分重要。
频率响应的计算来源于信号与系统的拉氏变换:将模拟系统看做线性时不变(LTI)系统,输入电压 v i ( t ) v_i(t) vi(t)看做激励信号 e ( t ) e(t) e(t),输出电压 v o ( t ) v_o(t) vo(t)看做响应信号 r ( t ) r(t) r(t),那么该系统就满足(1)式:
(1) r ( t ) = e ( t ) ∗ h ( t ) r(t) = e(t) * h(t) \tag1 r(t)=e(t)h(t)(1)
其中 h ( t ) h(t) h(t)是系统的冲激响应,对其进行拉氏变换,有
(2) R ( s ) = E ( s ) H ( s ) R(s) = E(s)H(s) \tag2 R(s)=E(s)H(s)(2)
(2)式中的 H ( s ) H(s) H(s)称为系统函数,已知系统函数满足(3)式:
(3) H ( s ) = ∣ H ( s ) ∣ e ϕ ( s ) H(s) = \left| H(s)\right| e^{\phi(s)} \tag3 H(s)=H(s)eϕ(s)(3)
在理论分析中,一般认为复频率 s s s满足(4)式(为什么?
(4) s = j ω s = j\omega \tag4 s=jω(4)
于是综合(3)(4)两式,易得
(5) H ( j ω ) = ∣ H ( ω ) ∣ e ϕ ( j ω ) H(j\omega) = \left| H(\omega) \right| e^{\phi(j\omega)} \tag5 H(jω)=H(ω)eϕ(jω)(5)
其中 ∣ H ( ω ) ∣ \left| H(\omega) \right| H(ω)称为信号的幅频特性, ϕ ( j ω ) \phi(j\omega) ϕ(jω)称为信号的相频特性,它们都反映了系统的频率特性。波特图正是直观反映它们的工具。
现在设某系统的系统函数为(6)式,逐一讨论如何使用matlab和python3绘制波特图
(6) H ( s ) = s + 1 s 2 − 5 s + 6 H(s) = \frac{s+1}{s^2-5s+6} \tag6 H(s)=s25s+6s+1(6)

使用matlab绘制波特图

Matlab拥有极丰富的信号处理工具箱,可以轻易的绘制出系统的波特图。
这里主要借助tf函数进行绘制

% 方法一:使用tf构建复频率变量
s = tf('s');
sys = (s + 1) / (s ^ 2 - 5 * s + 6);
bode(sys)

% 方法二:直接使用tf构建系统函数
sys = tf([1, 1], [1, -5, 6]);
bode(sys)

可见,不论如何构建系统函数,都需要使用bode()函数进行绘图,该函数可以一次性给出幅频特性和相频特性的曲线,极为方便。

使用python3绘制波特图

这里必须安装这么几个第三方库:numpyscipymatplotlib。可以使用conda或者pip安装。

# -*-coding: UTF-8 -*-
from scipy import signal
from pylab import *

def main():
	system = signal.lti([1, 1], [1, -5, 6])			# 类似tf函数,构建系统函数H(s)
	f = logspace(-2, 5)								# 取频率坐标,0.01Hz ~ 0.1MHz
	w = 2 * pi * f									# 取角频率
	w, mag, phase = signal.bode(system, w)			# 计算各参量, mag为幅频特性,phase为相频特性
	semilogx(f, phase)								# 绘制半对数坐标图(频率作为横轴采用对数坐标),将phase换成mag即为幅频特性曲线

	show()											# 很重要,如无此函数则不显示

if __name__ == "__main__":
	main()

注意

代码较为简单,因此就不上图了
这里交代两个问题:

  1. 为什么 s = j ω s=j\omega s=jω
    答:因为模电的理论分析中常用正弦信号作为输入信号,由欧拉公式, c o s j ω t = e j ω t + e − j ω t 2 cosj{\omega}t = \frac{e^{j\omega t} + e^{-j\omega t}}{2} cosjωt=2ejωt+ejωt,因此复频率为纯虚数

  2. tflti传参的问题
    这两个函数较为相似,在直接构建系统函数时,接受的参数应为系统函数分子和分母各项的系数组成的列表,系数的分配是从右到左的,这点不难从上面的代码中观察得出

你可能感兴趣的:(信号与系统,模拟电子技术,数字信号处理,Anaconda,Python)