matplotlib 如何从波特图确定截止频率、静态误差常数以及相位和增益裕度

amrnrhlw  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(231)

我已经从包含每个频率值的幅度和相位值的CSV文件中构建了系统的波特图。现在我需要确定静态误差常数的值,增益和相位裕度以及截止频率。由于传递函数未知,因此必须通过图形分析获得这些值。
我从csv文件中得到的图表如下所示
x1c 0d1x的数据
这是我用来绘制波特图的代码:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

data = pd.read_csv('example_P3.csv')
data
magnitude = data['Mag']
phase = data['Phase']
w_rad = data['W']

w_hz = w_rad/(2*np.pi)

plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
plt.semilogx(w_hz, magnitude, 'b')
plt.title('Diagrama de Bode - Magnitud')
plt.ylabel('Magnitud (dB)')

plt.subplot(2, 1, 2)
plt.semilogx(w_hz, phase, 'r')
plt.title('Diagrama de Bode - Fase')
plt.xlabel('Frecuencia (Hz)')
plt.ylabel('Fase (grados)')

plt.tight_layout()
plt.show()

字符串
为了确定相位和增益裕量以及截止频率,我在代码中执行了以下几行:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

data = pd.read_csv('example_P3.csv')
magnitude = data['Mag']
phase = data['Phase']
w_rad = data['W']

w_hz = w_rad/(2*np.pi)

plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
plt.semilogx(w_hz, magnitude, 'b')
plt.title('Diagrama de Bode - Magnitud')
plt.ylabel('Magnitud (dB)')

plt.subplot(2, 1, 2)
plt.semilogx(w_hz, phase, 'r')
plt.title('Diagrama de Bode - Fase')
plt.xlabel('Frecuencia (Hz)')
plt.ylabel('Fase (grados)')

# Calculate gain margin and phase margin
gain_margin_freq = w_hz[np.argmax(magnitude > 0)]  # Frequency where magnitude crosses 0 dB
phase_margin_phase = phase[np.argmin(np.abs(magnitude - 0))]  # Phase at the frequency of gain margin

# Calculate cutoff frequency and bandwidth
cutoff_freq = w_hz[np.argmax(magnitude > -3)]  # Frequency where magnitude is -3 dB
bandwidth = w_hz[np.argmax(magnitude > -3)] - w_deg[np.argmax(magnitude == np.max(magnitude))]  # Width at -3 dB

# Plot vertical lines and text annotations for gain and phase margins, cutoff frequency, and bandwidth
plt.subplot(2, 1, 1)
plt.axvline(gain_margin_freq, color='g', linestyle='--', label=f'Gain Margin: {gain_margin_freq:.2f} Hz')
plt.axvline(cutoff_freq, color='y', linestyle='--', label=f'Cutoff Frequency: {cutoff_freq:.2f} Hz')
plt.legend()

plt.subplot(2, 1, 2)
plt.axvline(gain_margin_freq, color='g', linestyle='--', label=f'Gain Margin: {gain_margin_freq:.2f} Hz')
plt.axhline(phase_margin_phase, color='m', linestyle='--', label=f'Phase Margin: {phase_margin_phase:.2f} degrees')
plt.legend()

plt.tight_layout()
plt.show()


对于截止频率,我所做的是尝试定位幅度的最大值,并找到3 dB下降的位置,以在图上标记它。至于裕度,对于增益,我寻找幅度跨越0 dB的频率,对于相位,我寻找相位跨越-180度的相位值。对于截止频率,我所做的是尝试定位幅度的最大值,并找到3 dB下降的位置,以在图上标记它。至于裕度,对于增益,我寻找幅度穿过0 dB的频率和相位,我寻找相位与-180度交叉处的相位值。这种方法似乎不合适,因为,如下图所示,截止频率的位置不正确。



这是我第一次做这种类型的事情,所以我完全找不到解决问题的方法,这导致我向做过这种类型问题的人寻求帮助,他可以指导我解决它。

drkbr07n

drkbr07n1#

几点:
1.我认为你的幅度不是分贝(dB);转换时,使用mag_db = 20*np.log(magnitude)。(为什么我不认为它是dB:我认为不可能有一个相位为-90度的稳定dB幅度;然而,如果你的幅度是“自然”单位,它将在-20 dB/十年时趋于0,但这在自然尺度上很难看到。)

  1. np.degrees将弧度转换为度,这与转换为赫兹不同;除以2 * np.pi得到赫兹。
  2. np.argmax不会像你在w_deg[np.argmax(magnitude > 0)]中所想的那样--它实际上会返回满足要求的 first 索引。你需要找到幅度(单位为dB!)与0交叉的地方;一种方法是检查mag_db[:-1] * mag_db[1:] <= 0的位置。而是使用python-control(见下文)。
    1.你的相位不会超过180度,所以增益没有限制。
    查看https://github.com/python-control/python-control/ [免责声明,我是该项目的贡献者],其中有一个频率响应数据(FRD)类,应该可以帮助您。
    对于控制理论和相关问题的帮助,你可能会在https://dsp.stackexchange.com/上有更好的运气。

相关问题