|
From: <re...@us...> - 2014-05-23 12:41:56
|
Revision: 299
http://sourceforge.net/p/python-control/code/299
Author: repa
Date: 2014-05-23 12:41:47 +0000 (Fri, 23 May 2014)
Log Message:
-----------
Added c2d functionality for MIMO state-space systems; both in matlab mode
and for python mode; added tests for same
Modified Paths:
--------------
trunk/src/dtime.py
trunk/src/matlab.py
trunk/src/statesp.py
trunk/tests/discrete_test.py
trunk/tests/matlab_test.py
Modified: trunk/src/dtime.py
===================================================================
--- trunk/src/dtime.py 2014-03-23 20:39:48 UTC (rev 298)
+++ trunk/src/dtime.py 2014-05-23 12:41:47 UTC (rev 299)
@@ -94,11 +94,25 @@
if not isctime(sysc):
raise ValueError("First argument must be continuous time system")
- # TODO: impelement MIMO version
+ # If we are passed a state space system, convert to transfer function first
+ if isinstance(sysc, StateSpace) and method == 'zoh':
+
+ try:
+ # try with slycot routine
+ from slycot import mb05nd
+ F, H = mb05nd(sysc.A, Ts)
+ return StateSpace(F, H*sysc.B, sysc.C, sysc.D, Ts)
+ except ImportError:
+ if sysc.inputs != 1 or sysc.outputs != 1:
+ raise TypeError(
+ "mb05nd not found in slycot, or slycot not installed")
+
+ # TODO: implement MIMO version for other than ZOH state-space
if (sysc.inputs != 1 or sysc.outputs != 1):
raise NotImplementedError("MIMO implementation not available")
- # If we are passed a state space system, convert to transfer function first
+ # SISO state-space, with other than ZOH, or failing slycot import,
+ # is handled by conversion to TF
if isinstance(sysc, StateSpace):
warn("sample_system: converting to transfer function")
sysc = _convertToTransferFunction(sysc)
Modified: trunk/src/matlab.py
===================================================================
--- trunk/src/matlab.py 2014-03-23 20:39:48 UTC (rev 298)
+++ trunk/src/matlab.py 2014-05-23 12:41:47 UTC (rev 299)
@@ -1524,8 +1524,29 @@
return (tf.num, tf.den)
# Convert a continuous time system to a discrete time system
-def c2d(sysc, Ts, method):
- # TODO: add docstring
+def c2d(sysc, Ts, method='zoh'):
+ '''
+ Return a discrete-time system
+
+ Parameters
+ ----------
+ sysc: Lti (StateSpace or TransferFunction), continuous
+ System to be converted
+
+ Ts: number
+ Sample time for the conversion
+
+ method: string, optional
+ Method to be applied,
+ 'zoh' Zero-order hold on the inputs (default)
+ 'foh' First-order hold, currently not implemented
+ 'impulse' Impulse-invariant discretization, currently not implemented
+ 'tustin' Bilinear (Tustin) approximation, only SISO
+ 'matched' Matched pole-zero method, only SISO
+ '''
# Call the sample_system() function to do the work
- return sample_system(sysc, Ts, method)
+ sysd = sample_system(sysc, Ts, method)
+ if isinstance(sysc, StateSpace) and not isinstance(sysd, StateSpace):
+ return _convertToStateSpace(sysd)
+ return sysd
Modified: trunk/src/statesp.py
===================================================================
--- trunk/src/statesp.py 2014-03-23 20:39:48 UTC (rev 298)
+++ trunk/src/statesp.py 2014-05-23 12:41:47 UTC (rev 299)
@@ -610,7 +610,7 @@
ssout[3][:sys.outputs, :states],
ssout[4], sys.dt)
except ImportError:
- # TODO: do we want to squeeze first and check dimenations?
+ # TODO: do we want to squeeze first and check dimensions?
# I think this will fail if num and den aren't 1-D after
# the squeeze
lti_sys = lti(squeeze(sys.num), squeeze(sys.den))
Modified: trunk/tests/discrete_test.py
===================================================================
--- trunk/tests/discrete_test.py 2014-03-23 20:39:48 UTC (rev 298)
+++ trunk/tests/discrete_test.py 2014-05-23 12:41:47 UTC (rev 299)
@@ -272,6 +272,10 @@
self.assertEqual(sysd.dt, 1)
# TODO: put in other generic checks
+ for sysc in (self.mimo_ss1, self.mimo_ss1c):
+ sysd = sample_system(sysc, 1, method='zoh')
+ self.assertEqual(sysd.dt, 1)
+
# TODO: check results of converstion
# Check errors
Modified: trunk/tests/matlab_test.py
===================================================================
--- trunk/tests/matlab_test.py 2014-03-23 20:39:48 UTC (rev 298)
+++ trunk/tests/matlab_test.py 2014-05-23 12:41:47 UTC (rev 299)
@@ -515,7 +515,26 @@
np.testing.assert_array_almost_equal(hm.num[0][0], hr.num[0][0])
np.testing.assert_array_almost_equal(hm.den[0][0], hr.den[0][0])
+ def testSS2cont(self):
+ sys = ss(
+ np.mat("-3 4 2; -1 -3 0; 2 5 3"),
+ np.mat("1 4 ; -3 -3; -2 1"),
+ np.mat("4 2 -3; 1 4 3"),
+ np.mat("-2 4; 0 1"))
+ sysd = c2d(sys, 0.1)
+ np.testing.assert_array_almost_equal(
+ np.mat(
+ """0.742840837331905 0.342242024293711 0.203124211149560;
+ -0.074130792143890 0.724553295044645 -0.009143771143630;
+ 0.180264783290485 0.544385612448419 1.370501013067845"""),
+ sysd.A)
+ np.testing.assert_array_almost_equal(
+ np.mat(""" 0.012362066084719 0.301932197918268;
+ -0.260952977031384 -0.274201791021713;
+ -0.304617775734327 0.075182622718853"""), sysd.B)
+
+
#! TODO: not yet implemented
# def testMIMOtfdata(self):
# sisotf = ss2tf(self.siso_ss1)
|