Draw field on new webpage.
Change-Id: Ibf71aa126e51cb6a6110d890c13d0633fbc3087b
diff --git a/aos/network/www/config_handler.ts b/aos/network/www/config_handler.ts
index 72b496e..ae9896c 100644
--- a/aos/network/www/config_handler.ts
+++ b/aos/network/www/config_handler.ts
@@ -3,16 +3,26 @@
export class ConfigHandler {
private readonly root_div = document.getElementById('config');
+ private readonly tree_div;
constructor(
private readonly config: Configuration,
- private readonly dataChannel: RTCDataChannel) {}
+ private readonly dataChannel: RTCDataChannel) {
+ const show_button = document.createElement('button');
+ show_button.addEventListener('click', () => this.toggleConfig());
+ const show_text = document.createTextNode('Show/Hide Config');
+ show_button.appendChild(show_text);
+ this.tree_div = document.createElement('div');
+ this.tree_div.hidden = true;
+ this.root_div.appendChild(show_button);
+ this.root_div.appendChild(this.tree_div);
+ }
printConfig() {
for (const i = 0; i < this.config.channelsLength(); i++) {
const channel_div = document.createElement('div');
channel_div.classList.add('channel');
- this.root_div.appendChild(channel_div);
+ this.tree_div.appendChild(channel_div);
const input_el = document.createElement('input');
input_el.setAttribute('data-index', i);
@@ -64,4 +74,8 @@
console.log('connect', array);
this.dataChannel.send(array.buffer.slice(array.byteOffset));
}
+
+ toggleConfig() {
+ this.tree_div.hidden = !this.tree_div.hidden;
+ }
}
diff --git a/y2020/BUILD b/y2020/BUILD
index f3ea4d6..4aa851f 100644
--- a/y2020/BUILD
+++ b/y2020/BUILD
@@ -166,6 +166,7 @@
srcs = ["web_proxy.sh"],
data = [
":config.json",
+ "//y2020/www:field_main_bundle",
"//aos/network:web_proxy_main",
"//y2020/www:files",
"//y2020/www:flatbuffers",
diff --git a/y2020/www/BUILD b/y2020/www/BUILD
index 292618b..e8c227d 100644
--- a/y2020/www/BUILD
+++ b/y2020/www/BUILD
@@ -16,6 +16,18 @@
],
)
+ts_library(
+ name = "field_main",
+ srcs = [
+ "field_main.ts",
+ "field_handler.ts",
+ "constants.ts",
+ ],
+ deps = [
+ "//aos/network/www:proxy",
+ ],
+)
+
rollup_bundle(
name = "main_bundle",
entry_point = "y2020/www/main",
@@ -25,6 +37,15 @@
],
)
+rollup_bundle(
+ name = "field_main_bundle",
+ entry_point = "y2020/www/field_main",
+ deps = [
+ "field_main",
+ ],
+ visibility = ["//y2020:__subpackages__"],
+)
+
filegroup(
name = "files",
srcs = glob([
diff --git a/y2020/www/constants.ts b/y2020/www/constants.ts
new file mode 100644
index 0000000..b94d7a7
--- /dev/null
+++ b/y2020/www/constants.ts
@@ -0,0 +1,7 @@
+// Conversion constants to meters
+export const IN_TO_M = 0.0254;
+export const FT_TO_M = 0.3048;
+// Dimensions of the field in meters
+export const FIELD_WIDTH = 26 * FT_TO_M + 11.25 * IN_TO_M;
+export const FIELD_LENGTH = 52 * FT_TO_M + 5.25 * IN_TO_M;
+
diff --git a/y2020/www/field.html b/y2020/www/field.html
new file mode 100644
index 0000000..37452a3
--- /dev/null
+++ b/y2020/www/field.html
@@ -0,0 +1,12 @@
+<html>
+ <head>
+ <script src="flatbuffers.js"></script>
+ <script src="field_main_bundle.min.js" defer></script>
+ <link rel="stylesheet" href="styles.css">
+ </head>
+ <body>
+ <div id="config">
+ </div>
+ </body>
+</html>
+
diff --git a/y2020/www/field_handler.ts b/y2020/www/field_handler.ts
new file mode 100644
index 0000000..a960a63
--- /dev/null
+++ b/y2020/www/field_handler.ts
@@ -0,0 +1,167 @@
+import {FIELD_LENGTH, FIELD_WIDTH, FT_TO_M, IN_TO_M} from './constants';
+
+const FIELD_SIDE_Y = FIELD_WIDTH / 2;
+const FIELD_CENTER_X = (198.75 + 116) * IN_TO_M;
+
+const DS_WIDTH = 69 * IN_TO_M;
+const DS_ANGLE = 20 * Math.PI / 180;
+const DS_END_X = DS_WIDTH * Math.sin(DS_ANGLE);
+const OTHER_DS_X = FIELD_LENGTH - DS_END_X;
+const DS_INSIDE_Y = FIELD_SIDE_Y - DS_WIDTH * Math.cos(DS_ANGLE);
+
+const TRENCH_START_X = 206.57 * IN_TO_M;
+const TRENCH_END_X = FIELD_LENGTH - TRENCH_START_X;
+const TRENCH_WIDTH = 55.5 * IN_TO_M;
+const TRENCH_INSIDE = FIELD_SIDE_Y - TRENCH_WIDTH;
+
+const SPINNER_LENGTH = 30 * IN_TO_M;
+const SPINNER_TOP_X = 374.59 * IN_TO_M;
+const SPINNER_BOTTOM_X = SPINNER_TOP_X - SPINNER_LENGTH;
+
+const SHIELD_BOTTOM_X = FIELD_CENTER_X - 116 * IN_TO_M;
+const SHIELD_BOTTOM_Y = 43.75 * IN_TO_M;
+
+const SHIELD_TOP_X = FIELD_CENTER_X + 116 * IN_TO_M;
+const SHIELD_TOP_Y = -43.75 * IN_TO_M;
+
+const SHIELD_RIGHT_X = FIELD_CENTER_X - 51.06 * IN_TO_M;
+const SHIELD_RIGHT_Y = -112.88 * IN_TO_M;
+
+const SHIELD_LEFT_X = FIELD_CENTER_X + 51.06 * IN_TO_M;
+const SHIELD_LEFT_Y = 112.88 * IN_TO_M;
+
+const SHIELD_CENTER_TOP_X = (SHIELD_TOP_X + SHIELD_LEFT_X) / 2
+const SHIELD_CENTER_TOP_Y = (SHIELD_TOP_Y + SHIELD_LEFT_Y) / 2
+
+const SHIELD_CENTER_BOTTOM_X = (SHIELD_BOTTOM_X + SHIELD_RIGHT_X) / 2
+const SHIELD_CENTER_BOTTOM_Y = (SHIELD_BOTTOM_Y + SHIELD_RIGHT_Y) / 2
+
+const INITIATION_X = 120 * IN_TO_M;
+const FAR_INITIATION_X = FIELD_LENGTH - 120 * IN_TO_M;
+
+const TARGET_ZONE_TIP_X = 30 * IN_TO_M;
+const TARGET_ZONE_WIDTH = 48 * IN_TO_M;
+const LOADING_ZONE_WIDTH = 60 * IN_TO_M;
+
+export class FieldHandler {
+ private canvas = document.createElement('canvas');
+
+ constructor() {
+ document.body.appendChild(this.canvas);
+ }
+
+ drawField(): void {
+ const MY_COLOR = 'red';
+ const OTHER_COLOR = 'blue';
+ const ctx = this.canvas.getContext('2d');
+ // draw perimiter
+ ctx.beginPath();
+ ctx.moveTo(0, DS_INSIDE_Y);
+ ctx.lineTo(DS_END_X, FIELD_SIDE_Y);
+ ctx.lineTo(OTHER_DS_X, FIELD_SIDE_Y);
+ ctx.lineTo(FIELD_LENGTH, DS_INSIDE_Y);
+ ctx.lineTo(FIELD_LENGTH, -DS_INSIDE_Y);
+ ctx.lineTo(OTHER_DS_X, -FIELD_SIDE_Y);
+ ctx.lineTo(DS_END_X, -FIELD_SIDE_Y);
+ ctx.lineTo(0, -DS_INSIDE_Y);
+ ctx.lineTo(0, DS_INSIDE_Y);
+ ctx.stroke();
+
+ // draw shield generator
+ ctx.beginPath();
+ ctx.moveTo(SHIELD_BOTTOM_X, SHIELD_BOTTOM_Y);
+ ctx.lineTo(SHIELD_RIGHT_X, SHIELD_RIGHT_Y);
+ ctx.lineTo(SHIELD_TOP_X, SHIELD_TOP_Y);
+ ctx.lineTo(SHIELD_LEFT_X, SHIELD_LEFT_Y);
+ ctx.lineTo(SHIELD_BOTTOM_X, SHIELD_BOTTOM_Y);
+ ctx.moveTo(SHIELD_CENTER_TOP_X, SHIELD_CENTER_TOP_Y);
+ ctx.lineTo(SHIELD_CENTER_BOTTOM_X, SHIELD_CENTER_BOTTOM_Y);
+ ctx.stroke();
+
+ // draw trenches
+ ctx.strokeStyle = MY_COLOR;
+ ctx.beginPath();
+ ctx.moveTo(TRENCH_START_X, FIELD_SIDE_Y);
+ ctx.lineTo(TRENCH_START_X, TRENCH_INSIDE);
+ ctx.lineTo(TRENCH_END_X, TRENCH_INSIDE);
+ ctx.lineTo(TRENCH_END_X, FIELD_SIDE_Y);
+ ctx.stroke();
+
+ ctx.strokeStyle = OTHER_COLOR;
+ ctx.beginPath();
+ ctx.moveTo(TRENCH_START_X, -FIELD_SIDE_Y);
+ ctx.lineTo(TRENCH_START_X, -TRENCH_INSIDE);
+ ctx.lineTo(TRENCH_END_X, -TRENCH_INSIDE);
+ ctx.lineTo(TRENCH_END_X, -FIELD_SIDE_Y);
+ ctx.stroke();
+
+ ctx.strokeStyle = 'black';
+ ctx.beginPath();
+ ctx.moveTo(SPINNER_TOP_X, FIELD_SIDE_Y);
+ ctx.lineTo(SPINNER_TOP_X, TRENCH_INSIDE);
+ ctx.lineTo(SPINNER_BOTTOM_X, TRENCH_INSIDE);
+ ctx.lineTo(SPINNER_BOTTOM_X, FIELD_SIDE_Y);
+ ctx.moveTo(FIELD_LENGTH - SPINNER_TOP_X, -FIELD_SIDE_Y);
+ ctx.lineTo(FIELD_LENGTH - SPINNER_TOP_X, -TRENCH_INSIDE);
+ ctx.lineTo(FIELD_LENGTH - SPINNER_BOTTOM_X, -TRENCH_INSIDE);
+ ctx.lineTo(FIELD_LENGTH - SPINNER_BOTTOM_X, -FIELD_SIDE_Y);
+ ctx.stroke();
+
+ // draw initiation lines
+ ctx.beginPath();
+ ctx.moveTo(INITIATION_X, FIELD_SIDE_Y);
+ ctx.lineTo(INITIATION_X, -FIELD_SIDE_Y);
+ ctx.moveTo(FAR_INITIATION_X, FIELD_SIDE_Y);
+ ctx.lineTo(FAR_INITIATION_X, -FIELD_SIDE_Y);
+ ctx.stroke();
+
+ // draw target/loading zones
+ ctx.strokeStyle = MY_COLOR;
+ ctx.beginPath();
+ ctx.moveTo(0, DS_INSIDE_Y);
+ ctx.lineTo(TARGET_ZONE_TIP_X, DS_INSIDE_Y - 0.5 * TARGET_ZONE_WIDTH);
+ ctx.lineTo(0, DS_INSIDE_Y - TARGET_ZONE_WIDTH);
+
+ ctx.moveTo(FIELD_LENGTH, DS_INSIDE_Y);
+ ctx.lineTo(
+ FIELD_LENGTH - TARGET_ZONE_TIP_X,
+ DS_INSIDE_Y - 0.5 * LOADING_ZONE_WIDTH);
+ ctx.lineTo(FIELD_LENGTH, DS_INSIDE_Y - LOADING_ZONE_WIDTH);
+ ctx.stroke();
+
+ ctx.strokeStyle = OTHER_COLOR;
+ ctx.beginPath();
+ ctx.moveTo(0, -DS_INSIDE_Y);
+ ctx.lineTo(TARGET_ZONE_TIP_X, -(DS_INSIDE_Y - 0.5 * LOADING_ZONE_WIDTH));
+ ctx.lineTo(0, -(DS_INSIDE_Y - LOADING_ZONE_WIDTH));
+
+ ctx.moveTo(FIELD_LENGTH, -DS_INSIDE_Y);
+ ctx.lineTo(
+ FIELD_LENGTH - TARGET_ZONE_TIP_X,
+ -(DS_INSIDE_Y - 0.5 * TARGET_ZONE_WIDTH));
+ ctx.lineTo(FIELD_LENGTH, -(DS_INSIDE_Y - TARGET_ZONE_WIDTH));
+ ctx.stroke();
+ }
+
+ reset(): void {
+ const ctx = this.canvas.getContext('2d');
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
+ const size = window.innerHeight * 0.9;
+ ctx.canvas.height = size;
+ ctx.canvas.width = size / 2 + 10;
+ ctx.clearRect(0, 0, size, size / 2 + 10);
+
+ // Translate to center of bottom of display.
+ ctx.translate(size / 4, size);
+ // Coordinate system is:
+ // x -> forward.
+ // y -> to the left.
+ ctx.rotate(-Math.PI / 2);
+ ctx.scale(1, -1);
+ ctx.translate(5, 0);
+
+ const M_TO_PX = (size - 10) / FIELD_LENGTH;
+ ctx.scale(M_TO_PX, M_TO_PX);
+ ctx.lineWidth = 1 / M_TO_PX;
+ }
+}
diff --git a/y2020/www/field_main.ts b/y2020/www/field_main.ts
new file mode 100644
index 0000000..adcaa27
--- /dev/null
+++ b/y2020/www/field_main.ts
@@ -0,0 +1,13 @@
+import {Connection} from 'aos/network/www/proxy';
+
+import {FieldHandler} from './field_handler';
+
+const conn = new Connection();
+
+conn.connect();
+
+const fieldHandler = new FieldHandler();
+
+fieldHandler.reset();
+fieldHandler.drawField();
+
diff --git a/y2020/www/main.ts b/y2020/www/main.ts
index d414eac..e4c0f10 100644
--- a/y2020/www/main.ts
+++ b/y2020/www/main.ts
@@ -1,6 +1,7 @@
import {Connection} from 'aos/network/www/proxy';
import {ImageHandler} from './image_handler';
+import {FieldHandler} from './field_handler';
const conn = new Connection();