
Добавил:
vadikbee
ИВТ (советую зайти в "Несортированное")
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:1 лаб 3 вар / main
.py#Тема: Исследование устойчивости систем автоматического управления
#Цель работы:
#1)Ознакомиться с алгебраическими и частотными методами оценки устойчивости САУ.
#2)Получить практические навыки анализа устойчивости систем.
#Метод Гурвица (построение определителей Гурвица)
#Метод Михайлова (построение годографа)
################################# алгебраические методы устойчивости ##########################################
#Критерий Гурвица
#Позволяет определить устойчивость системы по коэффициентам характеристического уравнения.
#Использует специальные определители Гурвица, составляемые из коэффициентов уравнения.
#Условие устойчивости: Все определители Гурвица должны быть положительными.
############################## частотные методы устойчивости #############################################
#Критерий Михайлова
#Основан на построении годографа Михайлова (графика зависимости от ).
#Устойчивость определяется по количеству обходов начала координат против часовой стрелки.
import numpy as np
import matplotlib.pyplot as plt
import sympy as sp
from scipy import signal
# Заданные параметры
k = 3
T1 = 0.6
T2 = 0.5
xi = 0.03
# Формирование характеристического уравнения
# Номинатор передаточной функции
numerator = [k, 0] # 3p
# Деноминатор передаточной функции
denominator = np.polymul([T1, 1], [(T2 ** 2), 2 * T2 * xi, 1]) # (T1p + 1) * (T2^2 * p^2 + 2*T2*xi*p + 1)
# Выведем коэффициенты характеристического уравнения
char_poly = denominator
print("Характеристическое уравнение: ", np.poly1d(char_poly))
# --- Проверка устойчивости по критерию Гурвица ---
def hurwitz_determinants(coeffs):
"""Функция для вычисления определителей Гурвица"""
n = len(coeffs) - 1
H = np.zeros((n, n))
for i in range(n):
for j in range(n):
index = 2 * i - j
if 0 <= index < len(coeffs):
H[j, i] = coeffs[index]
determinants = [np.linalg.det(H[:i + 1, :i + 1]) for i in range(n)]
return determinants
# Преобразуем числа в обычный формат и выведем их
hurwitz_dets = hurwitz_determinants(char_poly)
converted_hurwitz_dets = [float(num) for num in hurwitz_dets]
print("Определители Гурвица (обычный формат):", converted_hurwitz_dets)
is_stable_hurwitz = all(d > 0 for d in hurwitz_dets)
print("Устойчивость по Гурвицу:", "Система устойчива" if is_stable_hurwitz else "Система неустойчива")
# --- Годограф Михайлова ---
def mikhailov_curve(coeffs, w_range):
"""Вычисление кривой Михайлова"""
jw = 1j * w_range #массив мнимых чисел jw
D_jw = sum(c * (jw ** i) for i, c in enumerate(reversed(coeffs))) #Вычисляет характеристический полином D(jw)
return D_jw.real, D_jw.imag
# Увеличим диапазон значений для большей детализации графика
# Новый диапазон частот с более мелким шагом
w_range_fine = np.linspace(0, 3, 5) # Было 50 и 1000 точек, теперь 100 и 5000 точек
# Пересчитаем годограф Михайлова с новым диапазоном
real_m_fine, imag_m_fine = mikhailov_curve(char_poly, w_range_fine)
# Построение графика годографа Михайлова с увеличенным количеством значений
plt.figure(figsize=(8, 8))
plt.plot(real_m_fine, imag_m_fine, label="Кривая Михайлова (увеличено значений)", linewidth=1.5)
plt.scatter(real_m_fine[0], imag_m_fine[0], color='red', label="Начало (w=0)", s=50)
plt.scatter(real_m_fine[-1], imag_m_fine[-1], color='green', label="Конец (w → ∞)", s=50)
# Улучшенные оси
# Добавляем оси
plt.axhline(0, color='black', lw=1, linestyle='solid', label="Ось Im (мнимая)")
plt.axvline(0, color='black', lw=1, linestyle='solid', label="Ось Re (вещественная)")
# Улучшенные подписи
plt.xlabel("Re(D(jw)) -вещественная", fontsize=12)
plt.ylabel("Im(D(jw)) - мнимая", fontsize=12)
plt.title("Годограф Михайлова (больше точек)", fontsize=14)
plt.legend(fontsize=10)
plt.grid(True, linestyle="--", linewidth=0.5)
plt.show()
# Проверка устойчивости по критерию Михайлова
def is_stable_mikhailov(real, imag):
"""Проверяет устойчивость по критерию Михайлова"""
angle_diff = np.angle(real + 1j * imag)[-1] - np.angle(real + 1j * imag)[0]
num_quadrants = angle_diff / np.pi #Деление на π переводит разницу углов в количество пройденных квадрантов комплексной плоскости.
return num_quadrants >= len(char_poly) - 1 #степень хар уравнения (полюса системы)
#real + 1j * imag – это комплексные числа, которые представляют кривую Михайлова в комплексной плоскости.
#np.angle(z) – вычисляет аргумент (угол) комплексного числа
#z.[-1] – это конечное значение угла при 𝑤→∞w→∞.[0] – это начальное значение угла при 𝑤=0w=0.
#angle_diff – вычисляет разницу финального и начального углов, то есть насколько повернулась кривая.
is_stable_mikhailov = is_stable_mikhailov(real_m, imag_m)
print("Устойчивость по Михайлову:", "Система устойчива" if is_stable_mikhailov else "Система неустойчива")
#По критерию Гурвица:
#Все определители Гурвица положительны --> Система устойчива.
#По критерию Михайлова:
#Годограф Михайлова не выполняет условия устойчивости ⇒ Система неустойчива.
#критерии дали противоречивые результаты. Это может указывать на пограничное состояние системы
Соседние файлы в папке 1 лаб 3 вар