Add time-since-last-target to server
And draw little cameras on the robot that turn green when we got a
target from that camera in the last 0.25sec.
Change-Id: Icd6107163fd3f5145fcba69ac6ebb2700f602f8d
diff --git a/y2019/vision/server/www/BUILD b/y2019/vision/server/www/BUILD
index 937b495..428dd41 100644
--- a/y2019/vision/server/www/BUILD
+++ b/y2019/vision/server/www/BUILD
@@ -6,7 +6,7 @@
filegroup(
name = "files",
srcs = glob([
- "**/*",
+ "**/*.html",
]),
)
@@ -14,7 +14,20 @@
name = "visualizer",
srcs = glob([
"*.ts",
- ]),
+ ]) + ["camera_constants.ts"],
+)
+
+cc_binary(
+ name = "generate_camera",
+ srcs = ["generate_camera.cc"],
+ deps = ["//y2019:constants"],
+)
+
+genrule(
+ name = "gen_cam_ts",
+ outs = ["camera_constants.ts"],
+ cmd = "$(location :generate_camera) $@",
+ tools = [":generate_camera"],
)
rollup_bundle(
diff --git a/y2019/vision/server/www/generate_camera.cc b/y2019/vision/server/www/generate_camera.cc
new file mode 100644
index 0000000..8e516c3
--- /dev/null
+++ b/y2019/vision/server/www/generate_camera.cc
@@ -0,0 +1,33 @@
+#include "y2019/constants.h"
+#include "y2019/vision/constants.h"
+
+#include <fstream>
+#include <iostream>
+
+namespace y2019 {
+namespace vision {
+void DumpPose(std::basic_ostream<char> *o, const vision::CameraGeometry &pose) {
+ *o << "{x: " << pose.location[0] << ", y: " << pose.location[1]
+ << ", theta: " << pose.heading << "}";
+}
+void DumpTypescriptConstants(const char *fname) {
+ ::std::ofstream out_file(fname);
+ out_file << "export const CAMERA_POSES = [\n";
+ for (size_t ii = 0; ii < constants::Values::kNumCameras; ++ii) {
+ out_file << " ";
+ DumpPose(&out_file,
+ GetCamera(CameraSerialNumbers(CompBotTeensyId())[ii])->geometry);
+ out_file << ",\n";
+ }
+ out_file << "];\n";
+}
+} // namespace constants
+} // namespace y2019
+
+int main(int argc, char *argv[]) {
+ if (argc != 2) {
+ ::std::cout << "Must provide a filename for output as an argument\n";
+ return 1;
+ }
+ ::y2019::vision::DumpTypescriptConstants(argv[1]);
+}
diff --git a/y2019/vision/server/www/main.ts b/y2019/vision/server/www/main.ts
index 17b7139..a9a57bd 100644
--- a/y2019/vision/server/www/main.ts
+++ b/y2019/vision/server/www/main.ts
@@ -16,6 +16,7 @@
private targetX = 0;
private targetY = 0;
private targetTheta = 0;
+ private cameraColors = ['red', 'red', 'red', 'red', 'red'];
constructor() {
const canvas = <HTMLCanvasElement>document.getElementById('field');
@@ -37,6 +38,13 @@
this.targetY = j.target.y;
this.targetTheta = j.target.theta;
}
+ for (let ii of [0, 1, 2, 3, 4]) {
+ if (j.last_target_age[ii] > 0.25) {
+ this.cameraColors[ii] = 'red';
+ } else {
+ this.cameraColors[ii] = 'green';
+ }
+ }
});
socket.addEventListener('message', (event) => {
reader.readAsText(event.data);
@@ -63,7 +71,7 @@
this.reset(ctx);
drawField(ctx);
- drawRobot(ctx, this.x, this.y, this.theta);
+ drawRobot(ctx, this.x, this.y, this.theta, this.cameraColors);
ctx.save();
ctx.lineWidth = 2.0 * ctx.lineWidth;
if (this.targetLocked) {
diff --git a/y2019/vision/server/www/robot.ts b/y2019/vision/server/www/robot.ts
index bc1f47f..489112c 100644
--- a/y2019/vision/server/www/robot.ts
+++ b/y2019/vision/server/www/robot.ts
@@ -1,9 +1,22 @@
import {IN_TO_M, FT_TO_M} from './constants';
+import {CAMERA_POSES} from './camera_constants';
const ROBOT_WIDTH = 25 * IN_TO_M;
const ROBOT_LENGTH = 31 * IN_TO_M;
+const CAMERA_SCALE = 0.3;
-export function drawRobot(ctx : CanvasRenderingContext2D, x : number, y : number, theta : number) : void {
+function drawCamera(ctx : canvasRenderingContext2d, pose : {x : number, y : number, theta : number}) : void {
+ ctx.beginPath();
+ ctx.moveTo(pose.x, pose.y);
+ ctx.lineTo(pose.x + CAMERA_SCALE * Math.cos(pose.theta + Math.PI / 4.0),
+ pose.y + CAMERA_SCALE * Math.sin(pose.theta + Math.PI / 4.0));
+ ctx.lineTo(pose.x + CAMERA_SCALE * Math.cos(pose.theta - Math.PI / 4.0),
+ pose.y + CAMERA_SCALE * Math.sin(pose.theta - Math.PI / 4.0));
+ ctx.closePath();
+ ctx.stroke();
+}
+
+export function drawRobot(ctx : CanvasRenderingContext2D, x : number, y : number, theta : number, camera_colors : string[]) : void {
ctx.save();
ctx.translate(x, y);
ctx.rotate(theta);
@@ -11,11 +24,18 @@
ctx.fillStyle = 'blue';
ctx.fillRect(-ROBOT_LENGTH / 2, -ROBOT_WIDTH / 2, ROBOT_LENGTH, ROBOT_WIDTH);
+ ctx.beginPath();
+ ctx.strokeStyle = 'black';
ctx.moveTo(ROBOT_LENGTH / 2, -ROBOT_WIDTH/2);
ctx.lineTo(ROBOT_LENGTH / 2 + 0.1, 0);
ctx.lineTo(ROBOT_LENGTH / 2, ROBOT_WIDTH/2);
ctx.closePath();
ctx.stroke();
+ ctx.lineWidth = 3.0 * ctx.lineWidth;
+ for (let ii of [0, 1, 2, 3, 4]) {
+ ctx.strokeStyle = camera_colors[ii];
+ drawCamera(ctx, CAMERA_POSES[ii]);
+ }
ctx.restore();
}