returnScipySignalLTI for discrete systems and add unit tests · python-control/python-control@a8aa41e

@@ -57,7 +57,8 @@

5757

polyadd, polymul, polyval, roots, sqrt, zeros, squeeze, exp, pi, \

5858

where, delete, real, poly, nonzero

5959

import scipy as sp

60-

from scipy.signal import lti, tf2zpk, zpk2tf, cont2discrete

60+

from scipy.signal import tf2zpk, zpk2tf, cont2discrete

61+

from scipy.signal import TransferFunction as signalTransferFunction

6162

from copy import deepcopy

6263

from warnings import warn

6364

from itertools import chain

@@ -93,8 +94,8 @@ class TransferFunction(LTI):

9394

instance variable and setting it to something other than 'None'. If 'dt'

9495

has a non-zero value, then it must match whenever two transfer functions

9596

are combined. If 'dt' is set to True, the system will be treated as a

96-

discrete time system with unspecified sampling time. The default value of

97-

'dt' is None and can be changed by changing the value of

97+

discrete time system with unspecified sampling time. The default value of

98+

'dt' is None and can be changed by changing the value of

9899

``control.config.defaults['xferfcn.default_dt']``.

99100100101

The TransferFunction class defines two constants ``s`` and ``z`` that

@@ -801,7 +802,7 @@ def minreal(self, tol=None):

801802

# end result

802803

return TransferFunction(num, den, self.dt)

803804804-

def returnScipySignalLTI(self):

805+

def returnScipySignalLTI(self, strict=True):

805806

"""Return a list of a list of scipy.signal.lti objects.

806807807808

For instance,

@@ -812,19 +813,38 @@ def returnScipySignalLTI(self):

812813

is a signal.scipy.lti object corresponding to the

813814

transfer function from the 6th input to the 4th output.

814815816+

Parameters

817+

----------

818+

strict : bool, optional

819+

True (default):

820+

`tfobject` must be continuous or discrete.

821+

`tfobject.dt`cannot be None.

822+

False:

823+

if `tfobject.dt` is None, continuous time signal.TransferFunction

824+

objects are is returned

825+826+

Returns

827+

-------

828+

out : list of list of scipy.signal.TransferFunction

815829

"""

830+

if strict and self.dt is None:

831+

raise ValueError("with strict=True, dt cannot be None")

816832817-

# TODO: implement for discrete time systems

818-

if self.dt != 0 and self.dt is not None:

819-

raise NotImplementedError("Function not \

820-

implemented in discrete time")

833+

if self.dt:

834+

kwdt = {'dt': self.dt}

835+

else:

836+

# scipy convention for continuous time lti systems: call without

837+

# dt keyword argument

838+

kwdt = {}

821839822840

# Preallocate the output.

823841

out = [[[] for j in range(self.inputs)] for i in range(self.outputs)]

824842825843

for i in range(self.outputs):

826844

for j in range(self.inputs):

827-

out[i][j] = lti(self.num[i][j], self.den[i][j])

845+

out[i][j] = signalTransferFunction(self.num[i][j],

846+

self.den[i][j],

847+

**kwdt)

828848829849

return out

830850

@@ -1016,11 +1036,11 @@ def sample(self, Ts, method='zoh', alpha=None, prewarp_frequency=None):

10161036

The generalized bilinear transformation weighting parameter, which

10171037

should only be specified with method="gbt", and is ignored

10181038

otherwise.

1019-1039+10201040

prewarp_frequency : float within [0, infinity)

10211041

The frequency [rad/s] at which to match with the input continuous-

1022-

time system's magnitude and phase (the gain=1 crossover frequency,

1023-

for example). Should only be specified with method='bilinear' or

1042+

time system's magnitude and phase (the gain=1 crossover frequency,

1043+

for example). Should only be specified with method='bilinear' or

10241044

'gbt' with alpha=0.5 and ignored otherwise.

1025104510261046

Returns

@@ -1050,7 +1070,7 @@ def sample(self, Ts, method='zoh', alpha=None, prewarp_frequency=None):

10501070

if (method=='bilinear' or (method=='gbt' and alpha==0.5)) and \

10511071

prewarp_frequency is not None:

10521072

Twarp = 2*np.tan(prewarp_frequency*Ts/2)/prewarp_frequency

1053-

else:

1073+

else:

10541074

Twarp = Ts

10551075

numd, dend, _ = cont2discrete(sys, Twarp, method, alpha)

10561076

return TransferFunction(numd[0, :], dend, Ts)