MATLAB,Python,Scilab,Julia比較 その77【PID制御⑥】

MATLAB,Python,Scilab,Julia比較 その77【PID制御⑥】 数値計算
MATLAB,Python,Scilab,Julia比較 その77【PID制御⑥】

バックナンバーはこちら。
https://www.simulationroom999.com/blog/compare-matlabpythonscilabjulia-backnumber/

はじめに

前回までで、PID制御の離散化とブロック線図を作成。
これでPID制御器もコード化可能な準備が整った。

というわけで、これをMATLABで実現してみる。

登場人物

博識フクロウのフクさん

指差しフクロウ

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1

エンジニア歴8年の太郎くん

技術者太郎

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1

【再掲】PID制御器のブロック線図と全体構成

太郎くん
太郎くん

今回からPID制御のコード化とシミュレーションが始まる感じだね。

フクさん
フクさん

そうそう。
まずは、PID制御器のブロック線図と全体構成を再掲しておこう。

PID制御器(変形式)ブロック線図、目標値、実値、1/zは前回値保持の意、Ki、Kp、Kd、T1、ΔT、e(t)、u(t)
PID制御器を加味した構成図、指令器0~1の範囲で出力、指令器、制御器、PID制御器、DCモータ、状態空間モデル、target(t)、actual(t)、E(t)、u(t)、ω(t)

MATLABコード

フクさん
フクさん

これを元に起こしたMATLABコードが以下になる。

% statespacemodel.m
function [x,y] = statespacemodel(A, B, C, D, u, dt, x)
    % 様態方程式
    x = x + (A*x + B*u) * dt;
    
    % 出力方程式
    y = C*x + D*u;
end
% PIDController.m
function [state, u]=PIDController(state, target, actual, Kp, Ki, Kd, dt, t1)
    e_i = target - actual;
    e_p = (t1/dt)*(e_i - state.pzi);
    e_d = (t1/dt)*(e_p - state.dzi);
    u = (dt/t1)*(e_p*Kp + e_i*Ki + e_d*Kd) + state.izi;

    state.pzi = e_i;
    state.dzi = e_p;
    state.izi = u;
end
% statespacemodel_pid.m
function []=statespacemodel_pid()
    K=0.016;
    J=0.000000919;
    R=1.34;
    L=0.00012;

    A=[0,1,0 ; 0,0,K/J ; 0,-K/L,-R/L];
    B=[0 ; 0; 1/L];
    C=[1,0,0;0,1,0;0,0,1];
    D=[0;0;0];
    
    dt = 0.0001;
    t = linspace(0, 1, 10000); % 時間(横)軸
    u = zeros(1,10000);        % 入力信号生成
    u(1,5000:10000)=1;         % 0.5秒後に0から1へ
    y = zeros(3,numel(t));
    x = zeros(3,1);
    
    state.pzi = 0;state.dzi = 0;state.izi = 0;
    ratio = 1/60;
    Kp = 0.8;
    Ki = 0.45;
    Kd = 0.0;
    t1 = 0.005;
    
    omega = 0;
    uPID = zeros(1,10000);
    
    for i = 1:numel(t)
        [state,uPID(1,i)] = PIDController( state, u(:,i), omega*ratio, Kp, Ki, Kd, dt, t1 );
        [x,y(:,i)] = statespacemodel(A,B,C,D,uPID(:,i),dt,x);
        omega = y(2,i);
    end
    subplot(3,1,1);
    plot(t,uPID','-r', t,u', '--b');
    xlim([0,1]);ylim([-0.1,1.1]);
    subplot(3,1,2);
    plot(t,y(1:2,:));
    xlim([0,1]);ylim([-5,65]);
    subplot(3,1,3);
    plot(t,y(3,:));
    xlim([0,1]);ylim([-0.1,1]);
end
太郎くん
太郎くん

状態空間モデルとPID制御器とそれを取りまとめるコードの
合計3つのソースコードファイルで実現されてる感じか。

フクさん
フクさん

MATLABの場合、1関数1ソースコードの制約があるからね。
関数枚にファイルが分かれてる。

太郎くん
太郎くん

forループの中でPID制御器と状態空間モデルが動いてるね。
信号の繋ぎはローカル変数でやっているのか。

フクさん
フクさん

その通り。
ここらへんの構成はソースコードからでは読み取り難いから
最初に出した、全体構成と見比べながら確認すると良いだろう。

フクさん
フクさん

ちなみに、PID制御器では前回値を保持する必要あって、
そこはMATLABの構造体の機能を使っている。

太郎くん
太郎くん

あーこの部分だね。

    state.pzi = e_i;
    state.dzi = e_p;
    state.izi = u;
フクさん
フクさん

特に事前に構造体の定義とかは不要。
ちょっとした時に使うと便利だ。

シミュレーション結果

フクさん
フクさん

そしてシミュレーション結果は以下となる。

DCモータ状態空間モデルをPID制御(MATLAB)、target(t)、u(t)、ω(t)、θ(t)、I(t)
太郎くん
太郎くん

\(u(t)\)を見ると分かるけど、ちゃんとPID制御っぽいことしてるね。

フクさん
フクさん

\(u(t)\)の挙動は、PIDの各ゲインを調整すると変わるんで、
試してみると良いだろう。

太郎くん
太郎くん

これで、MATLAB上でのPID制御が確認できたってところだね。

フクさん
フクさん

この調子で他のツール、言語も確認していこう。

まとめ

フクさん
フクさん

まとめだよ。

  • PID制御器のブロック線図と全体構成を再掲。
  • 上記をMATLABで実現。
    • 接続に関してはコード上では分かり難いので全体構成図と見比べながら確認した方が良い。
  • シミュレーション実施。
    • u(t)の挙動と見るとPID制御っぽい挙動になっている。
      • 各PIDゲインを調整すると挙動が変わるはず。

バックナンバーはこちら。

コメント

タイトルとURLをコピーしました