当前位置: 首页>>代码示例>>用法及示例精选>>正文


python scipy signal.place_poles用法及代码示例

用法:

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

计算K使得特征值(A-点(B,K))=极点。

K是增益矩阵,例如线性系统描述的工厂AX+BU将具有closed-loop个极点,即特征值A - B*K,尽可能接近两极要求的位置。

支持SISO,MISO和MIMO系统。

参数:

A, Bndarray

State-space线性系统的表示AX + BU

polesarray_like

所需的实极和/或复共轭极。仅支持复杂极点method="YT"(默认)。

method:{‘YT’, ‘KNV0’}, optional

选择哪种方法来找到增益矩阵K。

  • ‘YT’:Yang Tits

  • ‘KNV0’:Kautsky, Nichols, Van Dooren update method 0

有关算法的详细信息,请参见参考和注释。

rtol:float, optional

每次迭代后,特征向量的行列式A - B*K将其与之前的值进行比较,当这两个值之间的相对误差变得小于rtol时,算法将停止。默认值为1e-3。

maxiter:int, optional

计算增益矩阵的最大迭代次数。默认值为30。

返回值:

full_state_feedback束对象
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(请参阅注释)

olfloat

达到的相对公差det(X)(请参阅注释)。如果有可能解决系统问题,则rtol将为NaNdiag(poles) = (A - B*K),或0,表示优化算法无法执行任何操作,即B.shape[1] == 1

nb_iterint

收敛之前执行的迭代次数。如果有可能解决系统,则nb_iter将为NaNdiag(poles) = (A - B*K),或0,表示优化算法无法执行任何操作,即B.shape[1] == 1

注意:

山雀与杨(YT),[2]本文是原始Kautsky等人的更新。 (KNV)纸[1]。 KNV依靠等级1更新来找到传输矩阵XX * diag(poles) = (A - B*K)*X,而YT使用等级2更新。平均而言,这会产生更强大的解决方案(请参阅[2]pp 21-22),此外,YT算法支持复杂极点,而KNV不支持其原始版本。这里仅实现了KNV提出的更新方法0,因此名称为'KNV0'

Matlab的KNV扩展到复杂的极点place函数,YT在Slicot的非免费许可下以名称进行分发robpole。尚不清楚和没有记载KNV0如何扩展到复数极点(Tits和Yang在其论文的第14页上声称不能使用其方法将KNV扩展到复数极点),因此在此实现中仅YT支持它们。

由于极点放置问题的解决方案对于MIMO系统而言并非唯一,因此这两种方法均以暂定传输矩阵开始,并以各种方式对其进行更改以增加其行列式。已经证明这两种方法都可以收敛到稳定的解,但是根据选择初始传递矩阵的方式,它们将收敛到不同的解,因此绝对不能保证使用'KNV0'产生的结果类似于Matlab或这些算法的任何其他实现。

使用默认方法'YT'在大多数情况下应该很好;'KNV0'仅由于需要它而提供'YT'在某些特定情况下。此外'YT'平均而言,比'KNV0'abs(det(X))用作稳健性指标。

[2]可通过以下网址获得技术报告:https://hdl.handle.net/1903/5598

参考文献:

1(12)

J.考茨基(N.K.) Nichols和P. van Dooren,“线性状态反馈中的鲁棒极点分配”,国际控制杂志,第1卷。 1985年,第41页,第1129-1155页。

2(123)

A.L. Tits和Y. Yang,“通过状态反馈实现鲁棒极点分配的全球收敛算法”,IEEE自动控制学报,第1卷。 41,第1432-1452页,1996年。

例子:

一个使用KNV和YT算法演示实际磁极位置的简单示例。这是参考KNV出版物第4节中的示例1([1]):

>>> 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方法计算K,同时强制执行该算法的100次迭代,并在每次调用后打印一些结果。

>>> 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

源码:

scipy.signal.place_poles的API实现见:[源代码]

注:本文由纯净天空筛选整理自 scipy.signal.place_poles。非经特殊声明,原始代码版权归原作者所有,本译文的传播和使用请遵循“署名-相同方式共享 4.0 国际 (CC BY-SA 4.0)”协议。