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 会有它的闭环极点,也就是特征值 A - B*K ,尽可能接近杆子上要求的那些。

支持SISO、MISO和MIMO系统。

参数
A, Bndarray

线性系统的状态空间表示 AX + BU

polesarray_like

所需的实极和/或复共轭极。仅在以下情况下才支持复杂电杆 method="YT" (默认)。

方法:{{‘YT’,‘KNV0’}},可选

选择哪种方法来查找增益矩阵K。以下方法之一:

  • “YT”:阳咪咪

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

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

rtol:浮点,可选

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

maxiter:int,可选

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

退货
full_state_feedback簇对象
FULL_STATE_REFESSION由以下内容组成:
gain_matrix一维ndarray

闭环矩阵K,如的特征值 A-BK 尽可能靠近要求的极点。

computed_poles一维ndarray

对应于 A-BK 先将实极按升序排序,然后按字典顺序连在一起。

requested_poles一维ndarray

算法被要求放置的极点如上所述排序,它们可能与所获得的结果不同。

X二维ndarray

传输矩阵,例如 X * diag(poles) = (A - B*K)*X (请参阅注释)

rtol浮动

上达到的相对公差 det(X) (请参阅注释)。 rtol 如果有可能解决这个系统,我将是NaN diag(poles) = (A - B*K) ,或者当优化算法不能做任何事情时为0,即当 B.shape[1] == 1

nb_iter集成

收敛前执行的迭代次数。 nb_iter 如果有可能解决这个系统,我将是NaN diag(poles) = (A - B*K) ,或者当优化算法不能做任何事情时为0,即当 B.shape[1] == 1

注意事项

蒂斯与杨(The Tits and Yang,YT), [2] 论文是对最初的考茨基等人的更新。(KNV)纸 [1]. KNV依赖于秩1更新来找到传递矩阵X X * diag(poles) = (A - B*K)*X ,而YT使用秩2更新。这平均可产生更强大的解决方案(请参见 [2] PP21-22),此外,YT算法支持复极点,而KNV在其原始版本中不支持。这里只实现了KNV提出的更新方法0,因此得名 'KNV0'

扩展到复极的KNV在Matlab中使用 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(1,2)

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

2(1,2,3)

Tits,Y.Yang,“状态反馈鲁棒极点配置的全局收敛算法”,“IEEE自动控制学报”,第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