|
From: <kk...@us...> - 2011-02-08 22:16:49
|
Revision: 85
http://python-control.svn.sourceforge.net/python-control/?rev=85&view=rev
Author: kkchen
Date: 2011-02-08 22:16:42 +0000 (Tue, 08 Feb 2011)
Log Message:
-----------
Bode for SISO systems now compatible with new statespace and transferfunction classes. Added a script for testing frequency response functions.
Lauren Padilla <lpa...@pr...>
Modified Paths:
--------------
branches/control-0.4a/src/ctrlutil.py
branches/control-0.4a/src/freqplot.py
branches/control-0.4a/src/xferfcn.py
Added Paths:
-----------
branches/control-0.4a/src/TestFreqRsp.py
Added: branches/control-0.4a/src/TestFreqRsp.py
===================================================================
--- branches/control-0.4a/src/TestFreqRsp.py (rev 0)
+++ branches/control-0.4a/src/TestFreqRsp.py 2011-02-08 22:16:42 UTC (rev 85)
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+
+# Script to test frequency response and frequency response plots like bode, nyquist and gang of 4.
+# Especially need to ensure that nothing SISO is broken and that MIMO at least handles exceptions and has some default to SISO in place.
+
+from statesp import StateSpace
+from matlab import ss, tf, bode
+import numpy as np
+import matplotlib.pyplot as plt
+
+# SISO
+plt.close('all')
+
+A = np.matrix('1,1;0,1')
+B = np.matrix('0;1')
+C = np.matrix('1,0')
+D = 0
+sys = StateSpace(A,B,C,D)
+#or try
+#sys = ss(A,B,C,D)
+
+# test frequency response
+omega = np.linspace(10e-2,10e2,1000)
+frq=sys.freqresp(omega)
+
+# MIMO
+B = np.matrix('1,0;0,1')
+D = np.matrix('0,0')
+sysMIMO = ss(A,B,C,D)
+frqMIMO = sysMIMO.freqresp(omega)
+
+plt.figure(1)
+bode(sys)
+
+systf = tf(sys)
+tfMIMO = tf(sysMIMO)
+
+print systf.pole()
+#print tfMIMO.pole() # - should throw not implemented exception
+#print tfMIMO.zero() # - should throw not implemented exception
+
+plt.figure(2)
+bode(systf)
+
+#bode(sysMIMO) # - should throw not implemented exception
+#bode(tfMIMO) # - should throw not implemented exception
+
+#plt.figure(3)
+#plt.semilogx(omega,20*np.log10(np.squeeze(frq[0])))
+
+#plt.figure(4)
+#bode(sysMIMO,omega)
\ No newline at end of file
Modified: branches/control-0.4a/src/ctrlutil.py
===================================================================
--- branches/control-0.4a/src/ctrlutil.py 2011-02-08 22:16:36 UTC (rev 84)
+++ branches/control-0.4a/src/ctrlutil.py 2011-02-08 22:16:42 UTC (rev 85)
@@ -68,10 +68,11 @@
"""
wrap = 0;
last = angle[0];
+
for k in range(len(angle)):
# See if we need to account for angle wrapping
if (angle[k] - last > period/2):
- wrap = -period
+ wrap = -period
elif (last - angle[k] > period/2):
wrap = period
Modified: branches/control-0.4a/src/freqplot.py
===================================================================
--- branches/control-0.4a/src/freqplot.py 2011-02-08 22:16:36 UTC (rev 84)
+++ branches/control-0.4a/src/freqplot.py 2011-02-08 22:16:42 UTC (rev 85)
@@ -88,50 +88,56 @@
if (not getattr(syslist, '__iter__', False)):
syslist = (syslist,)
- # Select a default range if none is provided
- if (omega == None):
- omega = default_frequency_range(syslist)
-
for sys in syslist:
- # Get the magnitude and phase of the system
- mag, phase, omega = sys.freqresp(omega)
- if Hz: omega = omega/(2*sp.pi)
- if dB: mag = 20*sp.log10(mag)
- phase = unwrap(phase*180/sp.pi, 360)
+ if (sys.inputs > 1 or sys.outputs > 1):
+ #TODO: Add MIMO bode plots.
+ raise NotImplementedError("Bode is currently only implemented for SISO systems.")
+ else:
+ # Select a default range if none is provided
+ if (omega == None):
+ omega = default_frequency_range(syslist)
- # Get the dimensions of the current axis, which we will divide up
- #! TODO: Not current implemented; just use subplot for now
+ # Get the magnitude and phase of the system
+ mag_tmp, phase_tmp, omega = sys.freqresp(omega)
+ mag = np.squeeze(mag_tmp)
+ phase = np.squeeze(phase_tmp)
+ if Hz: omega = omega/(2*sp.pi)
+ if dB: mag = 20*sp.log10(mag)
+ phase = unwrap(phase*180/sp.pi, 360)
- # Magnitude plot
- plt.subplot(211);
- if dB:
- plt.semilogx(omega, mag)
- plt.ylabel("Magnitude (dB)")
- else:
- plt.loglog(omega, mag)
- plt.ylabel("Magnitude")
+ # Get the dimensions of the current axis, which we will divide up
+ #! TODO: Not current implemented; just use subplot for now
- # Add a grid to the plot
- plt.grid(True)
- plt.grid(True, which='minor')
- plt.hold(True);
+ # Magnitude plot
+ plt.subplot(211);
+ if dB:
+ plt.semilogx(omega, mag)
+ plt.ylabel("Magnitude (dB)")
+ else:
+ plt.loglog(omega, mag)
+ plt.ylabel("Magnitude")
- # Phase plot
- plt.subplot(212);
- plt.semilogx(omega, phase)
- plt.hold(True)
+ # Add a grid to the plot
+ plt.grid(True)
+ plt.grid(True, which='minor')
+ plt.hold(True);
- # Add a grid to the plot
- plt.grid(True)
- plt.grid(True, which='minor')
- plt.ylabel("Phase (deg)")
+ # Phase plot
+ plt.subplot(212);
+ plt.semilogx(omega, phase)
+ plt.hold(True)
- # Label the frequency axis
- if Hz:
- plt.xlabel("Frequency (Hz)")
- else:
- plt.xlabel("Frequency (rad/sec)")
+ # Add a grid to the plot
+ plt.grid(True)
+ plt.grid(True, which='minor')
+ plt.ylabel("Phase (deg)")
+ # Label the frequency axis
+ if Hz:
+ plt.xlabel("Frequency (Hz)")
+ else:
+ plt.xlabel("Frequency (rad/sec)")
+
return (211, 212)
# Nyquist plot
@@ -316,8 +322,8 @@
features = np.array(())
for sys in syslist:
# Add new features to the list
- features = np.concatenate((features, np.abs(sys.poles)))
- features = np.concatenate((features, np.abs(sys.zeros)))
+ features = np.concatenate((features, np.abs(sys.pole())))
+ features = np.concatenate((features, np.abs(sys.zero())))
# Get rid of poles and zeros at the origin
features = features[features != 0];
Modified: branches/control-0.4a/src/xferfcn.py
===================================================================
--- branches/control-0.4a/src/xferfcn.py 2011-02-08 22:16:36 UTC (rev 84)
+++ branches/control-0.4a/src/xferfcn.py 2011-02-08 22:16:42 UTC (rev 85)
@@ -413,8 +413,12 @@
def zero(self):
"""Compute the zeros of a transfer function."""
- raise NotImplementedError("TransferFunction.zero is not implemented \
-yet.")
+ if (self.inputs > 1 or self.outputs > 1):
+ raise NotImplementedError("TransferFunction.zero is currently \
+only implemented for SISO systems.")
+ else:
+ #for now, just give zeros of a SISO tf
+ return roots(self.num[0][0])
def feedback(self, other, sign=-1):
"""Feedback interconnection between two LTI objects."""
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|