如何使用 python 控制包正确绘制 MIMO 系统的阶跃响应

How to correctly plot the step response of a MIMO system with python control package

我需要用 python 控制包绘制 MIMO 系统的阶跃响应。

到目前为止,我已经尝试使用函数 step_response,但是在计算阶跃响应之前将系统转换为 SISO,因此只有一组计算输出。

然后我尝试使用函数 forced_response 和不同的输入设置(即恒定单位值,numpy 数组等...,只是为了尝试)。 我得到不同的阶跃响应,因此与其他输出相关,但不是所有响应(即输入数 x 输出数)。

这是实现具有 2 个输入和 4 个输出和虚拟数据的简单二阶模型的最小示例代码。在附件中我得到的回复图。

stepResponses

在我的测试中,我首先 运行 step_response 函数,yout 结果大小为 4 x size_time(所以只有前 4 个输出被激活)。

然后我 运行 forced_response 函数,并且 youtForced 仍然是大小 4 x size_time 的结果,而不是大小 4 x size_time x 2 (或类似)的结果,因为我预期(假设 forced_response 将系统视为 MIMO)。

有没有办法通过 forced_response 函数完全控制阶跃响应(类似于 MATLAB 阶跃函数的作用)?

不幸的是,关于这方面的文档很差,实际示例也很少。

非常感谢谁能提供帮助。

from control import ss, step_response, forced_response
import numpy as np
import matplotlib.pyplot as plt

sz = 2

f1 = 1*2*np.pi
f2 = 1.5*2*np.pi
OM2 = [-f1**2, -f2**2]
ZI = [-2*f1*0.01, -2*f2*0.01]

A11 = np.zeros((sz, sz))
A12 = np.eye(sz)
A21 = np.diag(OM2)
A22 = np.diag(ZI)

A = np.vstack((np.concatenate((A11, A12), axis=1), np.concatenate((A21, A22), axis=1)))

B1 = np.zeros((sz, sz))    
B2 = [[1e-6, 1e-7],[2e-6, 2e-7]]
B = np.vstack((B1, B2))

C1 = np.zeros((sz, sz*2))
C1[0] = [1e-4, 2*1e-4, 3*1e-4, 5*1e-5]
C1[1] = [2e-4, 3.5*1e-4, 1.5*1e-4, 2*1e-5]
C2 = np.zeros((sz*2, sz))
C = np.concatenate((C1.T, C2), axis=1)

D = np.zeros((sz*2, sz))

sys = ss(A, B, C, D)

tEnd = 1
time = np.arange(0, tEnd, 1e-3)
tout, youtStep = step_response(sys, T=time)
tout, youtForced, xout = forced_response(sys, T=time, U=1.0)
plt.figure()
for k, y in enumerate(youtStep):
    plt.subplot(4,1,k+1)
    plt.grid(True)
    plt.plot(tout, y,label='step')
    plt.plot(tout, youtForced[k], '--r',label='forced')
    if k == 0:
        plt.legend()
plt.xlabel('Time [s]')

好的,通过函数 control.matlab.step 可以轻松管理阶跃响应,它实际上允许选择 MIMO 系统的不同输入,我最初忽略了这一点,但在官方文档中得到了很好的报告:

https://python-control.readthedocs.io/en/0.8.1/generated/control.matlab.step.html

这是输出 [MIMO step response output]

幸运的是,这是一个简单的修复:)

from control import ss
import control.matlab as ctl
import numpy as np
import matplotlib.pyplot as plt

sz = 2

f1 = 1*2*np.pi
f2 = 1.5*2*np.pi
OM2 = [-f1**2, -f2**2]
ZI = [-2*f1*0.01, -2*f2*0.01]

A11 = np.zeros((sz, sz))
A12 = np.eye(sz)
A21 = np.diag(OM2)
A22 = np.diag(ZI)

A = np.vstack((np.concatenate((A11, A12), axis=1), np.concatenate((A21, A22), axis=1)))

B1 = np.zeros((sz, sz))    
B2 = [[1e-6, 1e-7],[2e-6, 2e-7]]
B = np.vstack((B1, B2))

C1 = np.zeros((sz, sz*2))
C1[0] = [1e-4, 2*1e-4, 3*1e-4, 5*1e-5]
C1[1] = [2e-4, 3.5*1e-4, 1.5*1e-4, 2*1e-5]
C2 = np.zeros((sz*2, sz))
C = np.concatenate((C1.T, C2), axis=1)

D = np.zeros((sz*2, sz))

sys = ss(A, B, C, D)

tEnd = 100
time = np.arange(0, tEnd, 1e-3)
yy1, tt1 = ctl.step(sys, T=time, input=0)
yy2, tt2 = ctl.step(sys, T=time, input=1)
plt.figure()
for k in range(0, len(yy1[1,:])):
    plt.subplot(4,1,k+1)
    plt.grid(True)
    plt.plot(tt1, yy1[:,k], label='input=0')
    plt.plot(tt2, yy2[:,k], label='input=1')
    if k == 0:
        plt.legend()
plt.xlabel('Time [s]')