blob: 948ca9794ad829919841dce83081d769a01dc6b6 [file] [log] [blame]
James Kuszmaul78101402021-09-11 12:42:21 -07001// Provides a plot for debugging robot state-related issues.
2import {AosPlotter} from 'org_frc971/aos/network/www/aos_plotter';
3import * as proxy from 'org_frc971/aos/network/www/proxy';
James Kuszmaulda52ce62021-09-25 21:51:42 -07004import * as configuration from 'org_frc971/aos/configuration_generated';
James Kuszmaul78101402021-09-11 12:42:21 -07005import {BLUE, BROWN, CYAN, GREEN, PINK, RED, WHITE} from 'org_frc971/aos/network/www/colors';
James Kuszmaulda52ce62021-09-25 21:51:42 -07006import {MessageHandler, TimestampedMessage} from 'org_frc971/aos/network/www/aos_plotter';
7import {Point} from 'org_frc971/aos/network/www/plotter';
8import {Table} from 'org_frc971/aos/network/www/reflection';
9import {ByteBuffer} from 'org_frc971/external/com_github_google_flatbuffers/ts/byte-buffer';
James Kuszmaul78101402021-09-11 12:42:21 -070010
11import Connection = proxy.Connection;
James Kuszmaulda52ce62021-09-25 21:51:42 -070012import Schema = configuration.reflection.Schema;
James Kuszmaul78101402021-09-11 12:42:21 -070013
14const TIME = AosPlotter.TIME;
15const DEFAULT_WIDTH = AosPlotter.DEFAULT_WIDTH;
16const DEFAULT_HEIGHT = AosPlotter.DEFAULT_HEIGHT;
17
James Kuszmaulda52ce62021-09-25 21:51:42 -070018class DerivativeMessageHandler extends MessageHandler {
19 // Calculated magnitude of the measured acceleration from the IMU.
20 private acceleration_magnitudes: Point[] = [];
21 constructor(private readonly schema: Schema) {
22 super(schema);
23 }
24 private readScalar(table: Table, fieldName: string): number {
25 return this.parser.readScalar(table, fieldName);
26 }
27
28 // Computes a numerical derivative for a given input.
29 private derivative(input: Point[]): Point[] {
30 const num_measurements = input.length;
31 const results = [];
32 for (let ii = 0; ii < num_measurements - 1; ++ii) {
33 const x0 = input[ii].x;
34 const x1 = input[ii + 1].x;
35 const y0 = input[ii].y;
36 const y1 = input[ii + 1].y;
37 results.push(new Point((x0 + x1) / 2.0, (y1 - y0) / (x1 - x0)));
38 }
39 return results;
40 }
41
42 getField(field: string[]): Point[] {
43 // Any requested input that ends with "_derivative" will get a derivative
44 // calculated for the provided field.
45 const derivative_suffix = "_derivative";
46 const num_fields = field.length;
47 const end_field = field[num_fields - 1];
48 if (end_field.endsWith(derivative_suffix)) {
49 const field_copy = [];
50 for (let ii = 0; ii < num_fields - 1; ++ii) {
51 field_copy.push(field[ii]);
52 }
53 field_copy.push(end_field.slice(0, end_field.length - derivative_suffix.length));
54 return this.derivative(this.getField(field_copy));
55 } else {
56 return super.getField(field);
57 }
58 }
59}
60
James Kuszmaul78101402021-09-11 12:42:21 -070061export function plotTurret(conn: Connection, element: Element) : void {
62 const aosPlotter = new AosPlotter(conn);
63 const goal = aosPlotter.addMessageSource('/superstructure', 'y2020.control_loops.superstructure.Goal');
64 const output = aosPlotter.addMessageSource('/superstructure', 'y2020.control_loops.superstructure.Output');
James Kuszmaulda52ce62021-09-25 21:51:42 -070065 const status = aosPlotter.addRawMessageSource(
66 '/superstructure', 'y2020.control_loops.superstructure.Status',
67 new DerivativeMessageHandler(conn.getSchema('y2020.control_loops.superstructure.Status'))
68 );
James Kuszmaul78101402021-09-11 12:42:21 -070069 const pdpValues =
70 aosPlotter.addMessageSource('/roborio/aos', 'frc971.PDPValues');
James Kuszmaulda52ce62021-09-25 21:51:42 -070071 const localizerDebug =
72 aosPlotter.addMessageSource('/drivetrain', 'y2020.control_loops.drivetrain.LocalizerDebug');
James Kuszmaul78101402021-09-11 12:42:21 -070073
74 var currentTop = 0;
75
76 const turretPosPlot = aosPlotter.addPlot(
77 element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
78 currentTop += DEFAULT_HEIGHT;
James Kuszmaulda52ce62021-09-25 21:51:42 -070079 turretPosPlot.plot.getAxisLabels().setTitle('Turret Position');
James Kuszmaul78101402021-09-11 12:42:21 -070080 turretPosPlot.plot.getAxisLabels().setXLabel(TIME);
81 turretPosPlot.plot.getAxisLabels().setYLabel('rad');
82
83 turretPosPlot.addMessageLine(status, ['aimer', 'turret_position'])
84 .setColor(RED)
85 .setPointSize(0.0);
86 turretPosPlot.addMessageLine(status, ['turret', 'position'])
87 .setColor(GREEN)
88 .setPointSize(0.0);
James Kuszmaulda52ce62021-09-25 21:51:42 -070089 turretPosPlot.addMessageLine(localizerDebug, ['matches[]', 'implied_turret_goal'])
90 .setColor(GREEN)
91 .setDrawLine(false);
James Kuszmaul78101402021-09-11 12:42:21 -070092 turretPosPlot.addMessageLine(status, ['turret', 'unprofiled_goal_position'])
93 .setColor(BLUE)
James Kuszmaulda52ce62021-09-25 21:51:42 -070094 .setDrawLine(false);
95
96 const turretVelPlot = aosPlotter.addPlot(
97 element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
98 currentTop += DEFAULT_HEIGHT;
99 turretVelPlot.plot.getAxisLabels().setTitle('Turret Velocity');
100 turretVelPlot.plot.getAxisLabels().setXLabel(TIME);
101 turretVelPlot.plot.getAxisLabels().setYLabel('rad / sec');
102
103 turretVelPlot.addMessageLine(status, ['aimer', 'turret_velocity'])
104 .setColor(RED)
105 .setPointSize(0.0);
106 turretVelPlot.addMessageLine(status, ['turret', 'velocity'])
107 .setColor(GREEN)
108 .setPointSize(0.0);
109 turretVelPlot.addMessageLine(status, ['turret', 'unprofiled_goal_velocity'])
110 .setColor(BLUE)
111 .setDrawLine(false);
112
113 const turretAccelPlot = aosPlotter.addPlot(
114 element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
115 currentTop += DEFAULT_HEIGHT;
116 turretAccelPlot.plot.getAxisLabels().setTitle('Turret Acceleration');
117 turretAccelPlot.plot.getAxisLabels().setXLabel(TIME);
118 turretAccelPlot.plot.getAxisLabels().setYLabel('rad / sec / sec');
119
120 turretAccelPlot.addMessageLine(status, ['aimer', 'turret_velocity_derivative'])
121 .setColor(RED)
James Kuszmaul78101402021-09-11 12:42:21 -0700122 .setPointSize(0.0);
123
124 const turretVoltagePlot = aosPlotter.addPlot(
125 element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
126 currentTop += DEFAULT_HEIGHT;
127 turretVoltagePlot.plot.getAxisLabels().setTitle('Turret Voltage');
128 turretVoltagePlot.plot.getAxisLabels().setXLabel(TIME);
129 turretVoltagePlot.plot.getAxisLabels().setYLabel('V');
130
James Kuszmaulda52ce62021-09-25 21:51:42 -0700131 turretVoltagePlot.addMessageLine(status, ['turret', 'voltage_error'])
132 .setColor(GREEN)
133 .setPointSize(0.0);
134 turretVoltagePlot.addMessageLine(status, ['turret', 'position_power'])
135 .setColor(BLUE)
136 .setPointSize(0.0);
137 turretVoltagePlot.addMessageLine(status, ['turret', 'velocity_power'])
138 .setColor(CYAN)
139 .setPointSize(0.0);
James Kuszmaul78101402021-09-11 12:42:21 -0700140 turretVoltagePlot.addMessageLine(output, ['turret_voltage'])
141 .setColor(RED)
142 .setPointSize(0.0);
143
144 const currentPlot = aosPlotter.addPlot(
145 element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
146 currentTop += DEFAULT_HEIGHT;
147 currentPlot.plot.getAxisLabels().setTitle('Current');
148 currentPlot.plot.getAxisLabels().setXLabel(TIME);
149 currentPlot.plot.getAxisLabels().setYLabel('Amps');
James Kuszmaulda52ce62021-09-25 21:51:42 -0700150 currentPlot.plot.setDefaultYRange([0.0, 40.0]);
James Kuszmaul78101402021-09-11 12:42:21 -0700151
152 currentPlot.addMessageLine(pdpValues, ['currents[6]'])
153 .setColor(GREEN)
154 .setPointSize(0.0);
155
156
157 const targetDistancePlot = aosPlotter.addPlot(
158 element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
159 currentTop += DEFAULT_HEIGHT;
160 targetDistancePlot.plot.getAxisLabels().setTitle('Target distance');
161 targetDistancePlot.plot.getAxisLabels().setXLabel(TIME);
162 targetDistancePlot.plot.getAxisLabels().setYLabel('m');
163
164 targetDistancePlot.addMessageLine(status, ['aimer', 'target_distance'])
165 .setColor(RED)
166 .setPointSize(0.0);
167
168 const targetChoicePlot = aosPlotter.addPlot(
169 element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
170 currentTop += DEFAULT_HEIGHT;
171 targetChoicePlot.plot.getAxisLabels().setTitle('Target choice');
172 targetChoicePlot.plot.getAxisLabels().setXLabel(TIME);
173 targetChoicePlot.plot.getAxisLabels().setYLabel('[bool]');
174 targetChoicePlot.plot.setDefaultYRange([-0.05, 1.05]);
175
176 targetChoicePlot.addMessageLine(status, ['aimer', 'aiming_for_inner_port'])
177 .setColor(RED)
178 .setPointSize(0.0);
James Kuszmaulda52ce62021-09-25 21:51:42 -0700179
180 const imageAcceptedPlot = aosPlotter.addPlot(
181 element, [0, currentTop], [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
182 currentTop += DEFAULT_HEIGHT;
183 imageAcceptedPlot.plot.getAxisLabels().setTitle('Image Acceptance');
184 imageAcceptedPlot.plot.getAxisLabels().setXLabel(TIME);
185 imageAcceptedPlot.plot.getAxisLabels().setYLabel('[bool]');
186 imageAcceptedPlot.plot.setDefaultYRange([-0.05, 1.05]);
187
188 imageAcceptedPlot.addMessageLine(localizerDebug, ['matches[]', 'accepted'])
189 .setColor(RED)
190 .setDrawLine(false);
James Kuszmaul78101402021-09-11 12:42:21 -0700191}