講義11 オブザーバの設計
現代制御のすごいところ
状態ベクトルが観測できない場合でも、オブザーバを用いれば推定することができる
さらに面白いのは、状態フィードバックと同じ理論で、推定の可能性や速度・精度を設定できる
オブザーバの構成
状態フィードバック制御を行う上で、 の全成分が計測できない場合がある
その場合、オブザーバを用いて、 を推定することで、フィードバック制御を行う
この場合、状態フィードバック制御は、となり、
となる
ここで、オブザーバとして、下記の微分方程式で を推定する
この場合、推定誤差 は
となり、状態フィードバックと同様に、
の固有値を極配置することで、
と収束させることができる
状態遷移図で表すと下図になる
設定したシステムモデルの出力と実際の計測値 の差分を オブザーバゲイン でフィードバックしている
Pythonによる数値シミュレーション
2x2の以下のシステムの自由応答における状態ベクトルを推定する
例11.1
となり、オブザーバは下記になる
xhat1_arr = [0.0] xhat2_arr = [0.0] t = [0.0] x1_arr = [1.0] x2_arr = [1.0] dt = 0.001 for i in range(10000): x1_arr += [x1_arr[-1] + (0 * x1_arr[-1] + 1 * x2_arr[-1]) * dt] x2_arr += [x2_arr[-1] + (-6 * x1_arr[-1] - 5 * x2_arr[-1]) * dt] t += [t[-1] + dt] y = 1.0 * x1_arr[-1] + 0.0 * x2_arr[-1] xhat1_arr += [xhat1_arr[-1] + (0 * xhat1_arr[-1] + 1 * xhat2_arr[-1] + (-2.0) * (y - (1.0 * xhat1_arr[-1] + 0.0 * xhat2_arr[-1]))) * dt] xhat2_arr += [xhat2_arr[-1] + (-6 * xhat1_arr[-1] - 5 * xhat2_arr[-1] + ( 6.0) * (y - (1.0 * xhat1_arr[-1] + 0.0 * xhat2_arr[-1]))) * dt]
fig = plt.figure(figsize=(9, 4)) ax1 = fig.add_subplot(1, 2, 1) ax2 = fig.add_subplot(1, 2, 2) ax1.plot(t, x1_arr, '-', label='$x_1$') ax1.plot(t, x2_arr, '--', label='$x_2$') ax1.plot(t, xhat1_arr, ':', label='$\hat{x}_1$') ax1.plot(t, xhat2_arr, '-.', label='$\hat{x}_2$') ax1.grid() ax1.legend() ax1.set_xlim(0, 10) ax1.set_ylim(-1.0, 3.0) ax2.plot(t, np.array(xhat1_arr) - np.array(x1_arr), '-', label='$e_1$') ax2.plot(t, np.array(xhat2_arr) - np.array(x2_arr), '--', label='$e_2$') ax2.grid() ax2.legend() ax2.set_xlim(0, 10) ax2.set_ylim(-2.0, 4.0) fig.tight_layout()
例11.3
xhat1_arr = [0.0] xhat2_arr = [0.0] t = [0.0] x1_arr = [1.0] x2_arr = [1.0] dt = 0.001 for i in range(10000): x1_arr += [x1_arr[-1] + (0 * x1_arr[-1] + 1 * x2_arr[-1]) * dt] x2_arr += [x2_arr[-1] + (-6 * x1_arr[-1] - 5 * x2_arr[-1]) * dt] t += [t[-1] + dt] y = 1.0 * x1_arr[-1] + 0.0 * x2_arr[-1] xhat1_arr += [xhat1_arr[-1] + (0 * xhat1_arr[-1] + 1 * xhat2_arr[-1] + (12.0) * (y - (1.0 * xhat1_arr[-1] + 0.0 * xhat2_arr[-1]))) * dt] xhat2_arr += [xhat2_arr[-1] + (-6 * xhat1_arr[-1] - 5 * xhat2_arr[-1] + ( 6.0) * (y - (1.0 * xhat1_arr[-1] + 0.0 * xhat2_arr[-1]))) * dt]
fig = plt.figure(figsize=(9, 4)) ax1 = fig.add_subplot(1, 2, 1) ax2 = fig.add_subplot(1, 2, 2) ax1.plot(t, x1_arr, '-', label='$x_1$') ax1.plot(t, x2_arr, '--', label='$x_2$') ax1.plot(t, xhat1_arr, ':', label='$\hat{x}_1$') ax1.plot(t, xhat2_arr, '-.', label='$\hat{x}_2$') ax1.grid() ax1.legend() ax1.set_xlim(0, 10) ax1.set_ylim(-1.0, 3.0) ax2.plot(t, np.array(xhat1_arr) - np.array(x1_arr), '-', label='$e_1$') ax2.plot(t, np.array(xhat2_arr) - np.array(x2_arr), '--', label='$e_2$') ax2.grid() ax2.legend() ax2.set_xlim(0, 10) ax2.set_ylim(-2.0, 4.0) fig.tight_layout()
状態フィードバック制御と同様、極配置を負に大きくすると、より早く収束する
例11.4
xhat1_arr = [0.0] xhat2_arr = [0.0] t = [0.0] x1_arr = [1.0] x2_arr = [1.0] dt = 0.001 for i in range(10000): x1_arr += [x1_arr[-1] + (0 * x1_arr[-1] + 1 * x2_arr[-1]) * dt] x2_arr += [x2_arr[-1] + (-6 * x1_arr[-1] - 5 * x2_arr[-1]) * dt] t += [t[-1] + dt] y = 1.0 * x1_arr[-1] + 0.0 * x2_arr[-1] xhat1_arr += [xhat1_arr[-1] + (0 * xhat1_arr[-1] + 1 * xhat2_arr[-1] + ( 5.0) * (y - (1.0 * xhat1_arr[-1] + 0.0 * xhat2_arr[-1]))) * dt] xhat2_arr += [xhat2_arr[-1] + (-6 * xhat1_arr[-1] - 5 * xhat2_arr[-1] + (30.0) * (y - (1.0 * xhat1_arr[-1] + 0.0 * xhat2_arr[-1]))) * dt]
fig = plt.figure(figsize=(9, 4)) ax1 = fig.add_subplot(1, 2, 1) ax2 = fig.add_subplot(1, 2, 2) ax1.plot(t, x1_arr, '-', label='$x_1$') ax1.plot(t, x2_arr, '--', label='$x_2$') ax1.plot(t, xhat1_arr, ':', label='$\hat{x}_1$') ax1.plot(t, xhat2_arr, '-.', label='$\hat{x}_2$') ax1.grid() ax1.legend() ax1.set_xlim(0, 10) ax1.set_ylim(-1.0, 3.0) ax2.plot(t, np.array(xhat1_arr) - np.array(x1_arr), '-', label='$e_1$') ax2.plot(t, np.array(xhat2_arr) - np.array(x2_arr), '--', label='$e_2$') ax2.grid() ax2.legend() ax2.set_xlim(0, 10) ax2.set_ylim(-2.0, 4.0) fig.tight_layout()
虚部を持つと発振成分が生じる
参考文献
この記事は以下の書籍を参考にしましたが、
私の拙い知識で書いておりますので、誤り等ありましたらご指摘ください