From: <kk...@us...> - 2011-02-08 22:19:13
|
Revision: 113 http://python-control.svn.sourceforge.net/python-control/?rev=113&view=rev Author: kkchen Date: 2011-02-08 22:19:07 +0000 (Tue, 08 Feb 2011) Log Message: ----------- Updated test.py to be in repository I forgot to hg add test.py last time, oops. Made a few other minor edits, removing some duplicate code with "execs" in test.py for python versions <2.7 bb...@ra... Modified Paths: -------------- branches/control-0.4a/examples/pvtol-lqr.py branches/control-0.4a/examples/pvtol-nested-ss.py branches/control-0.4a/examples/pvtol-nested.py branches/control-0.4a/examples/secord-matlab.py branches/control-0.4a/examples/slicot-test.py branches/control-0.4a/src/freqplot.py branches/control-0.4a/src/pzmap.py branches/control-0.4a/src/statesp.py branches/control-0.4a/src/xferfcn.py Added Paths: ----------- branches/control-0.4a/src/test.py Modified: branches/control-0.4a/examples/pvtol-lqr.py =================================================================== --- branches/control-0.4a/examples/pvtol-lqr.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/examples/pvtol-lqr.py 2011-02-08 22:19:07 UTC (rev 113) @@ -119,7 +119,7 @@ subplot(221); title("Identity weights") # plot(T, Y[:,1, 1], '-', T, Y[:,2, 2], '--'); hold(True); -plot(Tx.T, Yx[0,:].T, '-', Ty.T, Yy[0,:].T, '--'); hold(True); +plot(Tx, Yx[0,:].T, '-', Ty, Yy[0,:].T, '--'); hold(True); plot([0, 10], [1, 1], 'k-'); hold(True); axis([0, 10, -0.1, 1.4]); @@ -141,9 +141,9 @@ [T3, Y3] = step(H1cx, T=linspace(0,10,100)); subplot(222); title("Effect of input weights") -plot(T1.T, Y1[0,:].T, 'b-'); hold(True); -plot(T2.T, Y2[0,:].T, 'b-'); hold(True); -plot(T3.T, Y3[0,:].T, 'b-'); hold(True); +plot(T1, Y1[0,:].T, 'b-'); hold(True); +plot(T2, Y2[0,:].T, 'b-'); hold(True); +plot(T3, Y3[0,:].T, 'b-'); hold(True); plot([0 ,10], [1, 1], 'k-'); hold(True); axis([0, 10, -0.1, 1.4]); @@ -162,7 +162,7 @@ subplot(223); title("Output weighting") [T2x, Y2x] = step(H2x, T=linspace(0,10,100)); [T2y, Y2y] = step(H2y, T=linspace(0,10,100)); -plot(T2x.T, Y2x[0,:].T, T2y.T, Y2y[0,:].T) +plot(T2x, Y2x[0,:].T, T2y, Y2y[0,:].T) ylabel('position'); xlabel('time'); ylabel('position'); legend(('x', 'y'), loc='lower right'); @@ -185,7 +185,7 @@ # step(H3x, H3y, 10); [T3x, Y3x] = step(H3x, T=linspace(0,10,100)); [T3y, Y3y] = step(H3y, T=linspace(0,10,100)); -plot(T3x.T, Y3x[0,:].T, T3y.T, Y3y[0,:].T) +plot(T3x, Y3x[0,:].T, T3y, Y3y[0,:].T) title("Physically motivated weights") xlabel('time'); legend(('x', 'y'), loc='lower right'); Modified: branches/control-0.4a/examples/pvtol-nested-ss.py =================================================================== --- branches/control-0.4a/examples/pvtol-nested-ss.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/examples/pvtol-nested-ss.py 2011-02-08 22:19:07 UTC (rev 113) @@ -10,7 +10,6 @@ from matplotlib.pyplot import * # Grab MATLAB plotting functions from control.matlab import * # MATLAB-like functions -import numpy as np # System parameters m = 4; # mass of aircraft @@ -108,7 +107,7 @@ subplot(phaseh); semilogx([10^-4, 10^3], [-180, -180], 'k-') hold(True); -semilogx(w, np.squeeze(phase), 'b-') +semilogx(w, phase, 'b-') axis([10^-4, 10^3, -360, 0]); xlabel('Frequency [deg]'); ylabel('Phase [deg]'); # set(gca, 'YTick', [-360, -270, -180, -90, 0]); @@ -145,15 +144,14 @@ figure(9); (Tvec, Yvec) = step(T, None, linspace(1, 20)); -plot(Tvec.T, Yvec.T); hold(True); +plot(Tvec, Yvec); hold(True); (Tvec, Yvec) = step(Co*S, None, linspace(1, 20)); -plot(Tvec.T, Yvec.T); +plot(Tvec, Yvec); -#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.4a/examples/pvtol-nested.py =================================================================== --- branches/control-0.4a/examples/pvtol-nested.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/examples/pvtol-nested.py 2011-02-08 22:19:07 UTC (rev 113) @@ -10,7 +10,6 @@ from matplotlib.pyplot import * # Grab MATLAB plotting functions from control.matlab import * # MATLAB-like functions -import numpy as np # System parameters m = 4; # mass of aircraft @@ -24,8 +23,8 @@ Po = tf([1], [m, c, 0]); # outer loop (position) # Use state space versions -Pi = tf2ss(Pi); -Po = tf2ss(Po); +# Pi = tf2ss(Pi); +# Po = tf2ss(Po); # # Inner loop control design @@ -98,7 +97,7 @@ subplot(phaseh); semilogx([10^-4, 10^3], [-180, -180], 'k-') hold(True); -semilogx(w, np.squeeze(phase), 'b-') +semilogx(w, phase, 'b-') axis([10^-4, 10^3, -360, 0]); xlabel('Frequency [deg]'); ylabel('Phase [deg]'); # set(gca, 'YTick', [-360, -270, -180, -90, 0]); @@ -135,10 +134,10 @@ figure(9); (Tvec, Yvec) = step(T, None, linspace(1, 20)); -plot(Tvec.T, Yvec.T); hold(True); +plot(Tvec, Yvec); hold(True); (Tvec, Yvec) = step(Co*S, None, linspace(1, 20)); -plot(Tvec.T, Yvec.T); +plot(Tvec, Yvec); figure(10); clf(); (P, Z) = pzmap(T, Plot=True) Modified: branches/control-0.4a/examples/secord-matlab.py =================================================================== --- branches/control-0.4a/examples/secord-matlab.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/examples/secord-matlab.py 2011-02-08 22:19:07 UTC (rev 113) @@ -18,7 +18,7 @@ # Step response for the system figure(1) T, yout = step(sys) -plot(T.T, yout.T) +plot(T, yout) # Bode plot for the system figure(2) Modified: branches/control-0.4a/examples/slicot-test.py =================================================================== --- branches/control-0.4a/examples/slicot-test.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/examples/slicot-test.py 2011-02-08 22:19:07 UTC (rev 113) @@ -17,7 +17,7 @@ sys = ss(A, B, C, 0); # Eigenvalue placement -#from slycot import sb01bd +from slycot import sb01bd K = place(A, B, [-3, -2, -1]) print "Pole place: K = ", K print "Pole place: eigs = ", np.linalg.eig(A - B * K)[0] Modified: branches/control-0.4a/src/freqplot.py =================================================================== --- branches/control-0.4a/src/freqplot.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/src/freqplot.py 2011-02-08 22:19:07 UTC (rev 113) @@ -177,12 +177,7 @@ # Select a default range if none is provided if (omega == None): omega = default_frequency_range(syslist) - # Interpolate between wmin and wmax if a tuple or list are provided - elif (isinstance(omega,list) | isinstance(omega,tuple)): - # Only accept tuple or list of length 2 - if (len(omega) != 2): - raise ValueError("Supported frequency arguments are (wmin,wmax) tuple or list, or frequency vector. ") - omega = np.logspace(np.log10(omega[0]),np.log10(omega[1]),num=50,endpoint=True,base=10.0) + for sys in syslist: if (sys.inputs > 1 or sys.outputs > 1): #TODO: Add MIMO nyquist plots. Modified: branches/control-0.4a/src/pzmap.py =================================================================== --- branches/control-0.4a/src/pzmap.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/src/pzmap.py 2011-02-08 22:19:07 UTC (rev 113) @@ -42,7 +42,6 @@ import matplotlib.pyplot as plt import scipy as sp -import numpy as np import xferfcn # Compute poles and zeros for a system @@ -50,10 +49,10 @@ def pzmap(sys, Plot=True): """Plot a pole/zero map for a transfer function""" if (isinstance(sys, xferfcn.TransferFunction)): - poles = sp.roots(np.squeeze(np.asarray(sys.den))); - zeros = sp.roots(np.squeeze(np.asarray(sys.num))); + poles = sp.roots(sys.den); + zeros = sp.roots(sys.num); else: - raise NotImplementedError("pzmap not implemented for state space systems yet.") + raise TypeException if (Plot): # Plot the locations of the poles and zeros Modified: branches/control-0.4a/src/statesp.py =================================================================== --- branches/control-0.4a/src/statesp.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/src/statesp.py 2011-02-08 22:19:07 UTC (rev 113) @@ -73,7 +73,7 @@ """ from numpy import all, angle, any, array, concatenate, cos, delete, dot, \ - empty, exp, eye, matrix, ones, pi, poly, poly1d, roots, shape, sin, zeros + empty, exp, eye, matrix, ones, pi, poly, poly1d, roots, sin, zeros from numpy.random import rand, randn from numpy.linalg import inv, det, solve from numpy.linalg.linalg import LinAlgError @@ -456,8 +456,6 @@ # TODO: transfer function to state space conversion is still buggy! print "Warning: transfer function to state space conversion by td04ad \ is still buggy!" - #print num - #print shape(num) ssout = td04ad(sys.inputs, sys.outputs, index, den, num) states = ssout[0] Added: branches/control-0.4a/src/test.py =================================================================== --- branches/control-0.4a/src/test.py (rev 0) +++ branches/control-0.4a/src/test.py 2011-02-08 22:19:07 UTC (rev 113) @@ -0,0 +1,63 @@ +import subprocess as SP + +def tests_old(): + """ Runs all of the tests written for python-control. This should be + changed in the future so it does run seperate main functions/scripts, + but is integrated into the package. Also, the tests should be in their + own directory /trunk/tests. Running the test should be as simple as: + "import control; control.tests()" + """ + testList = ['TestBDAlg.py','TestConvert.py','TestFreqRsp.py',\ + 'TestMatlab.py','TestModelsimp.py','TestSlycot.py',\ + 'TestStateSp.py','TestStatefbk.py','TestXferFcn.py'] + #Add more tests to this list as they are created. Each is assumed to run + #as a script, as is usually done with unittest. + for test in testList: + print 'Running',test + print SP.Popen(['./'+test],stdout=SP.PIPE).communicate()[0] + print 'Completed',test + +def tests(): + import unittest + try: #auto test discovery is only implemented in python 2.7+ + start_dir='./' #change to a tests directory eventually. + pattern = 'Test*.py' + top_level_dir = './' #this might change? see + #http://docs.python.org/library/unittest.html#unittest.TestLoader.discover + test_mods=unittest.defaultTestLoader.discover(start_dir,pattern=pattern,\ + top_level_dir=top_level_dir) + #now go through each module and run all of its tests. + print 'found test mods and they are',test_mods + for mod in test_mods: + print 'Running tests in',mod + tests = unittest.defaultTestLoader.loadTestFromModule(mod) + t = unittest.TextTestRunner() + t.run(tests) + print 'Completed tests in',mod + except: + #If can't do auto discovery, for now it is hard-coded. This is not ideal for + #when new tests are added or existing ones are reorganized/renamed. + + #remove all of the print commands once tests are debugged and converted to + #unittests. + + print 'Tests may be incomplete' + t=unittest.TextTestRunner() + + testModules = ['TestBDAlg','TestConvert','TestFreqRsp','TestMatlab','TestModelsimp',\ + 'TestStateSp','TestStatefbk','TestXferFcn'] #add additional tests here, or discovery? + suite = unittest.TestSuite() + for mod in testModules: + exec('import '+mod+' as currentModule') + print 'TEST',mod + suite = currentModule.suite() + t.run(suite) + #After tests have been debugged and made into unittests, remove + #the above (except the import) and replace with something like this: + #suiteList.append(ts.suite()) + #alltests = unittest.TestSuite(suiteList) + #t.run(alltests) + + +if __name__=='__main__': + tests() Modified: branches/control-0.4a/src/xferfcn.py =================================================================== --- branches/control-0.4a/src/xferfcn.py 2011-02-08 22:18:58 UTC (rev 112) +++ branches/control-0.4a/src/xferfcn.py 2011-02-08 22:19:07 UTC (rev 113) @@ -344,14 +344,14 @@ def __div__(self, other): """Divide two LTI objects.""" - # Convert the second argument to a transfer function. - other = _convertToTransferFunction(other) - if (self.inputs > 1 or self.outputs > 1 or other.inputs > 1 or other.outputs > 1): raise NotImplementedError("TransferFunction.__div__ is currently \ implemented only for SISO systems.") + # Convert the second argument to a transfer function. + other = _convertToTransferFunction(other) + num = polymul(self.num[0][0], other.den[0][0]) den = polymul(self.den[0][0], other.num[0][0]) @@ -487,9 +487,8 @@ computes the single denominator containing all the poles of sys.den, and reports it as the array d. The output numerator array n is modified to - use the common denominator; the coefficient arrays are also padded with - zeros to be the same size as d. n is an sys.outputs-by-sys.inputs-by- - len(d) array. + use the common denominator. It is an sys.outputs-by-sys.inputs-by- + [something] array. """ @@ -589,12 +588,16 @@ # Multiply in the missing poles. for p in missingpoles[i][j]: num[i][j] = polymul(num[i][j], [1., -p]) - # Pad all numerator polynomials with zeros so that the numerator arrays - # are the same size as the denominator. + # Find the largest numerator polynomial size. + largest = 0 for i in range(self.outputs): for j in range(self.inputs): - num[i][j] = insert(num[i][j], zeros(len(den) - len(num[i][j])), - zeros(len(den) - len(num[i][j]))) + largest = max(largest, len(num[i][j])) + # Pad all smaller numerator polynomials with zeros. + for i in range(self.outputs): + for j in range(self.inputs): + num[i][j] = insert(num[i][j], zeros(largest - len(num[i][j])), + zeros(largest - len(num[i][j]))) # Finally, convert the numerator to a 3-D array. num = array(num) # Remove trivial imaginary parts. Check for nontrivial imaginary parts. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |