https://habrahabr.ru/post/328608/В поисках простой модели ПИД регулятора с объектом
Моделированию работы ПИД регулятора посвящено большое количество публикаций в сети. Лидирует проектирование моделей ПИД регулятора с применением Matlab Simulink [1,2] (134 миллиона ссылок в yandex). Сам процесс создания модели какой-то однообразный. В модель переносят всё новые и новые блоки. Одно движение ручного манипулятора и нате вам ПИД контролер, ещё одно и вот передаточная функция объекта. Соединяешь блоки, настраиваешь параметры, готовишь вычислитель. Да, возможностей много, но как-то слишком всё искусственно. И уже становится совсем непонятным к чему тут дифференциальные уравнения, методы их решения и то операционное исчисление, которым долго морочили голову. Ищу реализацию ПИД в Mathcad, тут ссылок в том же yandex, поменьше, всего то 81 миллион, а математики и формул побольше. Рассматриваю пример ПИД, поставляемый вместе с пакетом Mathcad 14.
![](https://habrastorage.org/web/dbc/ab1/e5d/dbcab1e5d39444598f563262f706a209.png)
В качестве объекта колебательное звено. Много умных объяснений, но в итоге два оператора laplace и invlaplace. Общая передаточная функция имеет в числителе вторую степень оператора, а в знаменателе четвёртую. Чтобы операторы laplace и invlaplace сработали, когда подключены все три составляющих ПИД, находят ещё и корни знаменателя передаточной функции, эти корни комплексно сопряжённые.
![](https://habrastorage.org/web/d7c/84b/774/d7c84b7743244d988ae1e5c4f2197410.PNG)
Теперь ищу реализацию ПИД на Python. Тихо радовался 97 миллионам результатов, но не долго. О Python 2.7 только применительно к прошивке Arduino на примере ESP32. Но и это переполняет сердце гордостью за Python.
Разочаровавшись в поиске, решил написать модель сам, в меру своих более чем скромных возможностей.
Структурная схема объекта управления
Постановку задачи взял из [3], в ней меня привлекло разнообразие структуры объекта регулирования. По ходу исправил несколько ошибок. Так, в конечном дифференциальном уравнении был потерян квадрат при T2, данные таблицы для a2 не соответствовали результатам аппроксимации. Кроме того, ввёл установку управления в виде единичного бесконечного импульса, чтобы оживить картинку переходного процесса. Уж как-то не естественно для ПИД регулятора она выглядит в [3].
![](https://habrastorage.org/web/d0b/6d1/f1a/d0b6d1f1a01a4d72a8a11316e2da37ce.JPG)
Будем исследовать систему регулирования со следующей структурной схемой.
![](https://habrastorage.org/web/f75/82d/f3b/f7582df3b15545f2a6b460f0da428897.PNG)
- Колебательное звено [4] описывается дифференциальным уравнением второго порядка.
![](https://habrastorage.org/web/13f/58b/ba4/13f58bba4c0c4a3987187d39e100c14f.JPG)
- Линейное статическое звено, определяющие зависимость выхода от входа которого определяется по табличным данным. Данные могут быть получены экспериментальным путём. Из-за погрешностей снятия данных, следует применять линейную аппроксимацию
.
- Второе линейное статическое звено — зависимость выхода от входа определяется по табличным данным, которые могут быть получены экспериментальным путём.. Из-за погрешностей снятия данных, следует применять линейную аппроксимацию
.
- Линейное динамическое звено, на вход которого поступает сума сигналов от блоков 2,3
![](https://habrastorage.org/web/b2a/b7a/8fe/b2ab7a8fe59d494db3f2d67ad0076177.JPG)
Звено имеет передаточную функцию, которая описывается линейным дифференциальным уравнением первого порядка.
![](https://habrastorage.org/web/02e/d87/8e2/02ed878e256b4a2ea2a660c3a074d0df.JPG)
- ПИД регулятор с известным законом регулирования, при котором для настройки на объект регулирования используются коэффициент пропорциональности
при линейной функции, коэффициент дифференцирования
при первой производной и коэффициент интегрирования
при неопределённом интеграле.
![](https://habrastorage.org/web/74e/a21/316/74ea213168544411a76130104a78e854.JPG)
Единичное входное воздействие 1(t) преобразуется в операторную форму как 1 /
p. Переведём в операторную форму уравнения 1,4 в результате получим.
![](https://habrastorage.org/web/935/95e/3f0/93595e3f0f724f26a16534b616caea01.JPG)
Продифференцируем обе части (5), для этого просто умножим на оператор p, получим.
![](https://habrastorage.org/web/b07/465/1c6/b074651c603245fe823c5946b3bcfec5.JPG)
Переведём в операторную форму уравнения (2), (3) и выразим y(y1).
![](https://habrastorage.org/web/48d/c4b/3af/48dc4b3af1bd4ddf9dd892132b7d98ed.JPG)
Подставим (7) в (6) получим:
![](https://habrastorage.org/web/0da/cf8/dad/0dacf8dadbf54ea58d4c0f11156e7198.JPG)
Перейдём (8) во временную область, для этого операторную форму заменим дифференциальным уравнением.
![](https://habrastorage.org/web/1f8/04f/f1a/1f804ff1a87941979a8a64479843c5f1.JPG)
Решение задачи определения настроек ПИД регулятора на Python
Зададим следующие параметры объекта регулирования:
T1=7.0; T2=5.0; s=0.4; k1=5.5; k2=5.5. Данные для аппроксимации характеристик звеньев 2,3 сведём в таблицу.
![](https://habrastorage.org/web/3f0/896/132/3f089613236642b885989aaa125d17fd.JPG)
Отставим объект без регулятора, для этого примем
![](https://habrastorage.org/web/634/4ce/140/6344ce1404124da9a07051a9d564267e.JPG)
.
Код программы#!/usr/bin/python
# -*- coding: utf-8 -*-
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
def mnkLIN(x,y,q): # аппроксимация характеристик статических объектов МНК
a=round((len(x)*sum([x[i]*y[i] for i in range(0,len(x))])-sum(x)*sum(y))/(len(x)*sum([x[i]**2 for i in range(0,len(x))])-sum(x)**2),3)
b=round((sum(y)-a*sum(x))/len(x) ,3)
y1=[round(a*w+b ,3) for w in x]
s=[round((y1[i]-y[i])**2,3) for i in range(0,len(x))]
sko=round((sum(s)/(len(x)-1))**0.5,3)
if q==1:
plt.subplot(221)
plt.plot(x, y, color='r', linewidth=2, marker='o', label='Коэффициент a= %s'%str(a))
plt.plot(x, y1, color='g', linestyle=' ', marker='o', label='СКО =%s'%str(sko))
plt.legend(loc='best')
plt.grid(True)
else:
plt.subplot(222)
plt.plot(x, y, color='r', linewidth=2, marker='o', label='Коэффициент a= %s'%str(a))
plt.plot(x, y1, color='g', linestyle=' ', marker='o', label='СКО =%s'%str(sko))
plt.legend(loc='best')
plt.grid(True)
return a
T1=7.0;T2=5.0;s=0.4;k1=5.5;k2=5.5# параметры объекта регулирования.
x=[0,1,2,3,4,5]
y=[0,-11,-22,-33,-44,-55]
a2=mnkLIN(x,y,1)
x=[0,1,2,3,4,5]
y=[0,17,34,51,68,85]
a3=mnkLIN(x,y,2)
#m1=0.5;m2=2.0;m3=0.3# параметры ПИД регулятора.
m1=0.0;m2=0.0;m3=0.0
a=a2+a3
A=round((s*T1*T2+T1**2)/(T1*T2**2),3)
B=round((T2+s*T1+k1*k2*m2*a)/(T1*T2**2),3)
C=round((1+k1*k2*m1*a)/(T1*T2**2),3)
D=round(k1*k2*m3*a/(T1*T2**2),3)
E=round(k1*k2*a/(T1*T2**2),3)
def f(y, t):# решение дифференциального уравнения системы регулирования.
y1,y2,y3,y4 = y
return [y2,y3,y4,-A*y4-B*y3-C*y2-D*y1+E]
t = np.linspace(0,100,10000)
y0 = [0,1,0,0]#начальные условия
w = odeint(f, y0, t)
y1=w[:,0] # вектор значений решения
y2=w[:,1] # вектор значений производной
plt.subplot(223)
plt.plot(t,y1,linewidth=1, label=' p- %s,d- %s,i- %s,'%(str(m1),str(m2),str(m3)))
plt.ylabel("z")
plt.xlabel("t")
plt.legend(loc='best')
plt.grid(True)
plt.show()
Результат роботы программы.![](https://habrastorage.org/web/e2b/973/470/e2b9734706964f1da1bae04a546f3337.png)
Без ПИД регулятора объект пошёл в «разнос». После предварительного подбора параметров ПИД получим.
![](https://habrastorage.org/web/b39/47c/566/b3947c5665cb4905bc910acd24db270c.png)
Изменим табличные данные для третьего звена, увеличим а3 в два раза.
![](https://habrastorage.org/web/849/b42/8ff/849b428ff8014774a86bb89cfe10e2f1.png)
Регулятор стабилен.
Выбор функции для решения уравнения (9) на Python и сравнение результатов с решением на Matcad
Я использовал функцию odeint из библиотеки scipy. Integrate.
def f(y, t):# решение дифференциального уравнения системы регулирования.
y1,y2,y3,y4 = y
return [y2,y3,y4,-A*y4-B*y3-C*y2-D*y1+E]
t = np. linspace(0,100,10000)
y0 = [0,1,0,0]#начальные условия
w = odeint(f, y0, t)
y1=w[:,0] # вектор значений решения
y2=w[:,1] # вектор значений производной
Если уравнение (9) перестроить так, чтобы в левой части была производная высшего порядка, а в правой всё остальное, то получим.
![](https://habrastorage.org/web/0b4/872/b86/0b4872b860b348d6b1c8c04c92ab4e12.JPG)
Так и строится функция def f (y, t). Функция odeint имеет три обязательных аргумента и выглядит вот так
odeint (func, y0, t[,args=(), ...]).
Для сравнения выведем используемые в приведенной функции def f (y, t) значения переменных A, B, C, D, E, получим 0.36 7.996 1.994 1.193 3.976. Составим на Mathcad 14 программу для решения дифференциального уравнения (9) и построим переходную характеристику.
![](https://habrastorage.org/web/9b5/5d7/807/9b55d78074f8438d97c80ea7b7fad08e.PNG)
Графики и числовые значения полностью идентичны. Таким образом, функции Odesolve Mathcad и odeint Python дают одинаковые численные решения приведённой в статье задачи.
Вывод
На данном этапе развития язык программирования Python с библиотеками SciPy и NumPy может эффективно использоваться для численного моделирования контуров автоматического регулирования содержащих динамические и статические звенья.
Ссылки
- Автоматизированная настройка ПИД-регулятора для объекта управления следящей системы с использованием программного пакета MATLAB Simulink Филиппов А. В.1, Косолапов М. А.2, Маслов И. А.3, Тарасова Г. И.
- Методы настройки ПИД-регулятора в matlab simulink.
- Подбор ПИД регулятора.
- Модель колебательного звена в режиме резонансных колебаний на Python.