From: <kk...@us...> - 2011-02-08 22:14:48
|
Revision: 61 http://python-control.svn.sourceforge.net/python-control/?rev=61&view=rev Author: kkchen Date: 2011-02-08 22:14:42 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Various edits: - Put some functions in matlab.py and marked as complete. - Minor fix to convertToStateSpace in statesp.py. - Wrote convertToTransferFunction and put it to use in xferfcn.py. - Changed a ValueError to TypeError; fixed in xferfcn.py and TestXferFcn.py. Kevin K. Chen <kk...@pr...> Modified Paths: -------------- branches/control-0.4a/src/TestXferFcn.py branches/control-0.4a/src/matlab.py branches/control-0.4a/src/statesp.py branches/control-0.4a/src/xferfcn.py Modified: branches/control-0.4a/src/TestXferFcn.py =================================================================== --- branches/control-0.4a/src/TestXferFcn.py 2011-02-08 22:14:38 UTC (rev 60) +++ branches/control-0.4a/src/TestXferFcn.py 2011-02-08 22:14:42 UTC (rev 61) @@ -14,7 +14,7 @@ def testBadInputType(self): """Give the constructor invalid input types.""" - self.assertRaises(ValueError, xTransferFunction, [[0., 1.], [2., 3.]], + self.assertRaises(TypeError, xTransferFunction, [[0., 1.], [2., 3.]], [[5., 2.], [3., 0.]]) def testInconsistentDimension(self): @@ -334,7 +334,7 @@ # Tests for xTransferFunction.freqresp. - def testFRespSISO(self): + def testFreqRespSISO(self): """Evaluate the magnitude and phase of a SISO system at multiple frequencies.""" @@ -351,7 +351,7 @@ np.testing.assert_array_almost_equal(phase, truephase) np.testing.assert_array_almost_equal(omega, trueomega) - def testFRespMIMO(self): + def testFreqRespMIMO(self): """Evaluate the magnitude and phase of a MIMO system at multiple frequencies.""" Modified: branches/control-0.4a/src/matlab.py =================================================================== --- branches/control-0.4a/src/matlab.py 2011-02-08 22:14:38 UTC (rev 60) +++ branches/control-0.4a/src/matlab.py 2011-02-08 22:14:42 UTC (rev 61) @@ -69,7 +69,7 @@ from freqplot import nyquist, nichols, gangof4 from bdalg import series, parallel, negate, feedback from pzmap import pzmap -from statefbk import ctrb, obsv, place, lqr +from statefbk import ctrb, obsv, gram, place, lqr from delay import pade __doc__ = """ @@ -158,8 +158,8 @@ * nichols - Nichols plot margin - gain and phase margins lti/allmargin - all crossover frequencies and related gain/phase margins - lti/freqresp - frequency response over a frequency grid - lti/evalfr - evaluate frequency response at given frequency +* lti/freqresp - frequency response over a frequency grid +* lti/evalfr - evaluate frequency response at given frequency Model simplification minreal - minimal realization and pole/zero cancellation @@ -193,7 +193,7 @@ canon - canonical forms of state-space models * ctrb - controllability matrix * obsv - observability matrix - gram - controllability and observability gramians +* gram - controllability and observability gramians ss/prescale - optimal scaling of state-space models. balreal - gramian-based input/output balancing ss/xperm - reorder states. @@ -317,13 +317,22 @@ return rss_generate(states, inputs, outputs, 'd') def pole(sys): + """Return system poles.""" + return sys.poles() -# Frequency response is handled by the system object -def freqresp(H, omega): - """Return the frequency response for an object H at frequency omega""" - return H.freqresp(omega) +def evalfr(sys, omega): + """Evaluate the transfer function of an LTI system at a single frequency + omega.""" + return sys.evalfr(omega) + +def freqresp(sys, omega): + """Return the frequency response for an LTI object at a list of frequencies + omega.""" + + return sys.freqresp(omega) + # Bode plots def bode(*args, **keywords): """Bode plot of the frequency response Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:14:38 UTC (rev 60) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:14:42 UTC (rev 61) @@ -267,7 +267,7 @@ # in the case of a scalar system # def convertToStateSpace(sys, inputs=1, outputs=1): - """Convert a system to state space form (if needed)""" + """Convert a system to state space form (if needed).""" if isinstance(sys, StateSpace): # Already a state space system; just return it @@ -278,11 +278,10 @@ # Generate a simple state space system of the desired dimension # The following Doesn't work due to inconsistencies in ltisys: # return StateSpace([[]], [[]], [[]], sp.eye(outputs, inputs)) - return StateSpace(-1, zeros((1, inputs)), zeros((outputs, 1)), - sp.eye(outputs, inputs)) - + return StateSpace(0, zeros((1, inputs)), zeros((outputs, 1)), + sys * sp.eye(outputs, inputs)) else: - raise TypeError("can't convert given type to StateSpace system") + raise TypeError("Can't convert given type to StateSpace system.") def rss_generate(states, inputs, outputs, type): """This does the actual random state space generation expected from rss and Modified: branches/control-0.4a/src/xferfcn.py =================================================================== --- branches/control-0.4a/src/xferfcn.py 2011-02-08 22:14:38 UTC (rev 60) +++ branches/control-0.4a/src/xferfcn.py 2011-02-08 22:14:42 UTC (rev 61) @@ -91,7 +91,7 @@ else: # If the user passed in anything else, then it's unclear what # the meaning is. - raise ValueError("The numerator and denominator inputs must be \ + raise TypeError("The numerator and denominator inputs must be \ scalars or vectors (for\nSISO), or lists of lists of vectors (for SISO or \ MIMO).") [num, den] = data @@ -205,7 +205,7 @@ # Convert the second argument to a transfer function. if not isinstance(other, xTransferFunction): - other = ss2tf(other) + other = convertToTransferFunction(other, self.inputs, self.outputs) # Check that the input-output sizes are consistent. if self.inputs != other.inputs: @@ -246,7 +246,7 @@ # Convert the second argument to a transfer function. if not isinstance(other, xTransferFunction): - other = ss2tf(other) + other = convertToTransferFunction(other, self.outputs, self.outputs) # Check that the input-output sizes are consistent. if self.inputs != other.outputs: @@ -291,7 +291,7 @@ # Convert the second argument to a transfer function. if not isinstance(other, xTransferFunction): - other = ss2tf(other) + other = convertToTransferFunction(other, 1, 1) num = sp.polymul(self.num[0][0], other.den[0][0]) den = sp.polymul(self.den[0][0], other.num[0][0]) @@ -586,8 +586,16 @@ den = sp.polymul(den1, den2) return num, den - -def ss2tf(sys): - """Convert a state space object to a transfer function object.""" - pass +def convertToTransferFunction(sys, inputs=1, outputs=1): + """Convert a system to transfer function form (if needed.)""" + + if isinstance(sys, xTransferFunction): + return sys + elif isinstance(sys, statesp.StateSpace): + pass #TODO: convert TF to SS + elif isinstance(sys, (int, long, float, complex)): + coeff = sp.eye(outputs, inputs) + return xTransferFunction(sys * coeff, coeff) + else: + raise TypeError("Can't convert given type to StateSpace system.") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |