講義14 最適制御
現代制御のひと段落が「最適制御」
評価関数と最適制御則
ここまでの状態フィードバックでは、極配置を行うことで、制御特性(収束具合)を調整できた
しかし、現実問題では、フィードバックゲインを大きくしすぎると、
アクチュエータがその出力を出せなかったり、負荷がかかったりで、実現できない
最適制御では以下の評価関数 を設定して、その値が最小となる制御を実現する
ここで は対角行列、 はスカラーとして、設定するパラメータになる
第1項が、計測値(状態量)の大きさ(2乗)を表し、
第2項が、出力(操作量)の大きさを表す
上記2つのパラメータの重みを割り振ることで、どちらを優先するかを設定できる
最適制御問題
上記の を最小とする制御パラメータ を求める
まずは、次のリカッチ代数方程式から行列を求める
また [tex: P = PT > 0] を満たす正定行列である
求まった から、 を下記で求める
これで、最適制御が実現できる
ちなみに、この時に評価関数は
になる
Pythonによる数値シミュレーション
2x2の以下のシステムでの最適制御を考える
この時、
とすると、リカッチ代数方程式は、
となり、結局、
となる
フィードバックは、
となる
t = [0.0] x1_arr = [-1.0] x2_arr = [ 0.0] u_arr = [] dt = 0.001 for i in range(10000): u_arr += [-(1 * x1_arr[-1] + 0.2915 * x2_arr[-1])] x1_arr += [x1_arr[-1] + (0 * x1_arr[-1] + 1 * x2_arr[-1] + 0.0 * u_arr[-1]) * dt] x2_arr += [x2_arr[-1] + (-6 * x1_arr[-1] - 5 * x2_arr[-1] + 1.0 * u_arr[-1]) * dt] t += [t[-1] + dt]
極配置法との比較
極を-3の重根にした場合、 となる
t = [0.0] x1_arr2 = [-1.0] x2_arr2 = [ 0.0] u_arr2 = [] dt = 0.001 for i in range(10000): u_arr2 += [-(3 * x1_arr2[-1] + 1 * x2_arr2[-1])] x1_arr2 += [x1_arr2[-1] + (0 * x1_arr2[-1] + 1 * x2_arr2[-1] + 0.0 * u_arr[-1]) * dt] x2_arr2 += [x2_arr2[-1] + (-6 * x1_arr2[-1] - 5 * x2_arr2[-1] + 1.0 * u_arr[-1]) * dt] t += [t[-1] + dt]
fig = plt.figure(figsize=(12, 4)) ax1 = fig.add_subplot(1, 3, 1) ax2 = fig.add_subplot(1, 3, 2, sharex=ax1) ax3 = fig.add_subplot(1, 3, 3, sharex=ax1) ax1.plot(t, x1_arr, '-', label='LQ') ax1.plot(t, x1_arr2, '--', label='pole') ax2.plot(t, x2_arr, '-', label='LQ') ax2.plot(t, x2_arr2, '--', label='pole') ax3.plot(t[1:], u_arr, '-', label='LQ') ax3.plot(t[1:], u_arr2, '--', label='pole') ax1.grid() ax1.legend() ax1.set_ylabel('$x_1(t)$') ax1.set_ylim(-1.2, 2.2) ax2.grid() ax2.legend() ax2.set_ylabel('$x_2(t)$') ax2.set_ylim(-1.2, 2.2) ax3.grid() ax3.legend() ax3.set_ylabel('$u(t)$') ax3.set_ylim(-0.1, 3.2) ax1.set_xlim(0, 5) fig.tight_layout()
最適制御では、出力が小さくできている
さらに出力を小さくする
パラメータを下記にする
フィードバックゲインは になる
t = [0.0] x1_arr3 = [-1.0] x2_arr3 = [ 0.0] u_arr3 = [] dt = 0.001 for i in range(10000): u_arr3 += [-(0.0277 * x1_arr3[-1] + 0.0387 * x2_arr3[-1])] x1_arr3 += [x1_arr3[-1] + (0 * x1_arr3[-1] + 1 * x2_arr3[-1] + 0.0 * u_arr3[-1]) * dt] x2_arr3 += [x2_arr3[-1] + (-6 * x1_arr3[-1] - 5 * x2_arr3[-1] + 1.0 * u_arr3[-1]) * dt] t += [t[-1] + dt]
fig = plt.figure(figsize=(5, 4)) ax1 = fig.add_subplot(1, 1, 1) ax1.plot(t, x1_arr, '-', label='$x_1$') ax1.plot(t, x2_arr, '--', label='$x_2$') ax1.grid() ax1.legend() ax1.set_xlim(0, 5) ax1.set_ylim(-1.2, 3.2) fig.tight_layout()
応答性はほぼ同じで、出力がかなり小さくなっている
参考文献
この記事は以下の書籍を参考にしましたが、
私の拙い知識で書いておりますので、誤り等ありましたらご指摘ください