James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 1 | // Provides a plot for debugging robot state-related issues. |
| 2 | import {AosPlotter} from 'org_frc971/aos/network/www/aos_plotter'; |
| 3 | import * as proxy from 'org_frc971/aos/network/www/proxy'; |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 4 | import * as configuration from 'org_frc971/aos/configuration_generated'; |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 5 | import {BLUE, BROWN, CYAN, GREEN, PINK, RED, WHITE} from 'org_frc971/aos/network/www/colors'; |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 6 | import {MessageHandler, TimestampedMessage} from 'org_frc971/aos/network/www/aos_plotter'; |
| 7 | import {Point} from 'org_frc971/aos/network/www/plotter'; |
| 8 | import {Table} from 'org_frc971/aos/network/www/reflection'; |
James Kuszmaul | dac091f | 2022-03-22 09:35:06 -0700 | [diff] [blame] | 9 | import {ByteBuffer} from 'flatbuffers'; |
James Kuszmaul | 136aa2b | 2022-04-02 14:50:56 -0700 | [diff] [blame] | 10 | import {Schema} from 'flatbuffers_reflection/reflection_generated'; |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 11 | |
| 12 | import Connection = proxy.Connection; |
| 13 | |
| 14 | const TIME = AosPlotter.TIME; |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 15 | |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 16 | class DerivativeMessageHandler extends MessageHandler { |
| 17 | // Calculated magnitude of the measured acceleration from the IMU. |
| 18 | private acceleration_magnitudes: Point[] = []; |
| 19 | constructor(private readonly schema: Schema) { |
| 20 | super(schema); |
| 21 | } |
James Kuszmaul | dac091f | 2022-03-22 09:35:06 -0700 | [diff] [blame] | 22 | private readScalar(table: Table, fieldName: string): number|BigInt|null { |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 23 | return this.parser.readScalar(table, fieldName); |
| 24 | } |
| 25 | |
| 26 | // Computes a numerical derivative for a given input. |
| 27 | private derivative(input: Point[]): Point[] { |
| 28 | const num_measurements = input.length; |
| 29 | const results = []; |
| 30 | for (let ii = 0; ii < num_measurements - 1; ++ii) { |
| 31 | const x0 = input[ii].x; |
| 32 | const x1 = input[ii + 1].x; |
| 33 | const y0 = input[ii].y; |
| 34 | const y1 = input[ii + 1].y; |
| 35 | results.push(new Point((x0 + x1) / 2.0, (y1 - y0) / (x1 - x0))); |
| 36 | } |
| 37 | return results; |
| 38 | } |
| 39 | |
| 40 | getField(field: string[]): Point[] { |
| 41 | // Any requested input that ends with "_derivative" will get a derivative |
| 42 | // calculated for the provided field. |
| 43 | const derivative_suffix = "_derivative"; |
| 44 | const num_fields = field.length; |
| 45 | const end_field = field[num_fields - 1]; |
| 46 | if (end_field.endsWith(derivative_suffix)) { |
| 47 | const field_copy = []; |
| 48 | for (let ii = 0; ii < num_fields - 1; ++ii) { |
| 49 | field_copy.push(field[ii]); |
| 50 | } |
| 51 | field_copy.push(end_field.slice(0, end_field.length - derivative_suffix.length)); |
| 52 | return this.derivative(this.getField(field_copy)); |
| 53 | } else { |
| 54 | return super.getField(field); |
| 55 | } |
| 56 | } |
| 57 | } |
| 58 | |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 59 | export function plotTurret(conn: Connection, element: Element) : void { |
| 60 | const aosPlotter = new AosPlotter(conn); |
| 61 | const goal = aosPlotter.addMessageSource('/superstructure', 'y2020.control_loops.superstructure.Goal'); |
| 62 | const output = aosPlotter.addMessageSource('/superstructure', 'y2020.control_loops.superstructure.Output'); |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 63 | const status = aosPlotter.addRawMessageSource( |
| 64 | '/superstructure', 'y2020.control_loops.superstructure.Status', |
| 65 | new DerivativeMessageHandler(conn.getSchema('y2020.control_loops.superstructure.Status')) |
| 66 | ); |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 67 | const pdpValues = |
| 68 | aosPlotter.addMessageSource('/roborio/aos', 'frc971.PDPValues'); |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 69 | const localizerDebug = |
| 70 | aosPlotter.addMessageSource('/drivetrain', 'y2020.control_loops.drivetrain.LocalizerDebug'); |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 71 | |
Austin Schuh | c2e9c50 | 2021-11-25 21:23:24 -0800 | [diff] [blame] | 72 | const turretPosPlot = aosPlotter.addPlot(element); |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 73 | turretPosPlot.plot.getAxisLabels().setTitle('Turret Position'); |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 74 | turretPosPlot.plot.getAxisLabels().setXLabel(TIME); |
| 75 | turretPosPlot.plot.getAxisLabels().setYLabel('rad'); |
| 76 | |
| 77 | turretPosPlot.addMessageLine(status, ['aimer', 'turret_position']) |
| 78 | .setColor(RED) |
| 79 | .setPointSize(0.0); |
| 80 | turretPosPlot.addMessageLine(status, ['turret', 'position']) |
| 81 | .setColor(GREEN) |
| 82 | .setPointSize(0.0); |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 83 | turretPosPlot.addMessageLine(localizerDebug, ['matches[]', 'implied_turret_goal']) |
| 84 | .setColor(GREEN) |
| 85 | .setDrawLine(false); |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 86 | turretPosPlot.addMessageLine(status, ['turret', 'unprofiled_goal_position']) |
| 87 | .setColor(BLUE) |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 88 | .setDrawLine(false); |
| 89 | |
Austin Schuh | c2e9c50 | 2021-11-25 21:23:24 -0800 | [diff] [blame] | 90 | const turretVelPlot = aosPlotter.addPlot(element); |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 91 | turretVelPlot.plot.getAxisLabels().setTitle('Turret Velocity'); |
| 92 | turretVelPlot.plot.getAxisLabels().setXLabel(TIME); |
| 93 | turretVelPlot.plot.getAxisLabels().setYLabel('rad / sec'); |
| 94 | |
| 95 | turretVelPlot.addMessageLine(status, ['aimer', 'turret_velocity']) |
| 96 | .setColor(RED) |
| 97 | .setPointSize(0.0); |
| 98 | turretVelPlot.addMessageLine(status, ['turret', 'velocity']) |
| 99 | .setColor(GREEN) |
| 100 | .setPointSize(0.0); |
| 101 | turretVelPlot.addMessageLine(status, ['turret', 'unprofiled_goal_velocity']) |
| 102 | .setColor(BLUE) |
| 103 | .setDrawLine(false); |
| 104 | |
Austin Schuh | c2e9c50 | 2021-11-25 21:23:24 -0800 | [diff] [blame] | 105 | const turretAccelPlot = aosPlotter.addPlot(element); |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 106 | turretAccelPlot.plot.getAxisLabels().setTitle('Turret Acceleration'); |
| 107 | turretAccelPlot.plot.getAxisLabels().setXLabel(TIME); |
| 108 | turretAccelPlot.plot.getAxisLabels().setYLabel('rad / sec / sec'); |
| 109 | |
| 110 | turretAccelPlot.addMessageLine(status, ['aimer', 'turret_velocity_derivative']) |
| 111 | .setColor(RED) |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 112 | .setPointSize(0.0); |
| 113 | |
Austin Schuh | c2e9c50 | 2021-11-25 21:23:24 -0800 | [diff] [blame] | 114 | const turretVoltagePlot = aosPlotter.addPlot(element); |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 115 | turretVoltagePlot.plot.getAxisLabels().setTitle('Turret Voltage'); |
| 116 | turretVoltagePlot.plot.getAxisLabels().setXLabel(TIME); |
| 117 | turretVoltagePlot.plot.getAxisLabels().setYLabel('V'); |
| 118 | |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 119 | turretVoltagePlot.addMessageLine(status, ['turret', 'voltage_error']) |
| 120 | .setColor(GREEN) |
| 121 | .setPointSize(0.0); |
| 122 | turretVoltagePlot.addMessageLine(status, ['turret', 'position_power']) |
| 123 | .setColor(BLUE) |
| 124 | .setPointSize(0.0); |
| 125 | turretVoltagePlot.addMessageLine(status, ['turret', 'velocity_power']) |
| 126 | .setColor(CYAN) |
| 127 | .setPointSize(0.0); |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 128 | turretVoltagePlot.addMessageLine(output, ['turret_voltage']) |
| 129 | .setColor(RED) |
| 130 | .setPointSize(0.0); |
| 131 | |
Austin Schuh | c2e9c50 | 2021-11-25 21:23:24 -0800 | [diff] [blame] | 132 | const currentPlot = aosPlotter.addPlot(element); |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 133 | currentPlot.plot.getAxisLabels().setTitle('Current'); |
| 134 | currentPlot.plot.getAxisLabels().setXLabel(TIME); |
| 135 | currentPlot.plot.getAxisLabels().setYLabel('Amps'); |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 136 | currentPlot.plot.setDefaultYRange([0.0, 40.0]); |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 137 | |
| 138 | currentPlot.addMessageLine(pdpValues, ['currents[6]']) |
| 139 | .setColor(GREEN) |
| 140 | .setPointSize(0.0); |
| 141 | |
| 142 | |
Austin Schuh | c2e9c50 | 2021-11-25 21:23:24 -0800 | [diff] [blame] | 143 | const targetDistancePlot = aosPlotter.addPlot(element); |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 144 | targetDistancePlot.plot.getAxisLabels().setTitle('Target distance'); |
| 145 | targetDistancePlot.plot.getAxisLabels().setXLabel(TIME); |
| 146 | targetDistancePlot.plot.getAxisLabels().setYLabel('m'); |
| 147 | |
| 148 | targetDistancePlot.addMessageLine(status, ['aimer', 'target_distance']) |
| 149 | .setColor(RED) |
| 150 | .setPointSize(0.0); |
| 151 | |
Austin Schuh | c2e9c50 | 2021-11-25 21:23:24 -0800 | [diff] [blame] | 152 | const targetChoicePlot = aosPlotter.addPlot(element); |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 153 | targetChoicePlot.plot.getAxisLabels().setTitle('Target choice'); |
| 154 | targetChoicePlot.plot.getAxisLabels().setXLabel(TIME); |
| 155 | targetChoicePlot.plot.getAxisLabels().setYLabel('[bool]'); |
| 156 | targetChoicePlot.plot.setDefaultYRange([-0.05, 1.05]); |
| 157 | |
| 158 | targetChoicePlot.addMessageLine(status, ['aimer', 'aiming_for_inner_port']) |
| 159 | .setColor(RED) |
| 160 | .setPointSize(0.0); |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 161 | |
Austin Schuh | c2e9c50 | 2021-11-25 21:23:24 -0800 | [diff] [blame] | 162 | const imageAcceptedPlot = aosPlotter.addPlot(element); |
James Kuszmaul | da52ce6 | 2021-09-25 21:51:42 -0700 | [diff] [blame] | 163 | imageAcceptedPlot.plot.getAxisLabels().setTitle('Image Acceptance'); |
| 164 | imageAcceptedPlot.plot.getAxisLabels().setXLabel(TIME); |
| 165 | imageAcceptedPlot.plot.getAxisLabels().setYLabel('[bool]'); |
| 166 | imageAcceptedPlot.plot.setDefaultYRange([-0.05, 1.05]); |
| 167 | |
| 168 | imageAcceptedPlot.addMessageLine(localizerDebug, ['matches[]', 'accepted']) |
| 169 | .setColor(RED) |
| 170 | .setDrawLine(false); |
James Kuszmaul | 7810140 | 2021-09-11 12:42:21 -0700 | [diff] [blame] | 171 | } |