Matlab_Simulink:PIDゲイン最適化プログラム④_様々な評価規範(無料公開)

実現したいこと

  • Simulinkとmファイルを用いたPID制御シミュレータの構築
  • 上記プログラムのPIDゲインの最適化
  • fminsearchを使っての最適化
  • 評価規範:IAE, ITAEによる最適化結果の比較

Matlabのバージョン

Matlab2021a
※ダウンロード形式として過去のバージョンも用意

必要なtoolbox

ダウンロードURL

【ダウンロードリンク】

PID_Control_fmin_IAE_ITAE - Google ドライブ

※ご利用中のMatlabバージョンのフォルダをダウンロードしてください。
 例:2021aバージョンであれば,上記リンクの「2021a」を選択
※上記プログラムの利用で生じたトラブルは一切の責任を負いかねます

フォルダ構成

上記ダウンロードし展開。
(下記のようなフォルダ構成になっていることを確認)

実行方法

「Main_PID_fmin_input_IAE_ITAE.m」を実行
Simulinkを閉じると最適化計算は非常に速くなります。

Simulinkファイル(I_PD.slx)

mファイルソースコード(Main_PID_fmin_input_satu_IAE_ITAE.m)

※下記赤文字が過去の記事からの変更点

%% 初期化
clc % コマンドウィンドウの初期化
clear % ワークスペースの初期化
close all % グラフを全部閉じる

%% 変数宣言
% ===== 制御対象 =====
K = 1;
A = 1;
B = 1;
C = 1;
% ===== 目標値 =====
r_val = 10; % ステップ状の目標値
% ===== Simulink関係 =====
N_File = 'I_PD.slx'; % simulinkファイル名
FinalTime = 10; % シミュレーション終了時刻[s]
SamplingTime = 0.01; % サンプリング時間[s]
% ===== 推定システムゲイン =====
K_hat = K; % fminsearchで偏差と入力の値のオーダーを一致させることに利用

%% fminsearch
ini_x = [1.5 1.5, 1.5]; % PIDゲインの初期値

% ===== 評価規範:IAE =====
[x_IAE, fval] = fminsearch(@(x) func_fmin_input_IAE(x,N_File,K_hat),ini_x);
sim(N_File); % Simulinkの実行
% ===== Simulinkデータ格納 =====
t_IAE = ScopeData.time; % 時刻情報
y_IAE = ScopeData.signals(1).values(:, 1); % 出力
r_IAE = ScopeData.signals(1).values(:, 2); % 目標値
u_IAE = ScopeData.signals(2).values(:, 1); % 入力

% ===== 評価規範:ITAE =====
[x_ITAE, fval] = fminsearch(@(x) func_fmin_input_ITAE(x,N_File,K_hat),ini_x);
open(N_File); % Simulinkを起動
sim(N_File); % Simulinkの実行
% ===== Simulinkデータ格納 =====
t_ITAE = ScopeData.time; % 時刻情報
y_ITAE = ScopeData.signals(1).values(:, 1); % 出力
r_ITAE = ScopeData.signals(1).values(:, 2); % 目標値
u_ITAE = ScopeData.signals(2).values(:, 1); % 入力

%% グラフ化
% ===== グラフ描画 =====
% ----- y -----
figure;
subplot(211);
plot(t_IAE,y_IAE,'b');
hold on;
plot(t_ITAE,y_ITAE,'r--');
hold on;
plot(t_IAE,r_IAE,'k:');
grid on;
xlabel('$ t {\rm [s]} $', 'interpreter', 'latex');
ylabel('$ y(t) $', 'interpreter', 'latex');
legend('$ y_{IAE}(t) $', '$ y_{ITAE}(t) $', '$ r(t) $', 'interpreter', 'latex');
% ----- u -----
subplot(212);
plot(t_IAE,u_IAE,'b');
hold on;
plot(t_ITAE,u_ITAE,'r--');
grid on;
xlabel('$ t {\rm [s]} $', 'interpreter', 'latex');
ylabel('$ u(t) $', 'interpreter', 'latex');
legend('$ u_{IAE}(t) $', '$ u_{ITAE}(t) $', 'interpreter', 'latex');

mファイルソースコード(func_fmin_input_IAE.m)

