#はじめに
最近、独学で制御工学を勉強し始めました。
理解を深める為にはプログラミングで実装してみるのが一番早い、というのが私の理念です。
なので、今回は最近勉強したPID制御をPythonを使って実現してみます。
なお、この記事ではPID制御や制御工学の原理・理論の説明はしません。
Pythonでの実装にのみフォーカスを当ててます。
matplotlibとnumpyを使います。
OSは、Ubuntu16.04とMacOS High Sierra10.13で動作確認済みです。
Python2.7, Python3.6の両方で動きます。
一応、GitHubにもコードを上げておきます。
#変数の説明
M : 与える操作量
M1 : 一つ前に与えた操作量
goal : 目的値
e : 偏差(目的値と現在値の差)
e1 : 前回の偏差
e2 : 前々回の偏差
Kp : 比例制御(P制御)の比例定数
Ki : 積分制御(I制御)の比例定数
Kd : 微分制御(D制御)の比例定数
#操作量(M)の求め方
操作量(M)の求め方ですが、本来ならば、微積の計算をして操作量(M)を求めます。
しかし、それには莫大な計算が必要になる上、そもそもコンピュータで扱えるのは基本的に離散的な値です。
そこで、サンプリング方式
M = M1 + Kp * (e-e1) + Ki * e + Kd * {(e-e1) - (e1-e2)}
で操作量(M)を求めます。
#プログラムコード
それでは、いよいよプログラムを書いていきます。
まずは、必要なモジュールをimportします。
import numpy as np
from matplotlib import pyplot as plt
from numpy.random import *
次に、メインの部分を書いていきます。
M = 0.00
M1 = 0.00
goal = 50.00
e = 0.00
e1 = 0.00
e2 = 0.00
Kp = 0.1
Ki = 0.1
Kd = 0.1
t = 100
M, M1, e, e1, e2は最初は0.00に設定しておきます。
goalは目的の値でとりあえず今回は50.00にしておきましょう。
Kp,Ki,Kdはパラメータとなります。最初は様子をみて全て0.10にしておきましょう。
謎の変数tが出てきましたが、これは時間(t)です。for文のループ回数を設定する為に使います。
次に、グラフで表示するための準備をします。
x_list = []
y_list = []
x_list.append(0)
y_list.append(0.00)
x_listには時間(t)が入ります。
y_listには与えた操作量(M)が入ります。
時間(t)が0の時には、操作量も0.00なので、for文で回す前に事前にリストに格納しておきます。
そして、いよいよPID制御に入ります。
と言っても、先ほどのサンプリング方式の式に代入するだけです。
for i in range(1,t):
M1 = M
e2 = e1
e1 = e
e = goal - y_list[i-1] #偏差(e) = 目的値(goal) - 前回の操作量
M = M1 + Kp * (e-e1) + Ki * e + Kd * ((e-e1) - (e1-e2))
x_list.append(i)
y_list.append(M)
偏差(e)の求め方は、制御対象によって変わるので注意してください。
とりあえず今は、(目的値)と(前回与えた操作量)の差を偏差(e)としています。
最後に、グラフで表示してみましょう。
plt.hlines([goal], 0, t, "red", linestyles='dashed') #ゴールを赤色の点線で表示
plt.plot(x_list, y_list, color="b") #青色でグラフを表示
plt.ylim(0, goal*2) #グラフの高さを調整
plt.show()
最初の段差が少々気になりますが、綺麗な曲線で目的値まで届いていると思います。
#パラメータを変えてみよう
試しに、Kp, Ki, Kdをそれぞれ0.01と0.50に変えてみました。
Kp = Ki = Kd = 0.01
パラメータが0.01だと、目的値50.00まで届かないです。
Kp = Ki = Kd = 0.5
パラメータが0.50だと値が収束せずにハンチングが発生してしまいました。
#ノイズ入りバージョン
ランダムでノイズを入れてみましょう。
コードはGitHubに上げておきます。
#最後に
簡単ではありますが、PythonでPID制御をやってみました。
今回はKp,Ki,Kdのパラメータを全て同じ値に設定しましたが、実際は各パラメータを細かく調整する必要があります。
2018/07/03 altさん、編集リクエストありがとうございます。
参考にしたサイトを載せておきます。
モータのPID制御法
【分かりすぎる】PID制御の基礎(YouTube動画)
ソースコードはGitHub載せておくので参考にしてください。