blob: 3a2dcaac005099f4e3beae206c6f82db55cad784 [file] [log] [blame]
Niko Sohmers3860f8a2024-01-12 21:05:19 -08001// Provides a plot for debugging robot state-related issues.
James Kuszmaul2e818b22024-02-24 09:02:42 -08002import {AosPlotter, MessageHandler} from '../../../aos/network/www/aos_plotter';
Niko Sohmers3860f8a2024-01-12 21:05:19 -08003import {BLUE, BROWN, CYAN, GREEN, PINK, RED, WHITE} from '../../../aos/network/www/colors';
4import * as proxy from '../../../aos/network/www/proxy';
5
6import Connection = proxy.Connection;
7
8const TIME = AosPlotter.TIME;
9const DEFAULT_WIDTH = AosPlotter.DEFAULT_WIDTH * 2;
James Kuszmaul2e818b22024-02-24 09:02:42 -080010const DEFAULT_HEIGHT = AosPlotter.DEFAULT_HEIGHT * 1;
11
12function plotSzsdofSubsystem(
13 name: string, plotter: AosPlotter, element: Element, position: MessageHandler, positionName: string,
14 status: MessageHandler, statusName: string, output: MessageHandler, outputName: string, hasPot:boolean = true): void {
15 {
16 const positionPlot =
17 plotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
18 positionPlot.plot.getAxisLabels().setTitle(name + ' Position');
19 positionPlot.plot.getAxisLabels().setXLabel(TIME);
20 positionPlot.plot.getAxisLabels().setYLabel('Position [rad,m]');
21 positionPlot.addMessageLine(position, [positionName, 'encoder'])
22 .setColor(RED);
23 positionPlot.addMessageLine(position, [positionName, 'absolute_encoder'])
24 .setColor(GREEN);
25 if (hasPot) {
26 positionPlot.addMessageLine(position, [positionName, 'pot'])
27 .setColor(BLUE);
28 }
29 positionPlot
30 .addMessageLine(status, [statusName, 'estimator_state', 'position'])
31 .setColor(BROWN);
32 positionPlot.addMessageLine(status, [statusName, 'position'])
33 .setColor(WHITE);
34 }
35 {
36 const statesPlot =
37 plotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT / 2]);
38 statesPlot.plot.getAxisLabels().setTitle(name + ' State');
39 statesPlot.plot.getAxisLabels().setXLabel(TIME);
40 statesPlot.plot.getAxisLabels().setYLabel('[bool,ZeroingError]');
41 statesPlot.addMessageLine(status, [statusName, 'estopped']).setColor(RED);
42 statesPlot.addMessageLine(status, [statusName, 'zeroed']).setColor(GREEN);
43 statesPlot
44 .addMessageLine(status, [statusName, 'estimator_state', 'errors[]'])
45 .setColor(BLUE)
46 .setDrawLine(false);
47 }
48 {
49 const positionConvergencePlot =
50 plotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
51 positionConvergencePlot.plot.getAxisLabels().setTitle(name + ' Position Goals');
52 positionConvergencePlot.plot.getAxisLabels().setXLabel(TIME);
53 positionConvergencePlot.plot.getAxisLabels().setYLabel('[rad,m]');
54 positionConvergencePlot.addMessageLine(status, [statusName, 'position'])
55 .setColor(RED);
56 positionConvergencePlot.addMessageLine(status, [statusName, 'goal_position'])
57 .setColor(GREEN);
58 positionConvergencePlot
59 .addMessageLine(status, [statusName, 'unprofiled_goal_position'])
60 .setColor(BROWN);
61 }
62 {
63 const velocityConvergencePlot =
64 plotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
65 velocityConvergencePlot.plot.getAxisLabels().setTitle(name + ' Velocity Goals');
66 velocityConvergencePlot.plot.getAxisLabels().setXLabel(TIME);
67 velocityConvergencePlot.plot.getAxisLabels().setYLabel('[rad,m]');
68 velocityConvergencePlot.addMessageLine(status, [statusName, 'velocity'])
69 .setColor(RED);
70 velocityConvergencePlot.addMessageLine(status, [statusName, 'calculated_velocity'])
71 .setColor(RED).setDrawLine(false);
72 velocityConvergencePlot.addMessageLine(status, [statusName, 'goal_velocity'])
73 .setColor(GREEN);
74 velocityConvergencePlot
75 .addMessageLine(status, [statusName, 'unprofiled_goal_velocity'])
76 .setColor(BROWN);
77 }
78 {
79 const outputPlot =
80 plotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
81 outputPlot.plot.getAxisLabels().setTitle(name + ' Outputs');
82 outputPlot.plot.getAxisLabels().setXLabel(TIME);
83 outputPlot.plot.getAxisLabels().setYLabel('[volts]');
84 outputPlot.addMessageLine(output, [outputName])
85 .setColor(RED);
86 outputPlot.addMessageLine(status, [statusName, 'voltage_error'])
87 .setColor(GREEN);
88 outputPlot.addMessageLine(status, [statusName, 'position_power'])
89 .setColor(BLUE);
90 outputPlot.addMessageLine(status, [statusName, 'velocity_power'])
91 .setColor(BROWN);
92 outputPlot.addMessageLine(status, [statusName, 'feedforwards_power'])
93 .setColor(WHITE);
94 }
95}
Niko Sohmers3860f8a2024-01-12 21:05:19 -080096
97export function plotSuperstructure(conn: Connection, element: Element): void {
98 const aosPlotter = new AosPlotter(conn);
James Kuszmaul2e818b22024-02-24 09:02:42 -080099 const status = aosPlotter.addMessageSource(
100 '/superstructure', 'y2024.control_loops.superstructure.Status');
101 const robotState = aosPlotter.addMessageSource('/aos', 'aos.RobotState');
102
103 {
104 const robotStatePlot =
105 aosPlotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
106 robotStatePlot.plot.getAxisLabels().setTitle('Robot State Plot');
107 robotStatePlot.plot.getAxisLabels().setXLabel(TIME);
108 robotStatePlot.plot.getAxisLabels().setYLabel('[bool]');
109 robotStatePlot.addMessageLine(robotState, ['outputs_enabled'])
110 .setColor(RED);
111 robotStatePlot.addMessageLine(status, ['zeroed'])
112 .setColor(GREEN);
113 robotStatePlot.addMessageLine(status, ['estopped'])
114 .setColor(BLUE);
115 }
116}
117
118export function plotClimber(conn: Connection, element: Element): void {
119 const aosPlotter = new AosPlotter(conn);
120 const goal = aosPlotter.addMessageSource(
121 '/superstructure', 'y2024.control_loops.superstructure.Goal');
122 const output = aosPlotter.addMessageSource(
123 '/superstructure', 'y2024.control_loops.superstructure.Output');
124 const status = aosPlotter.addMessageSource(
125 '/superstructure', 'y2024.control_loops.superstructure.Status');
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800126 const position = aosPlotter.addMessageSource(
127 '/superstructure', 'y2024.control_loops.superstructure.Position');
James Kuszmaul2e818b22024-02-24 09:02:42 -0800128 {
129 const goalPlot =
130 aosPlotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
131 goalPlot.plot.getAxisLabels().setTitle('Climber Goal');
132 goalPlot.plot.getAxisLabels().setXLabel(TIME);
133 goalPlot.plot.getAxisLabels().setYLabel('[enum]');
134 goalPlot.addMessageLine(goal, ['climber_goal']).setColor(RED);
135 }
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800136
James Kuszmaul2e818b22024-02-24 09:02:42 -0800137 plotSzsdofSubsystem(
138 'Climber', aosPlotter, element, position, 'climber', status, 'climber',
139 output, 'climber_voltage');
140}
141
142export function plotIntake(conn: Connection, element: Element): void {
143 const aosPlotter = new AosPlotter(conn);
144 const goal = aosPlotter.addMessageSource(
145 '/superstructure', 'y2024.control_loops.superstructure.Goal');
146 const output = aosPlotter.addMessageSource(
147 '/superstructure', 'y2024.control_loops.superstructure.Output');
148 const status = aosPlotter.addMessageSource(
149 '/superstructure', 'y2024.control_loops.superstructure.Status');
150 const position = aosPlotter.addMessageSource(
151 '/superstructure', 'y2024.control_loops.superstructure.Position');
152
153 {
154 const goalPlot =
155 aosPlotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
156 goalPlot.plot.getAxisLabels().setTitle('Intake Goal');
157 goalPlot.plot.getAxisLabels().setXLabel(TIME);
158 goalPlot.plot.getAxisLabels().setYLabel('[enum]');
159 goalPlot.addMessageLine(goal, ['intake_goal']).setColor(RED);
160 }
161 {
162 const rollerPlot =
163 aosPlotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
164 rollerPlot.plot.getAxisLabels().setTitle('Intake Rollers');
165 rollerPlot.plot.getAxisLabels().setXLabel(TIME);
166 rollerPlot.plot.getAxisLabels().setYLabel('[enum,voltage]');
167 rollerPlot.addMessageLine(status, ['intake_roller']).setColor(RED);
168 rollerPlot.addMessageLine(status, ['transfer_roller']).setColor(BLUE);
169 rollerPlot.addMessageLine(output, ['intake_roller_voltage'])
170 .setColor(RED)
171 .setPointSize(0);
172 rollerPlot.addMessageLine(output, ['transfer_roller_voltage'])
173 .setColor(BLUE)
174 .setPointSize(0);
175 }
176
177 plotSzsdofSubsystem(
178 'Intake', aosPlotter, element, position, 'intake_pivot', status, 'intake_pivot',
179 output, 'intake_pivot_voltage', false);
180}
181
182export function plotExtend(conn: Connection, element: Element): void {
183 const aosPlotter = new AosPlotter(conn);
184 const goal = aosPlotter.addMessageSource(
185 '/superstructure', 'y2024.control_loops.superstructure.Goal');
186 const output = aosPlotter.addMessageSource(
187 '/superstructure', 'y2024.control_loops.superstructure.Output');
188 const status = aosPlotter.addMessageSource(
189 '/superstructure', 'y2024.control_loops.superstructure.Status');
190 const position = aosPlotter.addMessageSource(
191 '/superstructure', 'y2024.control_loops.superstructure.Position');
192
193 {
194 const goalPlot =
195 aosPlotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
196 goalPlot.plot.getAxisLabels().setTitle('Extend Goal');
197 goalPlot.plot.getAxisLabels().setXLabel(TIME);
198 goalPlot.plot.getAxisLabels().setYLabel('[enum]');
199 goalPlot.addMessageLine(goal, ['intake_goal']).setColor(RED);
200 }
201 {
202 const rollerPlot =
203 aosPlotter.addPlot(element, [DEFAULT_WIDTH, DEFAULT_HEIGHT]);
204 rollerPlot.plot.getAxisLabels().setTitle('Extend Rollers');
205 rollerPlot.plot.getAxisLabels().setXLabel(TIME);
206 rollerPlot.plot.getAxisLabels().setYLabel('[enum,voltage]');
207 rollerPlot.addMessageLine(status, ['intake_roller']).setColor(RED);
208 rollerPlot.addMessageLine(status, ['transfer_roller']).setColor(BLUE);
209 rollerPlot.addMessageLine(output, ['intake_roller_voltage'])
210 .setColor(RED)
211 .setPointSize(0);
212 rollerPlot.addMessageLine(output, ['transfer_roller_voltage'])
213 .setColor(BLUE)
214 .setPointSize(0);
215 }
216
217 plotSzsdofSubsystem(
218 'Extend', aosPlotter, element, position, 'extend', status, 'extend',
219 output, 'extend_voltage');
Niko Sohmers3860f8a2024-01-12 21:05:19 -0800220}