見出し画像

Python-Control 伝達関数モデルを扱いやすくする方法

Python-Controlは伝達関数モデルを作成して、制御工学の計算を簡単に行うことができます。本記事では、伝達関数モデルを扱いやすくする方法について書いていきます。

概要を説明すると、多数の伝達関数モデルを用いた複雑なシステムの設計計算を想定し、伝達関数モデルの作成部をdef関数化して扱いやすくします。1度、関数化してしまえば、以降は関数に引数を入れるだけで簡単に伝達関数モデルを作成することができます。

関数化するメリットは、コードを書く量が減る、コーディングミスを減らせるといった事が挙げられます。

伝達関数モデル作成をdef関数で定義する

複雑なシステムの設計計算を想定して、Python-Controlを用いた伝達関数モデル作成部もdef関数で作成していきます。今回はいくつかの伝達関数モデルを作成するdef関数を作りました。個人的に、システム設計で出てくる頻度の高い伝達関数をピックアップしています。

比例要素

画像7

# 伝達関数モデル作成 (比例要素)
def tf_proportional(k):
   num = [k]
   den = [1]
   return matlab.tf(num, den)

積分要素

画像6

# 伝達関数モデル作成 (積分要素)
def tf_integral(k, t):
   num = [k]
   den = [t, 0]
   return matlab.tf(num, den)

1次遅れ要素

画像4

# 伝達関数モデル作成 (1次遅れ要素)
def tf_delay_1st(k, t):
   num = [k]
   den = [t, 1]
   return matlab.tf(num, den)

2次系

画像2

# 伝達関数モデル作成 (2次系)
def tf_2nd_order(k, zeta, wn):
   num = [k*wn*wn]
   den = [1, 2*zeta*wn, wn*wn]
   return matlab.tf(num, den)

P補償器(比例)

画像3

# 伝達関数モデル作成 (P補償器)
def tf_controller_p(kp):
   # 比例補償器
   num_p = [kp]
   den_p = [1]
   return matlab.tf(num_p, den_p)

PI補償器(比例+積分)

画像4

# 伝達関数モデル作成 (PI補償器)
def tf_controller_pi(kp, ki):
   # 比例補償器
   num_p = [kp]
   den_p = [1]
   Gp = matlab.tf(num_p, den_p)
   # 積分補償器
   num_i = [ki]
   den_i = [1, 0]
   Gi = matlab.tf(num_i, den_i)
   return Gp + Gi

PID補償器(比例+積分+微分)

画像7

# 伝達関数モデル作成 (PID補償器)
def tf_controller_pid(kp, ki, kd):
   # 比例補償器
   num_p = [kp]
   den_p = [1]
   Gp = matlab.tf(num_p, den_p)
   # 積分補償器
   num_i = [ki]
   den_i = [1, 0]
   Gi = matlab.tf(num_i, den_i)
   # 微分補償器
   num_d = [kd, 0]
   den_d = [1]
   Gd = matlab.tf(num_d, den_d)
   return Gp + Gi + Gd

補足
補償器のPIDとはそれぞれ下記の意味になります。比例器、積分器、微分器を組み合わせた補償器(コントローラ)でシステムの状態(動作)を指令通り(目標値)に制御するものになります。システムの自動制御を行う際に用いられます。

Proportional = 比例
Integral = 積分
Differential = 微分

def関数の使用例
作成したdef関数の使い方を説明します。PID補償器を例にすると、下記のように「関数名(引数1, 引数2, 引数3)」と記載し、それを変数に入れてあげれば伝達関数モデルを作成することができます。

Gpid = tf_controller_pid(2.0, 0.1, 5.0)
print(Gpid)

出力結果は以下のようになります。

5 s^2 + 2 s + 0.1
-----------------
       s


classを使って書いてみた例

