blob: d1570656a4704e3fe2e4805bca9fe6be61c7e397 [file] [log] [blame]
Lee Mracek3e16a862019-01-24 11:15:36 -05001#!/usr/bin/python
Philipp Schrader7861dce2015-02-23 00:27:59 +00002
3import sys
4import numpy
Lee Mracek3e16a862019-01-24 11:15:36 -05005from frc971.analysis.plotter import Plotter
Philipp Schrader7861dce2015-02-23 00:27:59 +00006import argparse
7
8def ReadPlotDefinitions(filename):
9 """
10 Read a file with plotting definitions.
11
12 A plotting definition is a single line that defines what data to search for
13 in order to plot it. The following in a file would duplicate the default
14 behaviour:
15
16 fridge goal height
17 fridge goal angle
18 fridge goal velocity
19 fridge goal angular_velocity
20 fridge output left_arm
21 fridge output right_arm
22 fridge output left_elevator
23 fridge output right_elevator
24
25 Lines are ignored if they start with a hash mark (i.e. '#').
26
Philipp Schrader26681bc2015-04-02 04:25:30 +000027 Lines that end with a "-b X" where X is a number then it designates that line
28 as plotting a boolean value. X is the value plotted when the boolean is true.
29 When the boolean is false then the values is plotted as zero. For example,
30 the following boolean value is drawn to toggle between 2.0 and 0 when the
31 boolean is True and False, respectively:
32
33 fridge status zeroed -b 2.0
34
Philipp Schrader7861dce2015-02-23 00:27:59 +000035 Args:
36 filename: The name of the file to read the definitions from.
37
38 Returns:
39 [[str]]: The definitions in the specified file.
40 """
41 defs = []
42 with open(filename) as fd:
43 for line in fd:
44 raw_defs = line.split()
45
46 # Only add to the list of definitions if the line's not empty and it
47 # doesn't start with a hash.
48 if raw_defs and not raw_defs[0].startswith('#'):
49 defs.append(raw_defs)
50
51 return defs
52
Lee Mracek437d1dd2019-01-22 10:38:01 -050053
54def maybeint(x):
55 try:
56 return int(x)
57 except ValueError:
58 return x
59
60
Philipp Schrader7861dce2015-02-23 00:27:59 +000061def main():
62 # Parse all command line arguments.
63 arg_parser = argparse.ArgumentParser(description='Log Plotter')
64 arg_parser.add_argument('log_file', metavar='LOG_FILE', type=str, \
65 help='The file from which to read logs and plot.')
Philipp Schrader26681bc2015-04-02 04:25:30 +000066 arg_parser.add_argument('--plot-defs', '-p', action='store', type=str, \
Philipp Schrader7861dce2015-02-23 00:27:59 +000067 help='Read the items to plot from this file.')
Philipp Schrader0db60452015-03-15 07:32:38 +000068 arg_parser.add_argument('--no-binary', '-n', action='store_true', \
69 help='Don\'t print the binary name in the legend.')
Philipp Schrader7861dce2015-02-23 00:27:59 +000070
71 args = arg_parser.parse_args(sys.argv[1:])
72
Dave Smithacbca192016-03-06 15:27:23 -080073 p = Plotter()
Philipp Schrader7861dce2015-02-23 00:27:59 +000074
75 # If the user defines the list of data to plot in a file, read it from there.
76 if args.plot_defs:
77 defs = ReadPlotDefinitions(args.plot_defs)
78 for definition in defs:
Lee Mracek437d1dd2019-01-22 10:38:01 -050079 mapped_definitions = map(maybeint, definition[2:])
80 p.Add(definition[0], definition[1], *mapped_definitions)
Philipp Schrader7861dce2015-02-23 00:27:59 +000081
82 # Otherwise use a pre-defined set of data to plot.
83 else:
84 p.Add('fridge', 'goal', 'height')
85 p.Add('fridge', 'goal', 'angle')
86 p.Add('fridge', 'goal', 'velocity')
87 p.Add('fridge', 'goal', 'angular_velocity')
88
89 p.Add('fridge', 'output', 'left_arm')
90 p.Add('fridge', 'output', 'right_arm')
91 p.Add('fridge', 'output', 'left_elevator')
92 p.Add('fridge', 'output', 'right_elevator')
93
Philipp Schrader0db60452015-03-15 07:32:38 +000094 p.PlotFile(args.log_file, args.no_binary)
Philipp Schrader7861dce2015-02-23 00:27:59 +000095
96if __name__ == '__main__':
97 main()