scipy.signal.

place_poles#

scipy.signal.place_poles(A, B, poles, method='YT', rtol=0.001, maxiter=30)[source]#

計算 K 使得特徵值 (A - dot(B, K))=poles。

K 是增益矩陣,使得由線性系統 AX+BU 描述的系統,其閉迴路極點,即特徵值 A - B*K,將盡可能接近在 poles 中要求的極點。

支援 SISO、MISO 和 MIMO 系統。

參數:
A, Bndarray

線性系統 AX + BU 的狀態空間表示。

polesarray_like

期望的實極點和/或複共軛極點。 只有在 method="YT" (預設) 的情況下才支援複數極點。

method: {‘YT’, ‘KNV0’}, 選項

選擇哪種方法來找到增益矩陣 K。選項之一:

  • ‘YT’:Yang Tits

  • ‘KNV0’:Kautsky、Nichols、Van Dooren 更新方法 0

請參閱「參考文獻」和「註解」以了解演算法的詳細資訊。

rtol: float, 選項

在每次迭代後,A - B*K 的特徵向量的行列式會與其先前的值進行比較,當這兩個值之間的相對誤差低於 rtol 時,演算法會停止。預設值為 1e-3。

maxiter: int, 選項

計算增益矩陣的最大迭代次數。預設值為 30。

回傳值:
full_state_feedbackBunch 物件
full_state_feedback 由以下組成
gain_matrix1-D ndarray

閉迴路矩陣 K,使得 A-BK 的特徵值盡可能接近要求的極點。

computed_poles1-D ndarray

對應於 A-BK 的極點,排序方式為先將實極點按遞增順序排列,然後將複共軛極點按字典順序排列。

requested_poles1-D ndarray

演算法要求放置的極點,以上述方式排序,它們可能與實際達成的結果不同。

X2-D ndarray

轉移矩陣,例如 X * diag(poles) = (A - B*K)*X (請參閱「註解」)

rtolfloat

det(X) 上達成的相對容忍度(請參閱「註解」)。如果可以解系統 diag(poles) = (A - B*K),則 rtol 將為 NaN;或者當最佳化演算法無法執行任何操作時(即當 B.shape[1] == 1 時),則為 0。

nb_iterint

收斂前執行的迭代次數。如果可以解系統 diag(poles) = (A - B*K),則 nb_iter 將為 NaN;或者當最佳化演算法無法執行任何操作時(即當 B.shape[1] == 1 時),則為 0。

註解

Tits 和 Yang (YT), [2] 的論文是對原始 Kautsky et al. (KNV) 論文 [1] 的更新。 KNV 依賴秩 1 更新來找到轉移矩陣 X,使得 X * diag(poles) = (A - B*K)*X,而 YT 使用秩 2 更新。這平均產生更穩健的解決方案(請參閱 [2] pp 21-22),此外,YT 演算法支援複數極點,而 KNV 在其原始版本中則不支援。 此處僅實作 KNV 提出的更新方法 0,因此名稱為 'KNV0'

擴展到複數極點的 KNV 用於 Matlab 的 place 函數中,YT 由 Slicot 以非免費許可證發行,名稱為 robpole。 目前尚不清楚且未記錄 KNV0 如何擴展到複數極點(Tits 和 Yang 在他們的論文第 14 頁中聲稱他們的方法不能用於將 KNV 擴展到複數極點),因此在此實作中只有 YT 支援它們。

由於 MIMO 系統的極點放置問題的解決方案不是唯一的,因此兩種方法都從一個試探性的轉移矩陣開始,該矩陣以各種方式更改以增加其行列式。 兩種方法都已被證明可以收斂到穩定的解決方案,但是,根據初始轉移矩陣的選擇方式,它們將收斂到不同的解決方案,因此絕對不能保證使用 'KNV0' 會產生類似於 Matlab 或任何其他這些演算法實作的結果。

在大多數情況下,使用預設方法 'YT' 應該沒問題; 提供 'KNV0' 只是因為在某些特定情況下 'YT' 需要它。 此外,當 abs(det(X)) 用作穩健性指標時,'YT' 平均比 'KNV0' 產生更穩健的結果。

[2] 可在以下 URL 作為技術報告取得: https://hdl.handle.net/1903/5598

