Skip to content

Commit

Permalink
Station Stops Installed
Browse files Browse the repository at this point in the history
  • Loading branch information
cpapplefamily committed Dec 2, 2024
1 parent ae7da89 commit 30b59ed
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 23 deletions.
16 changes: 5 additions & 11 deletions field/arena.go
Original file line number Diff line number Diff line change
Expand Up @@ -924,18 +924,12 @@ var blueAmplifiedTimeRemaining_ons = false
// Updates the score given new input information from the field PLC, and actuates PLC outputs accordingly.
func (arena *Arena) handlePlcInputOutput() {
if !arena.Plc.IsEnabled() {
// Declare and initialize arrays
redEStops, blueEStops := [3]bool{}, [3]bool{}
redAStops, blueAStops := [3]bool{}, [3]bool{}
// Fill arrays with false values
for i := range redEStops {
redEStops[i] = false
redAStops[i] = false
}
for i := range blueEStops {
blueEStops[i] = false
blueAStops[i] = false
// Handle PLC functions that are always active.
if arena.Plc.GetFieldEStop() && !arena.matchAborted {
arena.AbortMatch()
}
redEStops, blueEStops := arena.Plc.GetTeamEStops()
redAStops, blueAStops := arena.Plc.GetTeamAStops()
arena.handleTeamStop("R1", redEStops[0], redAStops[0])
arena.handleTeamStop("R2", redEStops[1], redAStops[1])
arena.handleTeamStop("R3", redEStops[2], redAStops[2])
Expand Down
23 changes: 23 additions & 0 deletions plc/plc.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ type Plc interface {
SetAddress(address string)
IsEnabled() bool
IsHealthy() bool
SetAlternateIOStopState(input int, state bool)
ResetEstops()
IoChangeNotifier() *websocket.Notifier
Run()
GetArmorBlockStatuses() map[string]bool
Expand Down Expand Up @@ -164,6 +166,25 @@ func (plc *ModbusPlc) SetAddress(address string) {
}
}

func (plc *ModbusPlc) ResetEstops(){
plc.inputs[red1EStop] = true
plc.inputs[red2EStop] = true
plc.inputs[red3EStop] = true
plc.inputs[blue1EStop] = true
plc.inputs[blue2EStop] = true
plc.inputs[blue3EStop] = true
plc.inputs[red1AStop] = true
plc.inputs[red2AStop] = true
plc.inputs[red3AStop] = true
plc.inputs[blue1AStop] = true
plc.inputs[blue2AStop] = true
plc.inputs[blue3AStop] = true
}

// used for Alternate IO stops
func (plc *ModbusPlc) SetAlternateIOStopState(input int, state bool){
plc.inputs[input] = state
}
// Returns true if the PLC is enabled in the configurations.
func (plc *ModbusPlc) IsEnabled() bool {
return plc.address != ""
Expand All @@ -186,6 +207,7 @@ func (plc *ModbusPlc) Run() {
if !plc.IsEnabled() {
// No PLC is configured; just allow the loop to continue to simulate inputs and outputs.
plc.isHealthy = false

} else {
err := plc.connect()
if err != nil {
Expand Down Expand Up @@ -403,6 +425,7 @@ func (plc *ModbusPlc) update() {

// Detect any changes in input or output and notify listeners if so.
if plc.inputs != plc.oldInputs || plc.registers != plc.oldRegisters || plc.coils != plc.oldCoils {
log.Print("changes in input or output")
plc.ioChangeNotifier.Notify()
plc.oldInputs = plc.inputs
plc.oldRegisters = plc.registers
Expand Down
70 changes: 70 additions & 0 deletions static/css/scoring_panel.css
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ body {
.shortcut {
margin: 0 0.2vw;
font-size: 1vw;
width: 100%;
align-self: flex-start;
}
.row{
Expand Down Expand Up @@ -219,4 +220,73 @@ body {
}
.icon {
width: 100%;
}

.eStops {
width: 98%;
display: flex;
flex-direction: row;
justify-content: space-evenly;
align-items: center;
border-radius: 25px;
border: 1px solid #333;
}
.teamEstopPanle {
width: 10vw;
height: auto;
margin: 0.4vw 3vw;
justify-content: space-between;
align-items: center;
}

.octagon-button {
position: relative;
width: 10vw; /* Adjust width */
height: 10vw; /* Adjust height */
clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
font-size: 2vw;
color: rgb(255, 255, 255); /* Text color */
cursor: pointer;
border: none;
}

.octagon-button .icon {
margin-top: 1px;
}

.octagon-button:hover {
background: #fbff06; /* Change color on hover */
color: rgb(0, 0, 0); /* Text color */
}

.iconCentered{
display: flex;
align-items: center; /* Vertically center the content */
justify-content: center; /* Horizontally center the content */
text-align: center; /* Center text alignment */
height: auto; /* Allow dynamic height adjustment */
line-height: 1.5; /* Adjust line spacing if needed */
padding: 10px; /* Add padding to increase perceived size */
font-size: 1.2em; /* Increase font size for visibility */
}
.shorcutCentered {
align-items: center; /* Vertically center the content */
justify-content: center; /* Horizontally center the content */
margin-bottom: 5px; /* Space between text and icon */
text-align: center; /* Center text within its container */
}

.hidden {
display: none; /* Completely hides the element */
}
.btnE {
background: rgb(255, 0, 0);
}
.btnA {
background: rgb(0, 119, 255);
}
17 changes: 17 additions & 0 deletions static/js/scoring_panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,20 @@ $(function() {
realtimeScore: function(event) { handleRealtimeScore(event.data); },
});
});

// Set initial visibility state
let bool = false;

// Function to toggle visibility of the panel
function toggleEstopPanel() {
const panel = document.querySelector('.eStops');
if (bool) {
panel.classList.remove('hidden'); // Hide the panel
} else {
panel.classList.add('hidden'); // Show the panel
}
bool = !bool; // Toggle the boolean state
}

// Attach event listener to the button
document.getElementById('toggleButton').addEventListener('click', toggleEstopPanel);
56 changes: 44 additions & 12 deletions templates/scoring_panel.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@

<div id="elements">
<div class="goal-header" >Speaker
{{template "goaladd" dict "plus" "S" "icon1" "Auto+"}}
{{template "2goal" dict "btn1" "O" "icon1" "Auto+" "btn2" "o" "icon2" "Auto-" "count" "autoSpeakerNotes"}}
{{template "2goal" dict "btn1" "P" "icon1" "Amped+" "btn2" "p" "icon2" "Amped-" "count" "teleopAmplifiedSpeakerNotes"}}
{{template "2goal" dict "btn1" "I" "icon1" "Teliop+" "btn2" "i" "icon2" "Teliop-" "count" "teleopUnamplifiedSpeakerNotes"}}
{{template "goaladd" dict "plus" "S" "txt1" "Auto+"}}
{{template "2goal" dict "btn1" "O" "txt1" "Auto+" "btn2" "o" "txt2" "Auto-" "count" "autoSpeakerNotes"}}
{{template "2goal" dict "btn1" "P" "txt1" "Amped+" "btn2" "p" "txt2" "Amped-" "count" "teleopAmplifiedSpeakerNotes"}}
{{template "2goal" dict "btn1" "I" "txt1" "Teliop+" "btn2" "i" "txt2" "Teliop-" "count" "teleopUnamplifiedSpeakerNotes"}}
</div>
<div class="goal-header">AMP
{{template "goaladd" dict "plus" "A" "icon1" "Sensor"}}
{{template "2goal" dict "btn1" "U" "icon1" "Auto+" "btn2" "u" "icon2" "Auto-" "count" "autoAmpNotes"}}
{{template "2goal" dict "btn1" "Y" "icon1" "Teliop+" "btn2" "y" "icon2" "Teliop-" "count" "teleopAmpNotes"}}
{{template "2goal" dict "btn1" "B" "icon1" "bank+" "btn2" "b" "icon2" "bank-" "count" "bankedAmpNotes"}}
{{template "goaladd" dict "plus" "A" "txt1" "Sensor"}}
{{template "2goal" dict "btn1" "U" "txt1" "Auto+" "btn2" "u" "txt2" "Auto-" "count" "autoAmpNotes"}}
{{template "2goal" dict "btn1" "Y" "txt1" "Teliop+" "btn2" "y" "txt2" "Teliop-" "count" "teleopAmpNotes"}}
{{template "2goal" dict "btn1" "B" "txt1" "bank+" "btn2" "b" "txt2" "bank-" "count" "bankedAmpNotes"}}
</div>
<div class="goal-header">Coop Button
<div id="coopertitionStatus" class="boolean robot-field" onclick="handleClick('coopButton');">
Expand Down Expand Up @@ -93,7 +93,16 @@
</div>
</div>
</div>
<button id="toggleButton">Show E-Stops</button>
<div class="eStops">EStops
{{template "2stops" dict "btn1" "E1" "txt1" "EStop" "btn2" "A1" "txt2" "AStop"}}
{{template "2stops" dict "btn1" "E2" "txt1" "EStop" "btn2" "A2" "txt2" "AStop"}}
{{template "2stops" dict "btn1" "E3" "txt1" "EStop" "btn2" "A3" "txt2" "AStop"}}
</div>
</div>



</div>

<div id="commitMatchScore">
Expand Down Expand Up @@ -128,18 +137,19 @@
<div class="number-button plus" onclick="handleClick('{{.plus}}');">
<div class="shortcut">{{.plus}}</div>
<div class="icon">
{{.icon1}}
{{.txt1}}
</div>
<div class="shortcut" style="opacity: 0;">{{.plus}}</div>
</div>
</div>
{{end}}

{{define "goalsub"}}
<div class="goal">
<div class="number-button minus" onclick="handleClick('{{.minus}}');">
<div class="shortcut">{{.minus}}</div>
<div class="icon">
{{.icon1}}
{{.txt1}}
</div>
<div class="shortcut" style="opacity: 0;">{{.minus}}</div>
</div>
Expand All @@ -153,15 +163,37 @@
<div class="number-button btn1" onclick="handleClick('{{.btn1}}');">
<div class="shortcut">{{.btn1}}</div>
<div class="icon">
{{.icon1}}
{{.txt1}}
</div>
<div class="shortcut" style="opacity: 0;">{{.btn1}}</div>
</div>
<div id={{.count}}></div>
<div class="number-button btn2" onclick="handleClick('{{.btn2}}');">
<div class="shortcut">{{.btn2}}</div>
<div class="icon">
{{.icon2}}
{{.txt2}}
</div>
<div class="shortcut" style="opacity: 0;">{{.minus}}</div>
</div>
</div>
{{end}}

{{define "2stops"}}
<div class="teamEstopPanle">
<div class="number-button btnE octagon-button" onclick="handleClick('{{.btn1}}');">
<div class="shorcutCentered">{{.btn1}}
<div class="iconCentered">
{{.txt1}}
</div>
</div>
<div class="shortcut" style="opacity: 0;">{{.btn1}}</div>
</div>
<div>&nbsp;</div>
<div class="number-button btnA octagon-button" onclick="handleClick('{{.btn2}}');">
<div class="shorcutCentered">{{.btn2}}
<div class="iconCentered">
{{.txt2}}
</div>
</div>
<div class="shortcut" style="opacity: 0;">{{.minus}}</div>
</div>
Expand Down
2 changes: 2 additions & 0 deletions web/match_play.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ func (web *Web) matchPlayMatchLoadHandler(w http.ResponseWriter, r *http.Request
handleWebErr(w, err)
return
}

web.arena.Plc.ResetEstops()
}

// The websocket endpoint for the match play client to send control commands and receive status updates.
Expand Down
60 changes: 60 additions & 0 deletions web/scoring_panel.go
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,66 @@ func (web *Web) scoringPanelWebsocketHandler(w http.ResponseWriter, r *http.Requ
web.arena.CurrentMatch.Type == model.Playoff)
log.Printf("coopButton Pressed")
scoreChanged = true
case "E1":
if web.arena.EventSettings.AlternateIOEnabled{
if alliance == "red"{
web.arena.Plc.SetAlternateIOStopState(1,false)
}else{
web.arena.Plc.SetAlternateIOStopState(7,false)
}
log.Printf("E1 Pressed")
scoreChanged = true
}
case "A1":
if web.arena.EventSettings.AlternateIOEnabled{
if alliance == "red"{
web.arena.Plc.SetAlternateIOStopState(2,false)
}else{
web.arena.Plc.SetAlternateIOStopState(8,false)
}
log.Printf("A1 Pressed")
scoreChanged = true
}
case "E2":
if web.arena.EventSettings.AlternateIOEnabled{
if alliance == "red"{
web.arena.Plc.SetAlternateIOStopState(3,false)
}else{
web.arena.Plc.SetAlternateIOStopState(9,false)
}
log.Printf("E2 Pressed")
scoreChanged = true
}
case "A2":
if web.arena.EventSettings.AlternateIOEnabled{
if alliance == "red"{
web.arena.Plc.SetAlternateIOStopState(4,false)
}else{
web.arena.Plc.SetAlternateIOStopState(10,false)
}
log.Printf("A2 Pressed")
scoreChanged = true
}
case "E3":
if web.arena.EventSettings.AlternateIOEnabled{
if alliance == "red"{
web.arena.Plc.SetAlternateIOStopState(5,false)
}else{
web.arena.Plc.SetAlternateIOStopState(11,false)
}
log.Printf("E3 Pressed")
scoreChanged = true
}
case "A3":
if web.arena.EventSettings.AlternateIOEnabled{
if alliance == "red"{
web.arena.Plc.SetAlternateIOStopState(6,false)
}else{
web.arena.Plc.SetAlternateIOStopState(12,false)
}
log.Printf("A3 Pressed")
scoreChanged = true
}
}

if scoreChanged {
Expand Down

0 comments on commit 30b59ed

Please sign in to comment.