blob: f383c080aaf032b573cfe1e3a5a016a1dadbdec8 [file] [log] [blame]
Niko Sohmers3860f8a2024-01-12 21:05:19 -08001import {ByteBuffer} from 'flatbuffers'
2import {ClientStatistics} from '../../aos/network/message_bridge_client_generated'
3import {ServerStatistics, State as ConnectionState} from '../../aos/network/message_bridge_server_generated'
4import {Connection} from '../../aos/network/www/proxy'
5import {ZeroingError} from '../../frc971/control_loops/control_loops_generated'
6import {Position as DrivetrainPosition} from '../../frc971/control_loops/drivetrain/drivetrain_position_generated'
7import {CANPosition as DrivetrainCANPosition} from '../../frc971/control_loops/drivetrain/drivetrain_can_position_generated'
8import {Status as DrivetrainStatus} from '../../frc971/control_loops/drivetrain/drivetrain_status_generated'
9import {LocalizerOutput} from '../../frc971/control_loops/drivetrain/localization/localizer_output_generated'
10import {TargetMap} from '../../frc971/vision/target_map_generated'
11
12
13import {FIELD_LENGTH, FIELD_WIDTH, FT_TO_M, IN_TO_M} from './constants';
14
15// (0,0) is field center, +X is toward red DS
16const FIELD_SIDE_Y = FIELD_WIDTH / 2;
17const FIELD_EDGE_X = FIELD_LENGTH / 2;
18
Niko Sohmers2d108762024-02-02 20:21:14 -080019const ROBOT_WIDTH = 29 * IN_TO_M;
Niko Sohmers3860f8a2024-01-12 21:05:19 -080020const ROBOT_LENGTH = 32 * IN_TO_M;
21
22export class FieldHandler {
Niko Sohmers2d108762024-02-02 20:21:14 -080023 private canvas = document.createElement('canvas');
24 private fieldImage: HTMLImageElement = new Image();
Niko Sohmers3860f8a2024-01-12 21:05:19 -080025 constructor(private readonly connection: Connection) {
Niko Sohmers2d108762024-02-02 20:21:14 -080026 (document.getElementById('field') as HTMLElement).appendChild(this.canvas);
27
28 this.fieldImage.src = '2024.png';
29 }
30
31 drawField(): void {
32 const ctx = this.canvas.getContext('2d');
33 ctx.save();
34 ctx.scale(1.0, -1.0);
35 ctx.drawImage(
36 this.fieldImage, 0, 0, this.fieldImage.width, this.fieldImage.height,
37 -FIELD_EDGE_X, -FIELD_SIDE_Y, FIELD_LENGTH, FIELD_WIDTH);
38 ctx.restore();
39 }
40
41 draw(): void {
42 this.reset();
43 this.drawField();
44
45 window.requestAnimationFrame(() => this.draw());
46 }
47
48 reset(): void {
49 const ctx = this.canvas.getContext('2d');
50 // Empty space from the canvas boundary to the image
51 const IMAGE_PADDING = 10;
52 ctx.setTransform(1, 0, 0, 1, 0, 0);
53 const size = window.innerHeight * 0.9;
54 ctx.canvas.height = size;
55 const width = size / 2 + 20;
56 ctx.canvas.width = width;
57 ctx.clearRect(0, 0, size, width);
58
59 // Translate to center of display.
60 ctx.translate(width / 2, size / 2);
61 // Coordinate system is:
62 // x -> forward.
63 // y -> to the left.
64 ctx.rotate(-Math.PI / 2);
65 ctx.scale(1, -1);
66
67 const M_TO_PX = (size - IMAGE_PADDING) / FIELD_LENGTH;
68 ctx.scale(M_TO_PX, M_TO_PX);
69 ctx.lineWidth = 1 / M_TO_PX;
Niko Sohmers3860f8a2024-01-12 21:05:19 -080070 }
71}