參考文獻

[1] (1,2)

J. Kautsky、N.K. Nichols 和 P. van Dooren,“線性狀態回饋中的穩健極點配置”,《國際控制雜誌》,第 41 卷,第 1129-1155 頁,1985 年。

[2] (1,2,3)

A.L. Tits 和 Y. Yang,“用於狀態回饋穩健極點配置的全局收斂演算法”,《IEEE 自動控制彙刊》,第 41 卷,第 1432-1452 頁,1996 年。

範例

一個簡單的範例,示範使用 KNV 和 YT 演算法進行實極點放置。 這是參考 KNV 出版物 ([1]) 第 4 節中的範例 1。

>>> import numpy as np
>>> from scipy import signal
>>> import matplotlib.pyplot as plt
>>> A = np.array([[ 1.380,  -0.2077,  6.715, -5.676  ],
...               [-0.5814, -4.290,   0,      0.6750 ],
...               [ 1.067,   4.273,  -6.654,  5.893  ],
...               [ 0.0480,  4.273,   1.343, -2.104  ]])
>>> B = np.array([[ 0,      5.679 ],
...               [ 1.136,  1.136 ],
...               [ 0,      0,    ],
...               [-3.146,  0     ]])
>>> P = np.array([-0.2, -0.5, -5.0566, -8.6659])

現在使用 KNV 方法 0、預設 YT 方法以及 YT 方法(同時強制演算法執行 100 次迭代)計算 K,並在每次呼叫後列印一些結果。

>>> fsf1 = signal.place_poles(A, B, P, method='KNV0')
>>> fsf1.gain_matrix
array([[ 0.20071427, -0.96665799,  0.24066128, -0.10279785],
       [ 0.50587268,  0.57779091,  0.51795763, -0.41991442]])
>>> fsf2 = signal.place_poles(A, B, P)  # uses YT method
>>> fsf2.computed_poles
array([-8.6659, -5.0566, -0.5   , -0.2   ])
>>> fsf3 = signal.place_poles(A, B, P, rtol=-1, maxiter=100)
>>> fsf3.X
array([[ 0.52072442+0.j, -0.08409372+0.j, -0.56847937+0.j,  0.74823657+0.j],
       [-0.04977751+0.j, -0.80872954+0.j,  0.13566234+0.j, -0.29322906+0.j],
       [-0.82266932+0.j, -0.19168026+0.j, -0.56348322+0.j, -0.43815060+0.j],
       [ 0.22267347+0.j,  0.54967577+0.j, -0.58387806+0.j, -0.40271926+0.j]])

X 的行列式的絕對值是檢查結果穩健性的良好指標,'KNV0''YT' 的目標都是最大化它。 以下是上述結果穩健性的比較

>>> abs(np.linalg.det(fsf1.X)) < abs(np.linalg.det(fsf2.X))
True
>>> abs(np.linalg.det(fsf2.X)) < abs(np.linalg.det(fsf3.X))
True

現在是一個關於複數極點的簡單範例

>>> A = np.array([[ 0,  7/3.,  0,   0   ],
...               [ 0,   0,    0,  7/9. ],
...               [ 0,   0,    0,   0   ],
...               [ 0,   0,    0,   0   ]])
>>> B = np.array([[ 0,  0 ],
...               [ 0,  0 ],
...               [ 1,  0 ],
...               [ 0,  1 ]])
>>> P = np.array([-3, -1, -2-1j, -2+1j]) / 3.
>>> fsf = signal.place_poles(A, B, P, method='YT')

我們可以在複數平面上繪製期望的和計算的極點

>>> t = np.linspace(0, 2*np.pi, 401)
>>> plt.plot(np.cos(t), np.sin(t), 'k--')  # unit circle
>>> plt.plot(fsf.requested_poles.real, fsf.requested_poles.imag,
...          'wo', label='Desired')
>>> plt.plot(fsf.computed_poles.real, fsf.computed_poles.imag, 'bx',
...          label='Placed')
>>> plt.grid()
>>> plt.axis('image')
>>> plt.axis([-1.1, 1.1, -1.1, 1.1])
>>> plt.legend(bbox_to_anchor=(1.05, 1), loc=2, numpoints=1)
../../_images/scipy-signal-place_poles-1.png