Skip to content

Commit 05d6bc5

Browse files
authored
Merge pull request #145 from roryyorke/rory/static-ss-to-tf
BUG: allow state-space to transfer function conversion of static gains
2 parents 606d60e + d9aaa8f commit 05d6bc5

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy