From: <mur...@us...> - 2011-04-02 18:13:30
|
Revision: 146 http://python-control.svn.sourceforge.net/python-control/?rev=146&view=rev Author: murrayrm Date: 2011-04-02 18:13:23 +0000 (Sat, 02 Apr 2011) Log Message: ----------- Changes in preparation for using v0.4 as trunk: * Added missing MATLAB compatible functions for module reduction * Turned off print statements in unit tests (turn back on using verbose flag) * Removed bug warnings from conversion routines; posted open bug to Pending * Updated examples/pvtol-nested-ss to reflect interface changes * See ChangeLog for a detailed list of changes Modified Paths: -------------- branches/control-0.4b/ChangeLog branches/control-0.4b/Pending branches/control-0.4b/examples/pvtol-nested-ss.py branches/control-0.4b/src/__init__.py branches/control-0.4b/src/matlab.py branches/control-0.4b/src/modelsimp.py branches/control-0.4b/src/statesp.py branches/control-0.4b/src/xferfcn.py branches/control-0.4b/tests/convert_test.py branches/control-0.4b/tests/modelsimp_test.py branches/control-0.4b/tests/slycot_convert_test.py branches/control-0.4b/tests/test_all.py Modified: branches/control-0.4b/ChangeLog =================================================================== --- branches/control-0.4b/ChangeLog 2011-04-02 16:15:41 UTC (rev 145) +++ branches/control-0.4b/ChangeLog 2011-04-02 18:13:23 UTC (rev 146) @@ -1,5 +1,31 @@ 2011-04-02 Richard Murray <murray@malabar.local> + * src/__init__.py: removed import of tests module (moved to tests/) + + * src/matlab.py: Added hsvd, balred, modred to list of functions + that are imported for use as is. Updated documentation string to + indicate that these are implemented, along with a few other + functions (zero, lqr) that weren't properly listed. + + * src/modelsimp.py (balred): Removed extraneous print statements + (modred): Set method to be 'matchdc' by default (to match MATLAB) + + * src/__init__.py: added missing import of modelsimp functions + + * tests/slycot_convert_test.py (TestSlycot.testTF): turned off print + statements in unit test to make it easier to see results. Use + verbose=True to turn back on. + + * tests/convert_test.py (TestConvert.testConvert): got rid of print + statements in unittest; clutters the output so that you can't see + the errors clearly. Use verbose=True to turn back on. + + * src/statesp.py (_convertToStateSpace): removed "buggy" print + statements + + * src/xferfcn.py (_convertToTransferFunction): removed "buggy" print + statements + * tests/nichols_test.py (TestStateSpace.testNgrid): updated testcode to turn off grid in initial Nichols chart plot. Modified: branches/control-0.4b/Pending =================================================================== --- branches/control-0.4b/Pending 2011-04-02 16:15:41 UTC (rev 145) +++ branches/control-0.4b/Pending 2011-04-02 18:13:23 UTC (rev 146) @@ -10,9 +10,9 @@ OPEN BUGS * matlab.step() doesn't handle systems with a pole at the origin (use lsim2) - * tests/convert_test.py not working yet - * tests/test_all.py should report on failed tests - * tests/freqresp.py needs to be converted to unit test + * TF <-> SS transformations are buggy; see tests/convert_test.py + * hsvd returns different value than MATLAB (2010a); see modelsimp_test.py + * MIMO common denominator fails unit test; see convert_test.py Transfer code from Roberto Bucher's yottalab to python-control acker - pole placement using Ackermann method @@ -40,6 +40,9 @@ * Put together unit tests for all functions (after deciding on framework) * Figure out how to import 'figure' command properly (version issue?) * Figure out source of BadCoefficients warning messages (pvtol-lqr and others) + * tests/test_all.py should report on failed tests + * tests/freqresp.py needs to be converted to unit test + * Convert examples/test-{response,statefbk}.py to unit tests TransferFunction class fixes * evalfr is not working (num, den stored as ndarrays, not poly1ds) Modified: branches/control-0.4b/examples/pvtol-nested-ss.py =================================================================== --- branches/control-0.4b/examples/pvtol-nested-ss.py 2011-04-02 16:15:41 UTC (rev 145) +++ branches/control-0.4b/examples/pvtol-nested-ss.py 2011-04-02 18:13:23 UTC (rev 146) @@ -95,21 +95,21 @@ # (gm, pm, wgc, wpc) = margin(L); figure(6); clf; subplot(221); -(magh, phaseh) = bode(L); +bode(L, logspace(-4, 3)); # Add crossover line -subplot(magh); hold(True); -loglog([10^-4, 10^3], [1, 1], 'k-') +subplot(211); hold(True); +loglog([1e-4, 1e3], [1, 1], 'k-') # Replot phase starting at -90 degrees -bode(L, logspace(-4, 3)); (mag, phase, w) = freqresp(L, logspace(-4, 3)); phase = phase - 360; -subplot(phaseh); -semilogx([10^-4, 10^3], [-180, -180], 'k-') + +subplot(212); +semilogx([1e-4, 1e3], [-180, -180], 'k-') hold(True); semilogx(w, np.squeeze(phase), 'b-') -axis([10^-4, 10^3, -360, 0]); +axis([1e-4, 1e3, -360, 0]); xlabel('Frequency [deg]'); ylabel('Phase [deg]'); # set(gca, 'YTick', [-360, -270, -180, -90, 0]); # set(gca, 'XTick', [10^-4, 10^-2, 1, 100]); @@ -152,8 +152,8 @@ #TODO: PZmap for statespace systems has not yet been implemented. figure(10); clf(); -#(P, Z) = pzmap(T, Plot=True) -#print "Closed loop poles and zeros: ", P, Z +# (P, Z) = pzmap(T, Plot=True) +# print "Closed loop poles and zeros: ", P, Z # Gang of Four figure(11); clf(); Modified: branches/control-0.4b/src/__init__.py =================================================================== --- branches/control-0.4b/src/__init__.py 2011-04-02 16:15:41 UTC (rev 145) +++ branches/control-0.4b/src/__init__.py 2011-04-02 18:13:23 UTC (rev 146) @@ -63,5 +63,4 @@ from bdalg import * from statefbk import * from delay import * - -from test import * +from modelsimp import * Modified: branches/control-0.4b/src/matlab.py =================================================================== --- branches/control-0.4b/src/matlab.py 2011-04-02 16:15:41 UTC (rev 145) +++ branches/control-0.4b/src/matlab.py 2011-04-02 18:13:23 UTC (rev 146) @@ -80,6 +80,7 @@ from pzmap import pzmap from statefbk import ctrb, obsv, gram, place, lqr from delay import pade +from modelsimp import hsvd, balred, modred __doc__ += """ The control.matlab module defines functions that are roughly the @@ -139,9 +140,9 @@ lti/bandwidth - system bandwidth lti/norm - h2 and Hinfinity norms of LTI models \* lti/pole - system poles - lti/zero - system (transmission) zeros +\* lti/zero - system (transmission) zeros lti/order - model order (number of states) -\* pzmap - pole-zero map +\* pzmap - pole-zero map (TF only) lti/iopzmap - input/output pole-zero map damp - natural frequency and damping of system poles esort - sort continuous poles by real part @@ -173,19 +174,20 @@ Model simplification minreal - minimal realization and pole/zero cancellation ss/sminreal - structurally minimal realization (state space) - lti/hsvd - hankel singular values (state contributions) - lti/balred - reduced-order approximations of LTI models - ss/modred - model order reduction +\* lti/hsvd - hankel singular values (state contributions) +\* lti/balred - reduced-order approximations of LTI models +\* ss/modred - model order reduction Compensator design rlocus - evans root locus - place - pole placement +\* place - pole placement estim - form estimator given estimator gain reg - form regulator given state-feedback and estimator gains LQR/LQG design ss/lqg - single-step LQG design - lqr, dlqr - linear-Quadratic (LQ) state-feedback regulator +\* lqr - linear-Quadratic (LQ) state-feedback regulator +\* dlqr - discrete-time LQ state-feedback regulator lqry - lq regulator with output weighting lqrd - discrete LQ regulator for continuous plant ss/lqi - linear-Quadratic-Integral (LQI) controller Modified: branches/control-0.4b/src/modelsimp.py =================================================================== --- branches/control-0.4b/src/modelsimp.py 2011-04-02 16:15:41 UTC (rev 145) +++ branches/control-0.4b/src/modelsimp.py 2011-04-02 18:13:23 UTC (rev 146) @@ -84,7 +84,7 @@ # Return the Hankel singular values return hsv -def modred(sys,ELIM,method): +def modred(sys,ELIM,method='matchdc'): """Model reduction of sys by eliminating the states in ELIM using a given method Parameters @@ -207,8 +207,8 @@ #Check system is stable D,V = np.linalg.eig(sys.A) - print D.shape - print D + # print D.shape + # print D for e in D: if e.real >= 0: raise ValueError, "Oops, the system is unstable!" Modified: branches/control-0.4b/src/statesp.py =================================================================== --- branches/control-0.4b/src/statesp.py 2011-04-02 16:15:41 UTC (rev 145) +++ branches/control-0.4b/src/statesp.py 2011-04-02 18:13:23 UTC (rev 146) @@ -469,8 +469,6 @@ # Repeat the common denominator along the rows. den = array([den for i in range(sys.outputs)]) # TODO: transfer function to state space conversion is still buggy! - print "Warning: transfer function to state space conversion by td04ad \ -is still buggy! Advise converting state space sys back to tf to verify the transformation was correct." #print num #print shape(num) ssout = td04ad('R',sys.inputs, sys.outputs, index, den, num,tol=0.0) Modified: branches/control-0.4b/src/xferfcn.py =================================================================== --- branches/control-0.4b/src/xferfcn.py 2011-04-02 16:15:41 UTC (rev 145) +++ branches/control-0.4b/src/xferfcn.py 2011-04-02 18:13:23 UTC (rev 146) @@ -713,8 +713,6 @@ # Use Slycot to make the transformation. TODO: this is still somewhat # buggy! - print "Warning: state space to transfer function conversion by tb04ad \ -is still buggy!" tfout = tb04ad(sys.states, sys.inputs, sys.outputs, sys.A, sys.B, sys.C, sys.D,tol1=0.0) @@ -727,8 +725,8 @@ num[i][j] = list(tfout[6][i, j, :]) # Each transfer function matrix row has a common denominator. den[i][j] = list(tfout[5][i, :]) - print num - print den + # print num + # print den return TransferFunction(num, den) elif isinstance(sys, (int, long, float, complex)): if "inputs" in kw: Modified: branches/control-0.4b/tests/convert_test.py =================================================================== --- branches/control-0.4b/tests/convert_test.py 2011-04-02 16:15:41 UTC (rev 145) +++ branches/control-0.4b/tests/convert_test.py 2011-04-02 18:13:23 UTC (rev 146) @@ -1,6 +1,6 @@ #!/usr/bin/env python -"""TestConvert.py +"""convert_test.py Test state space and transfer function conversion. @@ -40,7 +40,7 @@ print "sys%i:\n" % ind print sys - def testConvert(self): + def testConvert(self, verbose=0): """Test state space to transfer function conversion.""" #Currently it only tests that a TF->SS->TF generates an unchanged TF @@ -52,16 +52,20 @@ #start with a random SS system and transform to TF #then back to SS, check that the matrices are the same. ssOriginal = matlab.rss(states, inputs, outputs) - self.printSys(ssOriginal, 1) + if (verbose): + self.printSys(ssOriginal, 1) tfOriginal = matlab.tf(ssOriginal) - self.printSys(tfOriginal, 2) + if (verbose): + self.printSys(tfOriginal, 2) ssTransformed = matlab.ss(tfOriginal) - self.printSys(ssTransformed, 3) + if (verbose): + self.printSys(ssTransformed, 3) tfTransformed = matlab.tf(ssTransformed) - self.printSys(tfTransformed, 4) + if (verbose): + self.printSys(tfTransformed, 4) for inputNum in range(inputs): for outputNum in range(outputs): @@ -81,8 +85,6 @@ #[mag,phase,freq]=bode(sys) #it doesn't seem to...... #This should be added. - - def suite(): return unittest.TestLoader().loadTestsFromTestCase(TestConvert) Modified: branches/control-0.4b/tests/modelsimp_test.py =================================================================== --- branches/control-0.4b/tests/modelsimp_test.py 2011-04-02 16:15:41 UTC (rev 145) +++ branches/control-0.4b/tests/modelsimp_test.py 2011-04-02 18:13:23 UTC (rev 146) @@ -16,7 +16,7 @@ D = np.matrix("9.") sys = ss(A,B,C,D) hsv = hsvd(sys) - hsvtrue = np.matrix("24.42686 0.5731395") + hsvtrue = np.matrix("24.42686 0.5731395") # from MATLAB np.testing.assert_array_almost_equal(hsv, hsvtrue) def testMarkov(self): Modified: branches/control-0.4b/tests/slycot_convert_test.py =================================================================== --- branches/control-0.4b/tests/slycot_convert_test.py 2011-04-02 16:15:41 UTC (rev 145) +++ branches/control-0.4b/tests/slycot_convert_test.py 2011-04-02 18:13:23 UTC (rev 146) @@ -26,24 +26,23 @@ self.maxI = 1 self.maxO = 1 - def testTF(self): + def testTF(self, verbose=False): """ Directly tests the functions tb04ad and td04ad through direct comparison of transfer function coefficients. - Similar to TestConvert, but tests at a lower level. + Similar to convert_test, but tests at a lower level. """ for states in range(1, self.maxStates): for inputs in range(1, self.maxI+1): for outputs in range(1, self.maxO+1): for testNum in range(self.numTests): - ssOriginal = matlab.rss(states, inputs, outputs) + if (verbose): + print '====== Original SS ==========' + print ssOriginal + print 'states=',states + print 'inputs=',inputs + print 'outputs=',outputs - print '====== Original SS ==========' - print ssOriginal - print 'states=',states - print 'inputs=',inputs - print 'outputs=',outputs - tfOriginal_Actrb, tfOriginal_Bctrb, tfOriginal_Cctrb, tfOrigingal_nctrb, tfOriginal_index,\ tfOriginal_dcoeff, tfOriginal_ucoeff = tb04ad(states,inputs,outputs,\ ssOriginal.A,ssOriginal.B,ssOriginal.C,ssOriginal.D,tol1=0.0) @@ -55,15 +54,16 @@ tfTransformed_index, tfTransformed_dcoeff, tfTransformed_ucoeff = tb04ad(ssTransformed_nr,\ inputs,outputs,ssTransformed_A, ssTransformed_B, ssTransformed_C,ssTransformed_D,tol1=0.0) #print 'size(Trans_A)=',ssTransformed_A.shape - print '===== Transformed SS ==========' - print matlab.ss(ssTransformed_A, ssTransformed_B, ssTransformed_C, ssTransformed_D) - #print 'Trans_nr=',ssTransformed_nr - #print 'tfOrig_index=',tfOriginal_index - #print 'tfOrig_ucoeff=',tfOriginal_ucoeff - #print 'tfOrig_dcoeff=',tfOriginal_dcoeff - #print 'tfTrans_index=',tfTransformed_index - #print 'tfTrans_ucoeff=',tfTransformed_ucoeff - #print 'tfTrans_dcoeff=',tfTransformed_dcoeff + if (verbose): + print '===== Transformed SS ==========' + print matlab.ss(ssTransformed_A, ssTransformed_B, ssTransformed_C, ssTransformed_D) + # print 'Trans_nr=',ssTransformed_nr + # print 'tfOrig_index=',tfOriginal_index + # print 'tfOrig_ucoeff=',tfOriginal_ucoeff + # print 'tfOrig_dcoeff=',tfOriginal_dcoeff + # print 'tfTrans_index=',tfTransformed_index + # print 'tfTrans_ucoeff=',tfTransformed_ucoeff + # print 'tfTrans_dcoeff=',tfTransformed_dcoeff #Compare the TF directly, must match #numerators np.testing.assert_array_almost_equal(tfOriginal_ucoeff,tfTransformed_ucoeff,decimal=3) Modified: branches/control-0.4b/tests/test_all.py =================================================================== --- branches/control-0.4b/tests/test_all.py 2011-04-02 16:15:41 UTC (rev 145) +++ branches/control-0.4b/tests/test_all.py 2011-04-02 18:13:23 UTC (rev 146) @@ -7,7 +7,7 @@ import re # regular expressions import os # operating system commands -def test_all(verbosity=2): +def test_all(verbosity=0): """ Runs all tests written for python-control. """ try: # autodiscovery (python 2.7+) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |