mirror of
https://github.com/supleed2/ELEC50003-P1-CW.git
synced 2024-12-23 05:55:50 +00:00
46519cfe19
Console Changes: changed the name of the tokens so that more helpful error messages. Added help text. Moved command.jison to src. Other Changes: Added more telemetry data about battery and rover status. Finished gui commands, replaced to sliders from buttons and linked them to command console.
441 lines
16 KiB
HTML
441 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<html lang='en'>
|
|
|
|
<head>
|
|
<title>Rover Control Panel</title>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
|
|
<link rel="icon" href="/favicon.ico" type="image/x-icon">
|
|
<style>
|
|
* {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.flex-container {
|
|
display: flex;
|
|
flex-wrap: nowrap;
|
|
}
|
|
|
|
:is(h1, h2, h3, h4, h5, h6, label, strong, meter) {
|
|
font-family: Arial, Helvetica, sans-serif;
|
|
}
|
|
|
|
h2{
|
|
margin: 0px;
|
|
}
|
|
|
|
.slider {
|
|
-webkit-appearance: none;
|
|
width: 100%;
|
|
height: 25px;
|
|
background: #d3d3d3;
|
|
outline: none;
|
|
opacity: 0.7;
|
|
-webkit-transition: .2s;
|
|
transition: opacity .2s;
|
|
}
|
|
|
|
.slider:hover {
|
|
opacity: 1;
|
|
}
|
|
|
|
.slider::-webkit-slider-thumb {
|
|
-webkit-appearance: none;
|
|
appearance: none;
|
|
width: 25px;
|
|
height: 25px;
|
|
background: #000000;
|
|
cursor: pointer;
|
|
}
|
|
|
|
#command_space {
|
|
width:100%;
|
|
height: 200px;
|
|
line-height: normal;
|
|
overflow: auto;
|
|
background-color: rgb(248, 248, 248);
|
|
color: black;
|
|
border: 1px solid black;
|
|
}
|
|
|
|
meter {
|
|
width: 100%;
|
|
height: 40px;
|
|
transform: translateY(8px);
|
|
}
|
|
|
|
meter::after {
|
|
content: attr(value) attr(title);
|
|
top: -28px;
|
|
left: 45%;
|
|
position: relative;
|
|
}
|
|
|
|
button {
|
|
width: 100%;
|
|
display: inline-block;
|
|
padding: 7px 7px;
|
|
font-size: 12px;
|
|
cursor: pointer;
|
|
text-align: center;
|
|
text-decoration: none;
|
|
outline: none;
|
|
color: rgb(255, 255, 255);
|
|
background-color: #222222;
|
|
border: none;
|
|
border-radius: 5px;
|
|
box-shadow: 0 3px rgb(161, 161, 161);
|
|
-webkit-transition: .2s;
|
|
transition: background-color .2s;
|
|
}
|
|
|
|
button:hover {
|
|
background-color: #585858
|
|
}
|
|
|
|
button:active {
|
|
box-shadow: 0 3px rgb(161, 161, 161);
|
|
transform: translateY(1px);
|
|
}
|
|
|
|
.clearfix::after {
|
|
content: "";
|
|
clear: both;
|
|
display: table;
|
|
}
|
|
</style>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
<h1 style="text-align:center;">ROVER COMMAND CENTER</h1>
|
|
|
|
<div class="clearfix">
|
|
<table style="width:1100px; border-spacing: 10px; margin-left: auto; margin-right: auto;">
|
|
<tr>
|
|
<th style="width: 33%;"><h2>Control Panel</h2></th>
|
|
<th style="width: 33%;"><h2>Telemetry</h2></th>
|
|
<th style="width: 33%;"><h2>Command Console</h2></th>
|
|
</tr>
|
|
<tr><hr></tr>
|
|
|
|
<!-- Control Panel Section -->
|
|
<tr>
|
|
<td style="vertical-align: top;">
|
|
<table style="width:100%; border-spacing: 5px;">
|
|
<tr><td colspan="6"><hr></td></tr>
|
|
<tr>
|
|
<td style="text-align: center;" colspan="6"><strong>Main</strong></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td style="text-align: center;" colspan="2"><button style="color: red;">Emergency <br> Stop</button></td>
|
|
<td style="text-align: center;" colspan="2"><button>Telemetry Reset</button></td>
|
|
<td style="text-align: center;" colspan="2"><button>Full <br> Charge</button></td>
|
|
</tr>
|
|
<tr><td colspan="6"><hr></td></tr>
|
|
<tr>
|
|
<td style="text-align: center;" colspan="6"><strong> Set Heading to: </strong><strong id="SetHeading" style="font-size: 18px;">270</strong><strong>°</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="6"><input type ="range" min="0" max="359" value="270" class="slider" id="HdgSlider"></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="text-align: center;" colspan="6"><strong>Set Translation to: </strong><strong id="SetTrans" style="font-size: 18px;">180</strong><strong>mm</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="6"><input type ="range" min="0" max="1000" value="100" class="slider" id="TranSlider"></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="text-align: center;" colspan="6"><strong>Set Speed to: </strong><strong id="SetSpd" style="font-size: 18px;">50</strong><strong>%</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="6"><input type ="range" min="0" max="100" value="50" class="slider" id="SpdSlider"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="6"><button onclick="setCmdMode(1); moveCmd(setTransto, setHdgto, setSpdto);">Send<br>Command</button></td>
|
|
</tr>
|
|
<tr><td colspan="6"><hr></td></tr>
|
|
</table>
|
|
</td>
|
|
|
|
<!-- Telemetry Section -->
|
|
|
|
<td style="vertical-align: top;">
|
|
<table style="width:100%; border-spacing: 5px; ">
|
|
<tr><td colspan="2"><hr></td></tr>
|
|
<tr>
|
|
<td style="width:50%;"><label>Rover Status</label></td>
|
|
<td style="width:50%;"><strong id="Rov_status">X</strong>
|
|
</tr>
|
|
<tr><td colspan="2"><hr></td></tr>
|
|
<tr>
|
|
<td style="width:50%;"><label>Signal Strength</label></td>
|
|
<td style="width:50%;"><meter id="SigStr" min="-80" max="-30" low="-70" high="-50" optimum="-40" value="-XX"
|
|
title="dB"></meter></td>
|
|
</tr>
|
|
<tr><td colspan="2"><hr></td></tr>
|
|
<tr>
|
|
<td style="width:50%;"><label>Position</label></td>
|
|
<td style="width:50%;"><strong id="PosX">X</strong><strong>,</strong><strong id="PosY">Y</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:50%;"><label>Heading</label></td>
|
|
<td style="width:50%;"><strong id="Hdg">H</strong><strong>°</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:50%;"><label>Trip Distance</label></td>
|
|
<td style="width:50%;"><strong id="TrpDist">X</strong><strong> mm</strong></td>
|
|
</tr>
|
|
<tr><td colspan="2"><hr></td></tr>
|
|
<tr>
|
|
<td style="width:50%;"><label>Battery Voltage</label></td>
|
|
<td style="width:50%;"><strong id="btry_volt">X</strong><strong>V</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:50%;"><label>Battery Level</label></td>
|
|
<td style="width:50%;"><strong id="btry_lvl">X</strong><strong>%</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:50%;"><label>Battery Cycles</label></td>
|
|
<td style="width:50%;"><strong id="btry_cycls">X</strong></td>
|
|
</tr>
|
|
<tr><td colspan="2"><hr></td></tr>
|
|
|
|
</table>
|
|
</td>
|
|
|
|
<!-- Command Buffer Section -->
|
|
<td style="vertical-align: top;">
|
|
<table style="width:100%; border-spacing: 5px; ">
|
|
<tr><td colspan="2"><hr></td></tr>
|
|
<tr><td colspan="2"><div id="command_space"><p id="command_buffer" style="padding-left: 5px; font-size: 12px; font-family: 'Courier New', Courier, monospace;"></p></div></td></tr>
|
|
<tr>
|
|
<td><input type="text" placeholder="Type a command or 'help'." id="commandInput" value="" onkeyup="if(event.keyCode == 13){document.getElementById('commandEnter').click();}" style="width: 100%; font-size: 14px; font-family: 'Courier New', Courier, monospace;"></td>
|
|
<td style="width: 7%; "><button onclick="setCmdMode(0); RunParser();" id="commandEnter" style="height: 20px; width: 20px; padding: 3px 2px;">↵</button></td>
|
|
</tr>
|
|
</table>
|
|
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</body>
|
|
<script src="command.js"></script>
|
|
<script>
|
|
var connection = new WebSocket('ws://' + location.hostname + ':81/');
|
|
|
|
var command_id = 1;
|
|
var mode = 0;
|
|
var reqHeading = 0;
|
|
var reqDistance = 0;
|
|
var reqSpeed = 0;
|
|
var reqCharge = 0;
|
|
var pstop_time = 0;
|
|
|
|
var state = 0;
|
|
var batteryVoltage = 0;
|
|
var batteryLevel = 0;
|
|
var totalTripDistance = 0;
|
|
var currentHeading = 0;
|
|
var current_pos = [,];
|
|
var current_x = 0;
|
|
var current_y = 0;
|
|
var signal_strength = 0;
|
|
var lastCompletedCommand_id = 0;
|
|
var batteryCycles = 0;
|
|
|
|
|
|
connection.onmessage = function (event) {
|
|
var raw_data = event.data;
|
|
console.log(raw_data);
|
|
var data = JSON.parse(raw_data);
|
|
|
|
state = data.st;
|
|
batteryLevel = data.bV;
|
|
batteryVoltage = data.bV;
|
|
batteryCycles = data.bC;
|
|
totalTripDistance = data.tD;
|
|
currentHeading = data.cH;
|
|
current_pos = data.pos;
|
|
current_x = current_pos[0];
|
|
current_y = current_pos[1];
|
|
signal_strength = data.rssi;
|
|
lastCompletedCommand_id = data.LCCid;
|
|
|
|
var rStatus = ""
|
|
if(state == -1){
|
|
rStatus = "Error";
|
|
}else if(state == 0){
|
|
rStatus = "Idle";
|
|
}else if(state == 1){
|
|
rStatus = "Moving";
|
|
}else if(state == 2){
|
|
rStatus = "Charging";
|
|
}else{
|
|
rStatus = "Undefined";
|
|
}
|
|
|
|
document.getElementById("Rov_status").innerHTML = rStatus;
|
|
document.getElementById("SigStr").value = signal_strength;
|
|
document.getElementById("PosX").innerHTML = current_x;
|
|
document.getElementById("PosY").innerHTML = current_y;
|
|
document.getElementById("Hdg").innerHTML = currentHeading;
|
|
document.getElementById("TrpDist").innerHTML = totalTripDistance;
|
|
document.getElementById("btry_volt").innerHTML = batteryVoltage;
|
|
document.getElementById("btry_lvl").innerHTML = batteryLevel;
|
|
document.getElementById("btry_cycls").innerHTML = batteryCycles;
|
|
}
|
|
|
|
function send_data() {
|
|
var raw_data = '{"Cid":' + command_id + ',"mode":' + mode + ',"rH":' + reqHeading + ',"rD":' + reqDistance + ',"rS":' + reqSpeed + ',"rC":' + reqCharge + ',"pSt":' + pstop_time + '}';
|
|
connection.send(raw_data);
|
|
console.log(raw_data);
|
|
}
|
|
|
|
function setCmdMode(mode){
|
|
cmdMode = mode;
|
|
}
|
|
|
|
function updateCommandBuffer(){
|
|
var bufferOutput = "";
|
|
if(cmdMode == 0){
|
|
bufferOutput = document.getElementById("commandInput").value;
|
|
}else if(cmdMode == 1){
|
|
bufferOutput = "move " + reqDistance + "mm " + reqHeading + "deg " + reqSpeed + "%";
|
|
}
|
|
if((mode == 1) || (mode == -1) || (mode == 2) || (mode == 3)){
|
|
document.getElementById("command_buffer").innerHTML += '[' + command_id + '] ' + bufferOutput + "<br>";
|
|
document.getElementById("commandInput").value = ""
|
|
}else if(mode == 0){
|
|
document.getElementById("command_buffer").innerHTML = "Rover Emergency Stop." + "<br>" +"Command buffer cleared." + "<br>";
|
|
document.getElementById("commandInput").value = "";
|
|
}
|
|
}
|
|
|
|
function printHelpDetails(){
|
|
document.getElementById("command_buffer").innerHTML =
|
|
("------------------------------------------" + "<br>" + "<br>" +
|
|
"Types of commands available:" + "<br>" + "<br>" +
|
|
"'move' moves rover along a given vector" + "<br>" +
|
|
"> move [distance]mm [heading]deg [speed]%" + "<br>" + "<br>" +
|
|
"'pstop' short for planned stop it stops the rover without reseting the command buffer" + "<br>" +
|
|
"> pstop" + "<br>" + "<br>" +
|
|
"'charge' stops the rover and recharges to a set battery level" + "<br>" +
|
|
"> charge to [percentage]%" + "<br>" + "<br>" +
|
|
"'telemetry reset' resets X,Y coordinates and Trip Distance" + "<br>" +
|
|
"> telemetry reset" + "<br>" + "<br>" +
|
|
"'stop' and emergency stop that stops the rover and resets the command buffer" + "<br>" +
|
|
"> stop" + "<br>" + "<br>" +
|
|
"------------------------------------------"
|
|
)
|
|
document.getElementById("commandInput").value = "";
|
|
}
|
|
|
|
function moveCmd(dist,hdg,spd){
|
|
mode = 1;
|
|
reqDistance = dist;
|
|
reqHeading = hdg;
|
|
reqSpeed = spd;
|
|
reqCharge = 0;
|
|
pstop_time = 0;
|
|
tel_rst = 0;
|
|
send_data();
|
|
updateCommandBuffer();
|
|
command_id++;
|
|
}
|
|
|
|
function stpCmd(){
|
|
mode = 0;
|
|
reqDistance = 0;
|
|
reqHeading = 0;
|
|
reqSpeed = 0;
|
|
reqCharge = 0;
|
|
pstop_time = 0;
|
|
tel_rst = 0;
|
|
send_data();
|
|
command_id = 1;
|
|
updateCommandBuffer();
|
|
}
|
|
|
|
function pstpCmd(pstp_tme){
|
|
mode = 3;
|
|
reqDistance = 0;
|
|
reqHeading = 0;
|
|
reqSpeed = 0;
|
|
reqCharge = 0;
|
|
pstop_time = pstp_tme;
|
|
tel_rst = 0;
|
|
send_data();
|
|
updateCommandBuffer();
|
|
command_id++;
|
|
}
|
|
|
|
function chrgCmd(chrglvl){
|
|
mode = 2;
|
|
reqDistance = 0;
|
|
reqHeading = 0;
|
|
reqSpeed = 0;
|
|
reqCharge = chrglvl;
|
|
pstop_time = 0;
|
|
tel_rst = 0;
|
|
send_data();
|
|
updateCommandBuffer();
|
|
command_id++;
|
|
}
|
|
|
|
function telRst(){
|
|
mode = -1;
|
|
reqDistance = 0;
|
|
reqHeading = 0;
|
|
reqSpeed = 0;
|
|
reqCharge = 0;
|
|
pstop_time = 0;
|
|
send_data();
|
|
updateCommandBuffer();
|
|
command_id++;
|
|
}
|
|
|
|
|
|
function RunParser(){
|
|
var commandstring = document.getElementById("commandInput").value;
|
|
try{
|
|
command.parse(commandstring);
|
|
} catch(err){
|
|
alert(err);
|
|
}
|
|
}
|
|
|
|
var setHdgto = 270;
|
|
var hdg_slider = document.getElementById("HdgSlider");
|
|
var hdg_output = document.getElementById("SetHeading");
|
|
hdg_output.innerHTML = hdg_slider.value;
|
|
hdg_slider.oninput = function() {
|
|
hdg_output.innerHTML = this.value;
|
|
setHdgto = this.value;
|
|
}
|
|
|
|
var setTransto = 100;
|
|
var tran_slider = document.getElementById("TranSlider");
|
|
var tran_output = document.getElementById("SetTrans");
|
|
tran_output.innerHTML = tran_slider.value;
|
|
tran_slider.oninput = function() {
|
|
tran_output.innerHTML = this.value;
|
|
setTransto = this.value;
|
|
}
|
|
|
|
var setSpdto = 50;
|
|
var spd_slider = document.getElementById("SpdSlider");
|
|
var spd_output = document.getElementById("SetSpd");
|
|
spd_output.innerHTML = spd_slider.value;
|
|
spd_slider.oninput = function() {
|
|
spd_output.innerHTML = this.value;
|
|
setSpdto = this.value;
|
|
}
|
|
|
|
</script>
|
|
|
|
</html> |