$search
00001 #!/usr/bin/env python 00002 # 00003 # Description: ART brake data analysis 00004 # 00005 # Copyright (C) 2009 Austin Robot Technology 00006 # 00007 # License: Modified BSD Software License Agreement 00008 # 00009 # $Id: plot_brake.py 866 2010-11-27 05:10:34Z jack.oquin $ 00010 00011 import sys 00012 import getopt 00013 import os 00014 00015 import numpy 00016 import matplotlib.pyplot as pyplot 00017 import pylab 00018 00019 class brakeData: 00020 "ART brake data analysis." 00021 00022 def __init__(self, name=None): 00023 "Constructor method." 00024 00025 # set default name prefix for plots 00026 if name: 00027 self.name = name 00028 else: 00029 self.name = 'brake' 00030 00031 # initialize some class variables 00032 self.clear() 00033 00034 # default pressure polynomial 00035 self.pr_poly = numpy.array([0.44371437, -3.84781813, 9.19754362]) 00036 # this value from octave (when pressure > 1.001v) 00037 self.oct_poly = numpy.array([0.40480, -3.56259, 8.69659]) 00038 00039 def cd(self, path): 00040 "Change directory to path." 00041 os.chdir(os.path.expanduser(path)) 00042 00043 def clear(self): 00044 "Clear data arrays." 00045 self.c_t = numpy.array([]) 00046 self.c_pos = numpy.array([]) 00047 self.s_t = numpy.array([]) 00048 self.s_pos = numpy.array([]) 00049 self.s_pot = numpy.array([]) 00050 self.s_enc = numpy.array([]) 00051 self.s_pr = numpy.array([]) 00052 00053 def fit_pressure(self, order): 00054 "Fit a polynomial function of potentiometer to pressure voltages. " 00055 (self.pr_poly, resid, rank, singularvalues, 00056 rcond) = numpy.polyfit(self.s_pot, self.s_pr, order, full=True) 00057 print("polynomial coefficients: " + str(self.pr_poly)) 00058 print("residual: " + str(resid)) 00059 00060 def plot(self, save=False): 00061 """ Plot some interesting data from the brake test run. 00062 00063 When save=True write the figures to PNG files, otherwise show 00064 them interactively. 00065 """ 00066 self.plot_encoder(save) 00067 self.plot_position(save) 00068 self.plot_pressure(save) 00069 self.plot_sensors(save) 00070 self.plot_fit(save) 00071 00072 def plot_encoder(self, save=False): 00073 """ Plot encoder data from the brake test run. 00074 00075 When save=True write the figure to a PNG file, otherwise show 00076 it interactively. 00077 """ 00078 pyplot.hold(False) 00079 pyplot.plot(self.s_t, self.s_enc, 'b-', label="encoder ticks") 00080 pyplot.xlabel("time (s)") 00081 pyplot.title(self.name + " encoder values") 00082 self.render_plot(save, "-encoder") 00083 00084 def plot_fit(self, save=False): 00085 """ Plot pressure sensor voltages and corresponding curve fit from 00086 potentiometer values for the brake test run. 00087 00088 When save=True write the figure to a PNG file, otherwise show 00089 it interactively. 00090 """ 00091 pyplot.hold(False) 00092 pyplot.plot(self.s_t, self.s_pr, 'b', label="pressure (v)") 00093 pyplot.hold(True) 00094 pyplot.plot(self.s_t, numpy.polyval(self.pr_poly, self.s_pot), 00095 'r', label="pot -> pressure") 00096 pyplot.xlabel("time (s)") 00097 pyplot.title(self.name + " pressure curve fit") 00098 self.render_plot(save, "-fit") 00099 00100 def plot_position(self, save=False): 00101 """ Plot position requests and results from the brake test run. 00102 00103 When save=True write the figure to a PNG file, otherwise show 00104 it interactively. 00105 """ 00106 pyplot.hold(False) 00107 pyplot.plot(self.s_t, self.s_pos, 'b-', label="position reported") 00108 pyplot.hold(True) 00109 pyplot.plot(self.c_t, self.c_pos, 'rd', label="position request") 00110 pyplot.xlabel("time (s)") 00111 pyplot.title(self.name + " position") 00112 self.render_plot(save, "-position") 00113 00114 def plot_pressure(self, save=False): 00115 """ Plot brake potentiometer and pressure sensor voltages. 00116 00117 When save=True write the figure to a PNG file, otherwise show 00118 it interactively. 00119 """ 00120 pyplot.hold(False) 00121 pyplot.plot(self.s_pot, self.s_pr, 'b+', label="pressure (v)") 00122 pyplot.hold(True) 00123 pyplot.plot(self.s_pot, numpy.polyval(self.pr_poly, self.s_pot), 00124 'rd', label="polynomial fit") 00125 #pyplot.plot(self.s_pot, numpy.polyval(self.oct_poly, self.s_pot), 00126 # 'go', label="octave curve fit") 00127 pyplot.xlabel("potentiometer (v)") 00128 pyplot.title(self.name + " pressure") 00129 self.render_plot(save, "-pressure") 00130 00131 def plot_sensors(self, save=False): 00132 """ Plot pressure and potentiometer sensor voltages from the brake 00133 test run. 00134 00135 When save=True write the figure to a PNG file, otherwise show 00136 it interactively. 00137 """ 00138 pyplot.hold(False) 00139 pyplot.plot(self.s_t, self.s_pot, 'b', label="potentiometer (v)") 00140 pyplot.hold(True) 00141 pyplot.plot(self.s_t, self.s_pr, 'r', label="pressure (v)") 00142 pyplot.xlabel("time (s)") 00143 pyplot.title(self.name + " sensor voltages") 00144 self.render_plot(save, "-sensor") 00145 00146 def pwd(self): 00147 "Print current working directory." 00148 return os.getcwd() 00149 00150 def render_plot(self, save=False, suffix=''): 00151 """Common plot rendering commands. 00152 00153 When save=True write the figure to a PNG file appending suffix 00154 to the file name. Otherwise show the plot interactively. 00155 00156 """ 00157 pyplot.legend(loc="best") 00158 pyplot.axis("auto") 00159 pyplot.grid() 00160 if save: 00161 pylab.savefig(self.name + suffix + ".png") 00162 else: 00163 pyplot.show() 00164 00165 def set_cmd(self, t, pos): 00166 "set command data fields." 00167 self.c_t = numpy.append(self.c_t, t) 00168 self.c_pos = numpy.append(self.c_pos, pos) 00169 00170 def set_state(self, t, pos, pot, enc, pr): 00171 "set state data fields." 00172 self.s_t = numpy.append(self.s_t, t) 00173 self.s_pos = numpy.append(self.s_pos, pos) 00174 self.s_pot = numpy.append(self.s_pot, pot) 00175 self.s_enc = numpy.append(self.s_enc, enc) 00176 self.s_pr = numpy.append(self.s_pr, pr) 00177 00178 00179 b = brakeData() 00180 00181 def usage(progname): 00182 "Print usage message." 00183 print("\n" + str(progname) + """[-h] [ <file.bag> ] 00184 00185 -h, --help print this message 00186 -i, --interactive display plots to terminal (default: save as files) 00187 00188 Run some unit tests of the ART brake data analysis package. 00189 """) 00190 00191 # main program -- for either script or interactive use 00192 def main(argv=None): 00193 "Main program, called as a script or interactively." 00194 00195 if argv is None: 00196 argv = sys.argv # use command args 00197 00198 # extract base name of command, will be '' when imported 00199 progname = os.path.basename(argv[0]) 00200 if progname is "": 00201 progname = "plot_brake.py" 00202 00203 # process parameters 00204 try: 00205 opts, files = getopt.gnu_getopt(argv[1:], 'hi', 00206 ('help', 'interactive')) 00207 except getopt.error, msg: 00208 print(msg) 00209 print("for help use --help") 00210 return 9 00211 00212 save = True 00213 00214 for k,v in opts: 00215 if k in ("-h", "--help"): 00216 usage(progname) 00217 return 2 00218 if k in ("-i", "--interactive"): 00219 save = False 00220 00221 # @todo run some unit tests 00222 00223 return 0 00224 00225 # when called as a script or via python-send-buffer 00226 if __name__ == "__main__": 00227 # run main function and exit 00228 sys.exit(main())