8000 BUG: allow state-space to transfer function conversion of static gains · python-control/python-control@d9aaa8f · GitHub
[go: up one dir, main page]

Skip to content

Commit d9aaa8f

Browse files
committed
BUG: allow state-space to transfer function conversion of static gains
1 parent e3c0f79 commit d9aaa8f

File tree

2 files changed

+65
-34
lines changed

2 files changed

+65
-34
lines changed

control/tests/convert_test.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,29 @@ def testTf2ssStaticMimo(self):
206206
d = np.matrix([[0.5, 30, 0.0625], [-0.5, -1.25, 101.3]])
207207
np.testing.assert_array_equal(d, gmimo.D)
208208

209+
def testSs2tfStaticSiso(self):
210+
"""Regression: ss2tf for SISO static gain"""
211+
import control
212+
gsiso = control.ss2tf(control.ss([], [], [], 0.5))
213+
np.testing.assert_array_equal([[[0.5]]], gsiso.num)
214+
np.testing.assert_array_equal([[[1.]]], gsiso.den)
215+
216+
def testSs2tfStaticMimo(self):
217+
"""Regression: ss2tf for MIMO static gain"""
218+
import control
219+
# 2x3 TFM
220+
a = []
221+
b = []
222+
c = []
223+
d = np.matrix([[0.5, 30, 0.0625], [-0.5, -1.25, 101.3]])
224+
gtf = control.ss2tf(control.ss(a,b,c,d))
225+
226+
# we need a 3x2x1 array to compare with gtf.num
227+
# np.testing.assert_array_equal doesn't seem to like a matrices
228+
# with an extra dimension, so convert to ndarray
229+
numref = np.asarray(d)[...,np.newaxis]
230+
np.testing.assert_array_equal(numref, np.array(gtf.num) / np.array(gtf.den))
231+
209232

210233
def suite():
211234
return unittest.TestLoader().loadTestsFromTestCase(TestConvert)

control/xferfcn.py

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,40 +1098,48 @@ def _convertToTransferFunction(sys, **kw):
10981098

10991099
return sys
11001100
elif isinstance(sys, StateSpace):
1101-
try:
1102-
from slycot import tb04ad
1103-
if len(kw):
1104-
raise TypeError(
1105-
"If sys is a StateSpace, " +
1106-
"_convertToTransferFunction cannot take keywords.")
1107-
1108-
# Use Slycot to make the transformation
1109-
# Make sure to convert system matrices to numpy arrays
1110-
tfout = tb04ad(sys.states, sys.inputs, sys.outputs, array(sys.A),
1111-
array(sys.B), array(sys.C), array(sys.D), tol1=0.0)
1112-
1113-
# Preallocate outputs.
1114-
num = [[[] for j in range(sys.inputs)] for i in range(sys.outputs)]
1115-
den = [[[] for j in range(sys.inputs)] for i in range(sys.outputs)]
1116-
1117-
for i in range(sys.outputs):
1118-
for j in range(sys.inputs):
1119-
num[i][j] = list(tfout[6][i, j, :])
1120-
# Each transfer function matrix row
1121-
# has a common denominator.
1122-
den[i][j] = list(tfout[5][i, :])
1123-
# print(num)
1124-
# print(den)
1125-
except ImportError:
1126-
# If slycot is not available, use signal.lti (SISO only)
1127-
if (sys.inputs != 1 or sys.outputs != 1):
1128-
raise TypeError("No support for MIMO without slycot")
1129-
1130-
lti_sys = lti(sys.A, sys.B, sys.C, sys.D)
1131-
num = squeeze(lti_sys.num)
1132-
den = squeeze(lti_sys.den)
1133-
# print(num)
1134-
# print(den)
1101+
1102+
if 0==sys.states:
1103+
# Slycot doesn't like static SS->TF conversion, so handle
1104+
# it first. Can't join this with the no-Slycot branch,
1105+
# since that doesn't handle general MIMO systems
1106+
num = [[[sys.D[i,j]] for j in range(sys.inputs)] for i in range(sys.outputs)]
1107+
den = [[[1.] for j in range(sys.inputs)] for i in range(sys.outputs)]
1108+
else:
1109+
try:
1110+
from slycot import tb04ad
1111+
if len(kw):
1112+
raise TypeError(
1113+
"If sys is a StateSpace, " +
1114+
"_convertToTransferFunction cannot take keywords.")
1115+
1116+
# Use Slycot to make the transformation
1117+
# Make sure to convert system matrices to numpy arrays
1118+
tfout = tb04ad(sys.states, sys.inputs, sys.outputs, array(sys.A),
1119+
array(sys.B), array(sys.C), array(sys.D), tol1=0.0)
1120+
1121+
# Preallocate outputs.
1122+
num = [[[] for j in range(sys.inputs)] for i in range(sys.outputs)]
1123+
den = [[[] for j in range(sys.inputs)] for i in range(sys.outputs)]
1124+
1125+
for i in range(sys.outputs):
1126+
for j in range(sys.inputs):
1127+
num[i][j] = list(tfout[6][i, j, :])
1128+
# Each transfer function matrix row
1129+
# has a common denominator.
1130+
den[i][j] = list(tfout[5][i, :])
1131+
# print(num)
1132+
# print(den)
1133+
except ImportError:
1134+
# If slycot is not available, use signal.lti (SISO only)
1135+
if (sys.inputs != 1 or sys.outputs != 1):
1136+
raise TypeError("No support for MIMO without slycot")
1137+
1138+
lti_sys = lti(sys.A, sys.B, sys.C, sys.D)
1139+
num = squeeze(lti_sys.num)
1140+
den = squeeze(lti_sys.den)
1141+
# print(num)
1142+
# print(den)
11351143

11361144
return TransferFunction(num, den, sys.dt)
11371145

0 commit comments

Comments
 (0)
0