システムとモデリング

modelica, Julia, Design Structure Matrix, SysML, 他モデリング全般について。

JuliaでPID制御を実装する。

前回、JuliaでPI制御を実装しましたので、今回はそれに微分ゲインを加えてPID制御にします。

otepipi.hatenablog.com

離散的であるプログラムでの実装では微分制御は以下の式で実装できます。 $$ \begin{equation} u_d(t)=k_d \frac{e_t - e_{t-1}}{⊿t} \end{equation} $$

これを踏まえて前回のコードに微分制御を実装します。

using Plots

u = 0 #部品供給数初期値
wip = 0 #予備プールの部品数
que = 0 #バッファーの部品数
max_wip = 50 #予備プールへの最大投入数
max_flow = 10 #下流工程への処理速度の最大値
kp = 1.25 #比例ゲイン
ki = 0.01 #積分ゲイン
kd = 0.1 #微分ゲイン
tm = 1000 #シミュレーション時間
ie = 0 #誤差積算値初期値
er = 0 #誤差初期


function work(u)
    #予備プールへの部品供給
  u = max(0,u)
  u = min(u,max_wip)
 global wip = wip + u

# 予備プールからバファーへの部品移動

  r = rand( 0:wip)
  wip = wip - r
 global  que = que + r

# バッファーから下流工程への部品移動
  r = rand( 0:max_flow)
  r = min(r,que)
  que = que - r

  return que
end

# PIDコントローラー

function PID(er)
global ie = ie + er
return  kp * er + ki * ie + kd * ⊿er
end


#目標値の変更
function setpoint(t)
  if t < 100
      return 0
  elseif t < 300
      return 50
    else
      return 10
    end
end

#ループの実行

# 空の配列の作成
r_ = zeros(tm + 1)
er_ = zeros(tm + 1)
u_ = zeros(tm + 1)
y_ = zeros(tm + 1)

for t in 0:tm
  global er
  r = setpoint(t)
  u = PID(er)
  y = work(u)
  er = r - y
  r_[t+1] = r
  er_[t+1] = er
  u_[t+1] = u
  y_[t+1] = y

#誤差微分値の計算
  if t > 0
      global ⊿er = er_[t+1]-er_[t]
  end
end

plot([0:tm],[y_,r_],title="kp=0.1 ki=0.01 kd=0.1",label=["y","setpoint"])

これを実行すると以下のようになります。 f:id:Otepipi:20190405230631p:plain

これで無事PID制御の実装までいきつきました。

今回は短いですが以上です。