- 実現したいこと
- Matlabのバージョン
- 必要なtoolbox
- ダウンロードURL
- フォルダ構成
- 実行方法
- Simulinkファイル(PID_fmin.slx)
- mファイルソースコード(Main_PID_fmin_input.m)
- mファイルソースコード(func_fmin_input.m)
- 実行結果
- まとめ・考察
- 併せて確認推奨の過去記事
実現したいこと
- Simulinkとmファイルを用いたPID制御シミュレータの構築
- 上記プログラムのPIDゲインの最適化
- fminsearchを使っての最適化
- 過大な入力が印加されないような最適化
Matlabのバージョン
Matlab2021a
※ダウンロード形式として過去のバージョンも用意
必要なtoolbox
ダウンロードURL
【ダウンロードリンク】
※ご利用中のMatlabバージョンのフォルダをダウンロードしてください。
例:2021aバージョンであれば,上記リンクの「2021a」を選択
※上記プログラムの利用で生じたトラブルは一切の責任を負いかねます。
フォルダ構成
上記ダウンロードし展開。
(下記のようなフォルダ構成になっていることを確認)
実行方法
「Main_PID_fmin_input.m」を実行
※PCスペックに依って最適化計算に5分程度時間がかかります。
Simulinkファイル(PID_fmin.slx)
mファイルソースコード(Main_PID_fmin_input.m)
%% 初期化clc % コマンドウィンドウの初期化clear % ワークスペースの初期化close all % グラフを全部閉じる%% 変数宣言% ===== 制御対象 =====K = 1;A = 1;B = 1;C = 1;% ===== 目標値 =====r_val = 10; % ステップ状の目標値% ===== Simulink関係 =====N_File = 'PID_fmin.slx'; % simulinkファイル名FinalTime = 30; % シミュレーション終了時刻[s]SamplingTime = 0.1; % サンプリング時間[s]% ===== 推定システムゲイン =====K_hat = K; % fminsearchで偏差と入力の値のオーダーを一致させることに利用%% fminsearchini_x = [0.5 0.5, 0.5]; % PIDゲインの初期値[x, fval] = fminsearch(@(x) func_fmin_input(x,N_File,K_hat),ini_x);%% Simulinkの実行open(N_File); % Simulinkを起動sim(N_File); % Simulinkの実行%% グラフ化% ===== Simulinkデータ格納 =====t = ScopeData.time; % 時刻情報y = ScopeData.signals(1).values(:, 1); % 出力r = ScopeData.signals(1).values(:, 2); % 目標値u = ScopeData.signals(2).values(:, 1); % 入力% ===== グラフ描画 =====% ----- y -----figure;subplot(211);plot(t,y);hold on;plot(t,r,'--');grid on;xlabel('$ t {\rm [s]} $', 'interpreter', 'latex');ylabel('$ y(t) $', 'interpreter', 'latex');legend('$ y(t) $', '$ r(t) $', 'interpreter', 'latex');% ----- u -----subplot(212);plot(t,u);hold on;grid on;xlabel('$ t {\rm [s]} $', 'interpreter', 'latex');ylabel('$ u(t) $', 'interpreter', 'latex');
mファイルソースコード(func_fmin_input.m)
function f = func_fmin(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( ( r-y ).^2 ) + ( K_hat.*(u(end)-u)).^2 );
%% コマンドウィンドウ表示fprintf('[Kp, Ki, Kd, fval] = %.3g, %.3g, %.3g, %.3g\n',Kp, Ki, Kd, f);
実行結果
まとめ・考察
今回の最適化評価関数は下記の通り。
【最小化する評価関数】
このとき,は推定システムゲイン,は入力の整定値である。偏差と入力のオーダーを揃えるためにを導入している。
もし,を真値の10分の1と見積もった場合(=0.1K)は下記のグラフが取得され,入力の変動が大きくなることを確認できる。
次回の記事では入力飽和がある場合について執筆予定である。