function f = func_fmin_input_IAE(x,N_File,K_hat)
%% 変数宣言
Kp = x(1);
Ki = x(2);
Kd = x(3);
assignin('base','Kp',Kp);
assignin('base','Ki',Ki);
assignin('base','Kd',Kd);
% Simulink実行
sim(N_File);

%% Scopeデータの取得
t = ScopeData.time; % 時刻情報
y = ScopeData.signals(1).values(:, 1); % 出力
r = ScopeData.signals(1).values(:, 2); % 目標値
u = ScopeData.signals(2).values(:, 1); % 入力

%% 評価規範
% 入力の整定値u(end), K_hatを導入することで,偏差(r-y)と同じオーダーにする
f = sum(abs(r-y) + abs(K_hat.*(u(end)-u)));
%% コマンドウィンドウ表示
fprintf('[Kp, Ki, Kd, fval] = %.3g, %.3g, %.3g, %.3g\n',Kp, Ki, Kd, f);

mファイルソースコード(func_fmin_input_ITAE.m)

function f = func_fmin_input_IAE(x,N_File,K_hat)
%% 変数宣言
Kp = x(1);
Ki = x(2);
Kd = x(3);
assignin('base','Kp',Kp);
assignin('base','Ki',Ki);
assignin('base','Kd',Kd);
% Simulink実行
sim(N_File);

%% Scopeデータの取得
t = ScopeData.time; % 時刻情報
y = ScopeData.signals(1).values(:, 1); % 出力
r = ScopeData.signals(1).values(:, 2); % 目標値
u = ScopeData.signals(2).values(:, 1); % 入力

%% 評価規範
% 入力の整定値u(end), K_hatを導入することで,偏差(r-y)と同じオーダーにする
f = sum(t.*(abs(r-y) + abs(K_hat.*(u(end)-u))));
%% コマンドウィンドウ表示
fprintf('[Kp, Ki, Kd, fval] = %.3g, %.3g, %.3g, %.3g\n',Kp, Ki, Kd, f);

実行結果

まとめ・考察

上記の結果の通りIAE, ITAEの結果を比較すると

  • IAE:入力は穏やかだが,オーバーシュートが発生
  • ITAE:オーバーシュートは発生しないが,IAEより大きい入力が印加

という特徴が確認できる。このとき,利用している評価規範を下記に示す。

※下記は筆者が個人的に好んでいる評価規範であり,学術的な議論は別途必要である。
【入力項を考慮したIAE:Integral of Absolute Error】
 f_{IAE} = \sum_{t=0}^{N} (| r(t) - y(t) | + \hat{K}|u_{final}-u(t)|)

【入力項を考慮したITAE:Integral of Time weighted Absolute Error】
 f_{ITAE} = \sum_{t=0}^{N} t(| r(t) - y(t) |  + \hat{K}|u_{final}-u(t)|)

このとき, \hat{K}は推定システムゲイン, u_{final}は入力の整定値である。偏差 (r-y)と入力のオーダーを揃えるために \hat{K}, u_{final}を導入している。

(参考過去記事:入力を考慮した最適化

上記の評価規範の通り,ITAEは時刻 tの重みが付加されているため,IAEに比べ時間が経過した際の偏差を許さない。したがってオーバーシュートがない応答が得られたと考えられる(言い換えれば,前半は軽視するため,序盤に入力を過度に印加している)。

一方,読者の中には,入力を考慮しない下記の「通常のIAE, ITAE」の結果が気になると考えられる。

【IAE:Integral of Absolute Error】
 f_{IAE} = \sum_{t=0}^{N} | r(t) - y(t) |

【ITAE:Integral of Time weighted Absolute Error】
 f_{ITAE} = \sum_{t=0}^{N} t| r(t) - y(t) |

上記評価規範を最小化した場合の制御結果を下図に示す。入力を考慮していないため,両者同一の最適結果である「1ステップで偏差がゼロになるような制御結果」に近づいており,両者の違いがないことが確認できる。

これまでの記事では,伝達関数など数式を用いない最適化手法の紹介であったが,次回の記事では,伝達関数(規範モデル)を用いたPIDゲイン決定法について執筆予定である。

併せて確認推奨の過去記事

forfree.hatenablog.jp 

forfree.hatenablog.jp

forfree.hatenablog.jp