Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create LTI system in Python from state matrices using scipy.signal.lti

scipy.signal.lti claims to be able to accept four arrays, A, B, C, and D, to define a system (in addition to other methods). However, it gives me an error, and I can find no examples illustrating this.

My code is simply:

A=np.array([[0,0,1,0],[0,0,0,1],[-2,1,-.02,.01],[1,-2,.01,-.02]])
B=np.array([[0],[0],[-1],[0]])
C=np.array([[0,0,1,0],[0,0,0,1]])
D=np.array([[0],[0]])
sys=scipy.signal.lti(A,B,C,D) #spelled out

with the error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/scipy/signal/ltisys.py", line 317, in __init__
    self._update(N)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/scipy/signal/ltisys.py", line 428, in _update
    self.C, self.D)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/scipy/signal/ltisys.py", line 259, in ss2zpk
    return tf2zpk(*ss2tf(A, B, C, D, input=input))
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/scipy/signal/filter_design.py", line 315, in tf2zpk
    z = roots(b)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/numpy/lib/polynomial.py", line 203, in roots
    raise ValueError("Input must be a rank-1 array.")
ValueError: Input must be a rank-1 array.

What am I missing here? The matrix (array) sizes are correct.

like image 699
Joseph C. Slater Avatar asked Apr 15 '15 20:04

Joseph C. Slater


1 Answers

In the state-space representation, your input vector D has a size 2, which means that this control system has 2 output variables. I believe this is not supported by the current implementation of scipy.signal.lti.

For instance, the following input, with one output variable does work.

C=np.array([[0,0,1,0]])
D=np.array([[0]])

Further details. The issue is in that with your original input parameters,

num, den =  scipy.signal.ss2tf(A, B, C, D)

gives a 1D array for the denominator, but a 2D array for the numerator (i.e. several of them, since there are multiple output variables). But then scipy.signal.tf2zpk(num, den) expects both num and den to be just polynomials (i.e. 1D arrays). Hence, the failure to initialize the lte class.

like image 91
rth Avatar answered Oct 11 '22 10:10

rth