00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00026 if name:
00027 self.name = name
00028 else:
00029 self.name = 'brake'
00030
00031
00032 self.clear()
00033
00034
00035 self.pr_poly = numpy.array([0.44371437, -3.84781813, 9.19754362])
00036
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
00126
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
00192 def main(argv=None):
00193 "Main program, called as a script or interactively."
00194
00195 if argv is None:
00196 argv = sys.argv
00197
00198
00199 progname = os.path.basename(argv[0])
00200 if progname is "":
00201 progname = "plot_brake.py"
00202
00203
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
00222
00223 return 0
00224
00225
00226 if __name__ == "__main__":
00227
00228 sys.exit(main())