何が良いのかというと、私の場合はエディタに Visual Studio Code を使っているのですが、下図のように伝達関数モデル作成部の関数を一気に折りたたんで隠せるので、表示されるコードの量が減って非常に見やすいところが良いです。def関数ごとに折りたたむこともできるのですが、def関数の数が増えてくると1つずつ折りたたむのが面倒だったので。ちなみに、Python初心者の私はまだclassの理解が十分ではないので、もっと良い書き方があるかもしれないです。様々なサイトでclassの説明を読んでいますが、解釈がなかなか難しかったりしますね。

画像8

画像9

Pythonソースコード
class部のコード全体は以下のようになります。このようにモジュール化しておくと、後で新しい伝達関数モデルを追加したり、中身の変更がやりやすくなると思います。

# =================================================
#           class定義
# =================================================

# クラス定義 (伝達関数モデル作成)
class tf_model:

   # 初期化メソッド
   def __init__(self):
       # ゲイン 1.0 の比例要素に初期化
       num = [1.0]
       den = [1.0]
       self.tf = matlab.tf(num, den)

   # 比例要素
   def proportional(self, k):
       num = [k]
       den = [1]
       return matlab.tf(num, den)
   
   # 積分要素
   def integral(self, k, t):
       num = [k]
       den = [t, 0]
       return matlab.tf(num, den)

   # 1次遅れ要素
   def delay_1st(self, k, t):
       num = [k]
       den = [t, 1]
       return matlab.tf(num, den)

   # 2次系
   def order_2nd(self,k, zeta, wn):
       num = [k*wn*wn]
       den = [1, 2*zeta*wn, wn*wn]
       return matlab.tf(num, den)

   # P補償器
   def controller_p(self,kp):
       # 比例補償器
       num_p = [kp]
       den_p = [1]
       return matlab.tf(num_p, den_p)

   # PI補償器
   def controller_pi(self,kp, ki):
       # 比例補償器
       num_p = [kp]
       den_p = [1]
       Gp = matlab.tf(num_p, den_p)
       # 積分補償器
       num_i = [ki]
       den_i = [1, 0]
       Gi = matlab.tf(num_i, den_i)
       return Gp + Gi

   # PID補償器
   def controller_pid(self,kp, ki, kd):
       # 比例補償器
       num_p = [kp]
       den_p = [1]
       Gp = matlab.tf(num_p, den_p)
       # 積分補償器
       num_i = [ki]
       den_i = [1, 0]
       Gi = matlab.tf(num_i, den_i)
       # 微分補償器
       num_d = [kd, 0]
       den_d = [1]
       Gd = matlab.tf(num_d, den_d)
       return Gp + Gi + Gd

classを使った場合の使用例
作成したclassの使い方を説明します。まず、一時的に(temporally)伝達関数モデルを代入する変数を用意します。以下のソースコードだと「temp_tf」になります。この「temp_tf」を用いてインスタンスを生成します。あとは、「temp_tf.(関数名)(引数1, 引数2, 引数3・・)」というように記載し、その結果を伝達関数の変数に代入していきます。

 #インスタンス生成 
temp_tf = tf_model()

G1st = temp_tf.delay_1st(1.0, 0.01)
print(G1st)

Gpid = temp_tf.controller_pid(2.0, 0.1, 5.0)
print(Gpid)

出力結果は以下になります。

    1
----------
0.01 s + 1


5 s^2 + 2 s + 0.1
-----------------
       s


おわりに

自動制御システムの制御系を設計しようとすると、制御対象の伝達関数やコントローラの伝達関数が含まれます。さらに複雑になると、センサを用いた検出箇所が増え、フィードバックループが2つ、3つと増えていきます。細かく設計しようとすると、センサにも遅れが含まれるので、システム全体の伝達関数はかなりの量になります(ただし、複雑なシステムでは近似して簡易モデルで設計する場合もあると思います)。そういった場合は本記事に記載したように伝達関数モデル作成部の機能をモジュール化しておくと、記載するコードの量が減りますし、コーディングミスも減ると思います。

以上

何かお役に立てたら、サポートしていただけると嬉しいです!モチベーションを高めて、アウトプットしていきます!