diff --git a/proto/protofiles_sources/server_client/mode_change.proto b/proto/protofiles_sources/server_client/mode_change.proto index 67ea3036c7e..6851284c06f 100644 --- a/proto/protofiles_sources/server_client/mode_change.proto +++ b/proto/protofiles_sources/server_client/mode_change.proto @@ -2,9 +2,10 @@ syntax = "proto3"; message ModeChange { enum Mode { - ManualControl = 0; + Idle = 0; PerimeterBuilding = 1; PerimeterDebug = 2; + ManualControl = 3; } Mode newMode = 1; diff --git a/ui/index.html b/ui/index.html index 5a07830ba6f..596e2a93139 100644 --- a/ui/index.html +++ b/ui/index.html @@ -2,7 +2,7 @@ - Hello world + CarKot @@ -25,29 +25,43 @@
-
+
+ +
HEY
+
-
+
- - - - - + + + - - +
-
+
+
+ +
+ +
+ +
+ +
+ + + + +
+ + +
+ diff --git a/ui/scripts/index.js b/ui/scripts/index.js index f0e83a49ae7..c75f7537ff4 100644 --- a/ui/scripts/index.js +++ b/ui/scripts/index.js @@ -18,7 +18,14 @@ var ProtoBuf = dcodeIO.ProtoBuf, // serverAddress = "http://localhost:8000"; serverAddress = "http://localhost:7926", - remoteController = null; + remoteController = null, + + // drawing-related objects + canvas = $( "#pathCanvas" )[0], + ctx = canvas.getContext('2d'), + tooltip = $( "#coords-tooltip"); + +var currentActiveButton = null; var Commands = { UP: 0, @@ -118,28 +125,68 @@ $(document).keyup(function(event) { return handleControlKeyup(event) }); -function changeMode(modeId) { +$(document).ready(init) + +function init() { + $("#perimeter-mode-tab").hide() + $("#perimeter-debug-tab").hide() + $("#manual-mode-tab").hide() + $("#exit-btn").hide() + + canvas.addEventListener('mousemove', function(evt) { + var mousePos = getMousePos(evt); + var message = "(" + mousePos.x + "," + mousePos.y + ")"; + tooltip[0].textContent = message; + tooltip.offset( {top: (evt.clientY + 20), left: (evt.clientX + 20) } ); + }, + false +); + +} + +function hideTabs() { + $("#perimeter-mode-tab").fadeOut() + $("#perimeter-debug-tab").fadeOut() + $("#manual-mode-tab").fadeOut() + $("#exit-btn").fadeOut() +} + + +function changeMode(modeId, button, associatedTab) { console.log("Changing mode to mode #" + modeId) + + // check for pressing wrong buttons + if (($(button).hasClass("disabled"))) { + alert("Exit current mode first!"); + return; + } + + if ($(button) == currentActiveButton) { + alert("Already in this mode!"); + } + + // if exit pressed + if (modeId == 0) { + currentActiveButton.siblings().removeClass("disabled") + currentActiveButton = null + hideTabs(); + } + else { // entering mode + $(button).siblings().addClass("disabled"); + currentActiveButton = $(button); + $("#exit-btn").fadeIn(); + $("#" + associatedTab).fadeIn(); + } + + console.log("Sending request to change mode to" + modeId.toString()); var msg = new ModeChange(modeId); - console.log("Sending request to change algorithm"); sendProtobuf(msg, serverAddress + "/change-mode", function(response) { var response = GenericResponse.decode64(response); - if (response.result.errorCode != 0) { + if (response.result.error != 0) { alert("Something went wrong!"); return; } console.log("Got OK for changing request") - // switch(modeId) { - // case 0: - // enterManualMode(); - // break; - // case 1: - // buildPerimeter( debug = false); - // break; - // case 2: - // buildPerimeter(/* debug = */ true); - // break; - // } }); } diff --git a/ui/scripts/proto/client_debug.proto b/ui/scripts/proto/client_debug.proto index 01d1f79bac6..60da09b2b52 100644 --- a/ui/scripts/proto/client_debug.proto +++ b/ui/scripts/proto/client_debug.proto @@ -1,7 +1,6 @@ syntax = "proto3"; message DebugResponse { - repeated int32 begin_x = 1 [packed = true]; repeated int32 begin_y = 2 [packed = true]; repeated int32 end_x = 3 [packed = true]; @@ -14,5 +13,4 @@ message DebugResponse { repeated int32 x = 8 [packed = true]; repeated int32 y = 9 [packed = true]; -} - +} \ No newline at end of file diff --git a/ui/scripts/proto/generic_response.proto b/ui/scripts/proto/generic_response.proto index eda42fd8b9f..803b82d619c 100644 --- a/ui/scripts/proto/generic_response.proto +++ b/ui/scripts/proto/generic_response.proto @@ -1,7 +1,7 @@ syntax = "proto3"; message Result { - int32 errorCode = 1; + int32 error = 1; } message GenericResponse { diff --git a/ui/scripts/proto/mode_change.proto b/ui/scripts/proto/mode_change.proto index 138b30b619d..6851284c06f 100644 --- a/ui/scripts/proto/mode_change.proto +++ b/ui/scripts/proto/mode_change.proto @@ -2,8 +2,10 @@ syntax = "proto3"; message ModeChange { enum Mode { - ManualControl = 0; + Idle = 0; PerimeterBuilding = 1; + PerimeterDebug = 2; + ManualControl = 3; } Mode newMode = 1; diff --git a/ui/scripts/util/drawing.js b/ui/scripts/util/drawing.js index 55868b47401..8cb1eb42ce1 100644 --- a/ui/scripts/util/drawing.js +++ b/ui/scripts/util/drawing.js @@ -1,8 +1,12 @@ "use strict"; -var canvas = $( "#pathCanvas" )[0], - ctx = canvas.getContext('2d'), - eps = 1e-5, +var aspectRatio = 4.0/3.0; + +var leftmostPoint = createPoint(0, 0); +var rightmostPoint = createPoint(0, 0); +var topPoint = createPoint(0, 0); +var bottomPoint = createPoint(0, 0); +var eps = 1e-5, zero = { x: canvas.width / 2, y: canvas.height / 2 @@ -14,6 +18,9 @@ var canvas = $( "#pathCanvas" )[0], canvas.style = "border:5px solid #000000;"; +var stepX = canvas.width / 20 +var stepY = canvas.height / 20 + function drawPath(waypoints) { ctx.beginPath(); ctx.moveTo(canvas.width / 2, canvas.height / 2); @@ -30,19 +37,19 @@ function drawCar(carPosition) { drawPoint(carPosition, carColour, 10); } -function drawLine(line) { +function drawLine(line, colour, lineWidth) { var begin_x = 0; - var begin_y = (line.A * (0 - zero.x) + line.C) / line.B + zero.y; + var begin_y = - (line.A * (0 - zero.x) + line.C) / line.B + zero.y; var end_x = canvas.width; - var end_y = (line.A * (canvas.width - zero.x) + line.C) / line.B + zero.y; + var end_y = - (line.A * (canvas.width - zero.x) + line.C) / line.B + zero.y; // check if evaluated y-coordinates are in the canvas. If not, re-evaluate x-coordinates from y, to prevent issues with lines that are close to vertical if (gt(begin_y, canvas.height) || gt(end_y, canvas.height)) { - begin_x = (line.B * (0 - zero.y) + line.C) / line.A + zero.x; + begin_x = - (line.B * (0 - zero.y) + line.C) / line.A + zero.x; begin_y = 0; - end_x = (line.B * (canvas.height - zero.y) + line.C) / line.A + zero.x; + end_x = - (line.B * (canvas.height - zero.y) + line.C) / line.A + zero.x; end_y = canvas.height; } @@ -50,12 +57,17 @@ function drawLine(line) { ctx.beginPath(); ctx.moveTo(begin_x, begin_y); ctx.lineTo(end_x, end_y); - ctx.strokeStyle = foundColour; + if (lineWidth != null) { + ctx.lineWidth = lineWidth + } + ctx.strokeStyle = colour; ctx.closePath(); ctx.stroke(); } function drawSegment(segment, colour) { + updateCorners(segment.begin); + updateCorners(segment.end); console.log("Drawing segment from (" + segment.begin.x + ", " + segment.begin.y + ") to (" + segment.end.x + ", " + segment.end.y + ")") ctx.beginPath(); ctx.moveTo(segment.begin.x + zero.x, segment.begin.y + zero.y); @@ -123,7 +135,24 @@ function createPoint(x_, y_) { return point; } +function updateCorners(point) { + if (point.x < leftmostPoint.x) { + leftmostPoint = point; + } + if (point.x > rightmostPoint.x) { + rightmostPoint = point; + } + if (point.y < bottomPoint.y) { + bottomPoint = point; + } + if (point.y > topPoint.y) { + topPoint = point; + } + resizeCanvas(); +} + function drawPoint(point, colour, radius) { + updateCorners(point); ctx.beginPath(); ctx.arc(point.x + zero.x, point.y + zero.y, radius, 0, 2 * Math.PI, false); ctx.fillStyle = colour; @@ -131,6 +160,59 @@ function drawPoint(point, colour, radius) { ctx.fill(); } +function resizeCanvas() { + while (canvas.width < rightmostPoint.x + zero.x || 0 > leftmostPoint + zero.x) { + canvas.width *= 2.0; + canvas.height = canvas.width / 4.0 * 3.0; + } + + while (canvas.height < topPoint.y + zero.y || 0 > bottomPoint + zero.y) { + canvas.height *= 2.0; + canvas.width = canvas.height / 3.0 * 4.0 + } + + var contentMid = createPoint( (rightmostPoint.x + leftmostPoint.x) / 2, (topPoint.y + bottomPoint.y) / 2); + var canvasMid = createPoint(canvas.width / 2, canvas.height / 2); + + zero.x = canvasMid.x - contentMid.x + zero.y = canvasMid.y - contentMid.y + + stepX = canvas.width / 20; + stepY = canvas.height / 20; +} + +function getMousePos(evt) { + var rect = canvas.getBoundingClientRect(); + var pt = { + x: Math.floor((evt.clientX-rect.left) / (rect.right-rect.left) * canvas.width) - zero.x, + y: Math.floor((evt.clientY-rect.top) / (rect.bottom-rect.top) * canvas.height - zero.y) + }; + return pt; +} + + +function drawAxis() { + for (var i = zero.x + stepX; i < canvas.width; i += stepX) { + drawLine(createLine(1, 0, -(i - zero.x)), "black", 0.1); + } + + for (var i = zero.x - stepX; i > 0; i -= stepX) { + drawLine(createLine(1, 0, -(i - zero.x)), "black", 0.1); + } + + drawLine(createLine(1, 0, 0), "black", 2); + + for (var i = zero.y + stepY; i < canvas.height; i += stepY) { + drawLine(createLine(0, 1, -(i - zero.y)), "black", 0.1); + } + + for (var i = zero.y - stepY; i > 0; i -= stepY) { + drawLine(createLine(0, 1, -(i - zero.y)), "black", 0.1); + } + + drawLine(createLine(0, 1, 0), "black", 2) +} + function drawDebug(data) { ctx.clearRect(0, 0, canvas.width, canvas.height); @@ -147,7 +229,7 @@ function drawDebug(data) { var pt = createPoint(data.x[i], data.y[i]) points.push(pt); } - + var carPosition = createPoint(data.carX, data.carY); // draw everything @@ -163,4 +245,6 @@ function drawDebug(data) { for (var i = 0; i < points.length; i++) { drawPoint(points[i], "green", 2); } + + drawAxis() } diff --git a/ui/styles/style.css b/ui/styles/style.css index 1b345c7d239..dc1cf703d4b 100644 --- a/ui/styles/style.css +++ b/ui/styles/style.css @@ -3,6 +3,23 @@ height: 36em; } +#control-tabs { + display: block; +} + +.btn { + white-space: normal; +} + +#coords-tooltip { + display: none; +} + +#pathCanvas:hover + #coords-tooltip { + display: block; + position: fixed; + overflow: hidden; +} /*#algos { padding: 1em;