|
|
@ -15,6 +15,12 @@ let display_class_topic;
|
|
|
|
/** @type {string} */
|
|
|
|
/** @type {string} */
|
|
|
|
let display_name_topic;
|
|
|
|
let display_name_topic;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @type {string} */
|
|
|
|
|
|
|
|
let alliance_selecting = "";
|
|
|
|
|
|
|
|
/** @type {string} */
|
|
|
|
|
|
|
|
let alliance_selected = "";
|
|
|
|
|
|
|
|
let selection_state = "";
|
|
|
|
|
|
|
|
|
|
|
|
/** @type {string} */
|
|
|
|
/** @type {string} */
|
|
|
|
let display_sponsor_topic;
|
|
|
|
let display_sponsor_topic;
|
|
|
|
|
|
|
|
|
|
|
@ -47,9 +53,9 @@ let animation_timer_interval = setInterval(animation_timer, 10);
|
|
|
|
|
|
|
|
|
|
|
|
let event_name = "Mecha Mayhem 2024";
|
|
|
|
let event_name = "Mecha Mayhem 2024";
|
|
|
|
let match_name = "No Match";
|
|
|
|
let match_name = "No Match";
|
|
|
|
let match_name_show = "No Match";
|
|
|
|
|
|
|
|
let round = "";
|
|
|
|
let round = "";
|
|
|
|
let number = "";
|
|
|
|
let number = "";
|
|
|
|
|
|
|
|
let instance = "";
|
|
|
|
let score_red = 0;
|
|
|
|
let score_red = 0;
|
|
|
|
let score_red_str = "";
|
|
|
|
let score_red_str = "";
|
|
|
|
let score_blue = 0;
|
|
|
|
let score_blue = 0;
|
|
|
@ -79,6 +85,31 @@ const client = mqtt.connect("ws://10.42.0.36:8883");
|
|
|
|
|
|
|
|
|
|
|
|
client.on("connect", () => {
|
|
|
|
client.on("connect", () => {
|
|
|
|
console.log("connected to mqtt");
|
|
|
|
console.log("connected to mqtt");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client.subscribe("alliance/selecting", (err) => {
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
|
|
|
|
console.log(err);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
console.log(`subscribed to alliance/selecting`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client.subscribe("alliance/selected", (err) => {
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
|
|
|
|
console.log(err);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
console.log(`subscribed to alliance/selected`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client.subscribe("alliance/status", (err) => {
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
|
|
|
|
console.log(err);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
console.log(`subscribed to alliance/status`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
client.subscribe("time", (err) => {
|
|
|
|
client.subscribe("time", (err) => {
|
|
|
|
if (err) {
|
|
|
|
if (err) {
|
|
|
|
console.log(err);
|
|
|
|
console.log(err);
|
|
|
@ -178,12 +209,32 @@ client.on("message", (topic, message) => {
|
|
|
|
let message_str = message.toString();
|
|
|
|
let message_str = message.toString();
|
|
|
|
|
|
|
|
|
|
|
|
switch(topic_str){
|
|
|
|
switch(topic_str){
|
|
|
|
|
|
|
|
case "alliance/selecting":
|
|
|
|
|
|
|
|
alliance_selecting = message_str;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "alliance/selected":
|
|
|
|
|
|
|
|
alliance_selected = message_str;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case "alliance/status":
|
|
|
|
|
|
|
|
selection_state = message_str;
|
|
|
|
|
|
|
|
if(selection_state == "accepted") {
|
|
|
|
|
|
|
|
display_state = "accepted";
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
display_state = "alliance-selection";
|
|
|
|
|
|
|
|
}, 4000);
|
|
|
|
|
|
|
|
} else if(selection_state == "declined") {
|
|
|
|
|
|
|
|
display_state = "denied";
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
|
|
display_state = "alliance-selection";
|
|
|
|
|
|
|
|
}, 4000);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
case "time":
|
|
|
|
case "time":
|
|
|
|
let local = Date.now();
|
|
|
|
let local = Date.now();
|
|
|
|
let server = JSON.parse(message_str) * 1000;
|
|
|
|
let server = JSON.parse(message_str) * 1000;
|
|
|
|
offset = server - local;
|
|
|
|
offset = server - local;
|
|
|
|
|
|
|
|
|
|
|
|
if (timer != "Scoring" && timer != "Scored" && match_name_show != "Next Match") {
|
|
|
|
if (timer != "Scoring" && timer != "Scored") {
|
|
|
|
stop_timer();
|
|
|
|
stop_timer();
|
|
|
|
tick_timer();
|
|
|
|
tick_timer();
|
|
|
|
timer_next_tick = setInterval(tick_timer, 50);
|
|
|
|
timer_next_tick = setInterval(tick_timer, 50);
|
|
|
@ -199,8 +250,13 @@ client.on("message", (topic, message) => {
|
|
|
|
round = field_obj.tuple.round;
|
|
|
|
round = field_obj.tuple.round;
|
|
|
|
if (round == "Qualification") {
|
|
|
|
if (round == "Qualification") {
|
|
|
|
round = "Qual";
|
|
|
|
round = "Qual";
|
|
|
|
|
|
|
|
} else if (round == "QuarterFinals") {
|
|
|
|
|
|
|
|
round = "QF"
|
|
|
|
|
|
|
|
} else if (round == "SemiFinals") {
|
|
|
|
|
|
|
|
round = "SF"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
match_name = `${round} ${num}`;
|
|
|
|
instance = `${field_obj.tuple.instance}`;
|
|
|
|
|
|
|
|
match_name = `${round} ${instance}-${num}`;
|
|
|
|
number = `${num}`;
|
|
|
|
number = `${num}`;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case field_state_topic:
|
|
|
|
case field_state_topic:
|
|
|
@ -215,18 +271,15 @@ client.on("message", (topic, message) => {
|
|
|
|
score_blue_str = "";
|
|
|
|
score_blue_str = "";
|
|
|
|
score_blue = 0;
|
|
|
|
score_blue = 0;
|
|
|
|
score_red = 0;
|
|
|
|
score_red = 0;
|
|
|
|
match_name_show = "Next Match";
|
|
|
|
|
|
|
|
display_state = "pre-game";
|
|
|
|
display_state = "pre-game";
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case "Timeout":
|
|
|
|
case "Timeout":
|
|
|
|
timer = "Timeout";
|
|
|
|
timer = "Timeout";
|
|
|
|
match_name_show = match_name;
|
|
|
|
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case "Driver":
|
|
|
|
case "Driver":
|
|
|
|
timer_end = start_ms + 105;
|
|
|
|
timer_end = start_ms + 105;
|
|
|
|
tick_timer();
|
|
|
|
tick_timer();
|
|
|
|
timer_next_tick = setInterval(tick_timer, 50);
|
|
|
|
timer_next_tick = setInterval(tick_timer, 50);
|
|
|
|
match_name_show = match_name;
|
|
|
|
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case "DriverDone":
|
|
|
|
case "DriverDone":
|
|
|
|
timer = "Scoring";
|
|
|
|
timer = "Scoring";
|
|
|
@ -249,28 +302,23 @@ client.on("message", (topic, message) => {
|
|
|
|
timer_end = start_ms + 15;
|
|
|
|
timer_end = start_ms + 15;
|
|
|
|
tick_timer();
|
|
|
|
tick_timer();
|
|
|
|
timer_next_tick = setInterval(tick_timer, 50);
|
|
|
|
timer_next_tick = setInterval(tick_timer, 50);
|
|
|
|
match_name_show = match_name;
|
|
|
|
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case "AutonomousDone":
|
|
|
|
case "AutonomousDone":
|
|
|
|
match_name_show = match_name;
|
|
|
|
|
|
|
|
timer = "Scoring";
|
|
|
|
timer = "Scoring";
|
|
|
|
score_red_str = "";
|
|
|
|
score_red_str = "";
|
|
|
|
score_blue_str = "";
|
|
|
|
score_blue_str = "";
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case "Abandoned":
|
|
|
|
case "Abandoned":
|
|
|
|
timer = "Abandoned";
|
|
|
|
timer = "Abandoned";
|
|
|
|
match_name_show = match_name;
|
|
|
|
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case "Stopped":
|
|
|
|
case "Stopped":
|
|
|
|
timer = "Stopped";
|
|
|
|
timer = "Stopped";
|
|
|
|
match_name_show = match_name;
|
|
|
|
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case "Scored":
|
|
|
|
case "Scored":
|
|
|
|
timer = "Scored";
|
|
|
|
timer = "Scored";
|
|
|
|
score_red_str = `${score_red}`;
|
|
|
|
score_red_str = `${score_red}`;
|
|
|
|
score_blue_str = `${score_blue}`;
|
|
|
|
score_blue_str = `${score_blue}`;
|
|
|
|
display_state = "timer";
|
|
|
|
display_state = "timer";
|
|
|
|
match_name_show = match_name;
|
|
|
|
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -337,7 +385,7 @@ onMount(() => {
|
|
|
|
<p id="red-name">{event_name}</p>
|
|
|
|
<p id="red-name">{event_name}</p>
|
|
|
|
<p id="blue-name">{display_name}</p>
|
|
|
|
<p id="blue-name">{display_name}</p>
|
|
|
|
<p id="timer">{timer}</p>
|
|
|
|
<p id="timer">{timer}</p>
|
|
|
|
<p id="match">{match_name_show}</p>
|
|
|
|
<p id="match">{match_name}</p>
|
|
|
|
|
|
|
|
|
|
|
|
<p id="score-red">{score_red_str}</p>
|
|
|
|
<p id="score-red">{score_red_str}</p>
|
|
|
|
<p id="score-blue">{score_blue_str}</p>
|
|
|
|
<p id="score-blue">{score_blue_str}</p>
|
|
|
@ -383,7 +431,7 @@ onMount(() => {
|
|
|
|
<div id="pre-mid">
|
|
|
|
<div id="pre-mid">
|
|
|
|
<p id="pre-mid-top">{round}</p>
|
|
|
|
<p id="pre-mid-top">{round}</p>
|
|
|
|
<div id="pre-mid-vs"><p>VS</p></div>
|
|
|
|
<div id="pre-mid-vs"><p>VS</p></div>
|
|
|
|
<p id="pre-mid-bot">{number}</p>
|
|
|
|
<p id="pre-mid-bot">{instance}-{number}</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="pre-bot" id="pre-b1">
|
|
|
|
<div class="pre-bot" id="pre-b1">
|
|
|
|
<p>{teams_blue[0]}</p>
|
|
|
|
<p>{teams_blue[0]}</p>
|
|
|
@ -394,7 +442,7 @@ onMount(() => {
|
|
|
|
<div class="pre-bot" id="pre-b2">
|
|
|
|
<div class="pre-bot" id="pre-b2">
|
|
|
|
<p>{teams_blue[1]}</p>
|
|
|
|
<p>{teams_blue[1]}</p>
|
|
|
|
<object type="image/png" data="/robots/{teams_blue[1]}.gif">
|
|
|
|
<object type="image/png" data="/robots/{teams_blue[1]}.gif">
|
|
|
|
<img class="rotating" src="/robots/fallback.jgp">
|
|
|
|
<img class="rotating" src="/robots/fallback.jpg">
|
|
|
|
</object>
|
|
|
|
</object>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
@ -402,12 +450,38 @@ onMount(() => {
|
|
|
|
<img class="gif-background" alt="wavy" src="/gifs/wavy_background.gif">
|
|
|
|
<img class="gif-background" alt="wavy" src="/gifs/wavy_background.gif">
|
|
|
|
<img class="gif-foreground" alt="Mecha Mayhem 2024" src="/gifs/mm2024.gif">
|
|
|
|
<img class="gif-foreground" alt="Mecha Mayhem 2024" src="/gifs/mm2024.gif">
|
|
|
|
{:else if (display_state == "alliance-selection")}
|
|
|
|
{:else if (display_state == "alliance-selection")}
|
|
|
|
<div class="banner"><p>210Y Selecting</p></div>
|
|
|
|
<img class="gif-background" alt="wavy" src="/gifs/wavy_background.gif">
|
|
|
|
|
|
|
|
<div id="alliance-selection">
|
|
|
|
|
|
|
|
<div class="select-top" id="t1"><p>Captain</p></div>
|
|
|
|
|
|
|
|
<div class="select-top" id="t2"><p>Selected</p></div>
|
|
|
|
|
|
|
|
<div id="alliance-selecting">
|
|
|
|
|
|
|
|
{#if (alliance_selecting != "")}
|
|
|
|
|
|
|
|
<object type="image/png" data="/robots/{alliance_selecting}.gif">
|
|
|
|
|
|
|
|
<img class="rotating" src="/robots/fallback.jpg">
|
|
|
|
|
|
|
|
</object>
|
|
|
|
|
|
|
|
{/if}
|
|
|
|
|
|
|
|
<p>{alliance_selecting}</p>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div id="alliance-selected">
|
|
|
|
|
|
|
|
{#if (alliance_selected != "")}
|
|
|
|
|
|
|
|
<object type="image/png" data="/robots/{alliance_selected}.gif">
|
|
|
|
|
|
|
|
<img class="rotating" src="/robots/fallback.jpg">
|
|
|
|
|
|
|
|
</object>
|
|
|
|
|
|
|
|
{/if}
|
|
|
|
|
|
|
|
<p>{alliance_selected}</p>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
{:else if (display_state == "break")}
|
|
|
|
{:else if (display_state == "break")}
|
|
|
|
<div class="banner"><p>Practice @ 12:45</p></div>
|
|
|
|
<div class="banner"><p>Practice @ 12:45</p></div>
|
|
|
|
{:else if (display_state == "red-wins")}
|
|
|
|
{:else if (display_state == "red-wins")}
|
|
|
|
<img class="gif-background" alt="wavy" src="/gifs/wavy_background.gif">
|
|
|
|
<img class="gif-background" alt="wavy" src="/gifs/wavy_background.gif">
|
|
|
|
<img class="gif-foreground" alt="red-wins" src="/gifs/red_win.gif">
|
|
|
|
<img class="gif-foreground" alt="red-wins" src="/gifs/red_win.gif">
|
|
|
|
|
|
|
|
{:else if (display_state == "accepted")}
|
|
|
|
|
|
|
|
<img class="gif-background" alt="wavy" src="/gifs/wavy_background.gif">
|
|
|
|
|
|
|
|
<img class="gif-foreground" alt="accepted" src="/gifs/accepted.gif">
|
|
|
|
|
|
|
|
{:else if (display_state == "denied")}
|
|
|
|
|
|
|
|
<img class="gif-background" alt="wavy" src="/gifs/wavy_background.gif">
|
|
|
|
|
|
|
|
<img class="gif-foreground" alt="denied" src="/gifs/declined.gif">
|
|
|
|
{:else if (display_state == "blue-wins")}
|
|
|
|
{:else if (display_state == "blue-wins")}
|
|
|
|
<img class="gif-background" alt="wavy" src="/gifs/wavy_background.gif">
|
|
|
|
<img class="gif-background" alt="wavy" src="/gifs/wavy_background.gif">
|
|
|
|
<img class="gif-foreground" alt="blue-wins" src="/gifs/blue_win.gif">
|
|
|
|
<img class="gif-foreground" alt="blue-wins" src="/gifs/blue_win.gif">
|
|
|
@ -459,6 +533,52 @@ p {
|
|
|
|
color: white;
|
|
|
|
color: white;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#alliance-selection {
|
|
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
|
|
z-index: 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
display: grid;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grid-template-columns: 50% 50%;
|
|
|
|
|
|
|
|
grid-template-rows: 10% 90%;
|
|
|
|
|
|
|
|
grid-template-areas: "t1 t2"
|
|
|
|
|
|
|
|
"s1 s2";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#alliance-selecting {
|
|
|
|
|
|
|
|
grid-area: s1;
|
|
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
flex-direction: row-reverse;
|
|
|
|
|
|
|
|
flex-grow: 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#alliance-selecting p {
|
|
|
|
|
|
|
|
font-size: 3cqw;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#alliance-selected p {
|
|
|
|
|
|
|
|
font-size: 3cqw;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#alliance-selected {
|
|
|
|
|
|
|
|
grid-area: s2;
|
|
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
|
|
|
flex-grow: 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#score-midground {
|
|
|
|
#score-midground {
|
|
|
|
z-index: 1;
|
|
|
|
z-index: 1;
|
|
|
|
position: relative;
|
|
|
|
position: relative;
|
|
|
@ -538,6 +658,24 @@ p {
|
|
|
|
width: 100%;
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.select-top p {
|
|
|
|
|
|
|
|
font-size: 1cqw;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.select-top {
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#t1 {
|
|
|
|
|
|
|
|
grid-area: t1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#t2 {
|
|
|
|
|
|
|
|
grid-area: t2;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#pre-b1 {
|
|
|
|
#pre-b1 {
|
|
|
|
font-size: 2cqw;
|
|
|
|
font-size: 2cqw;
|
|
|
|
grid-area: b1;
|
|
|
|
grid-area: b1;
|
|
|
@ -610,6 +748,19 @@ p {
|
|
|
|
background-color: #ee0000;
|
|
|
|
background-color: #ee0000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#alliance-selection div object img {
|
|
|
|
|
|
|
|
height: 40cqh;
|
|
|
|
|
|
|
|
width: 40cqh;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#alliance-selection div object {
|
|
|
|
|
|
|
|
height: 180cqh;
|
|
|
|
|
|
|
|
width: 180cqh;
|
|
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.banner-gif {
|
|
|
|
.banner-gif {
|
|
|
|
z-index: 0;
|
|
|
|
z-index: 0;
|
|
|
|
position: absolute;
|
|
|
|
position: absolute;
|
|
|
|