Files
cheesy-arena-lite/lights.go
2014-08-25 20:18:52 -07:00

160 lines
4.3 KiB
Go

// Copyright 2014 Team 254. All Rights Reserved.
// Author: pat@patfairbank.com (Patrick Fairbank)
//
// Methods for controlling the field LED lighting.
package main
import (
"log"
"net"
)
type LightPacket [24]byte
type Lights struct {
connections map[string]*net.Conn
packets map[string]*LightPacket
oldPackets map[string]*LightPacket
hotGoal string
newConnections bool
}
func (lightPacket *LightPacket) setColor(channel int, color string) {
switch color {
case "red":
lightPacket.setRgb(channel, 15, 0, 0)
case "blue":
lightPacket.setRgb(channel, 0, 0, 15)
case "yellow":
lightPacket.setRgb(channel, 15, 11, 0)
default:
lightPacket.setRgb(channel, 0, 0, 0)
}
}
func (lightPacket *LightPacket) setRgb(channel int, red byte, green byte, blue byte) {
lightPacket[channel*3] = red
lightPacket[channel*3+1] = green
lightPacket[channel*3+2] = blue
}
func (lights *Lights) Setup() error {
err := lights.SetupConnections()
if err != nil {
return err
}
lights.packets = make(map[string]*LightPacket)
lights.packets["red"] = &LightPacket{}
lights.packets["blue"] = &LightPacket{}
lights.oldPackets = make(map[string]*LightPacket)
lights.oldPackets["red"] = &LightPacket{}
lights.oldPackets["blue"] = &LightPacket{}
lights.sendLights()
return nil
}
func (lights *Lights) SetupConnections() error {
lights.connections = make(map[string]*net.Conn)
// Don't enable lights for a side if the controller address is not configured.
if len(eventSettings.RedGoalLightsAddress) != 0 {
conn, err := net.Dial("udp4", eventSettings.RedGoalLightsAddress)
lights.connections["red"] = &conn
if err != nil {
return err
}
}
if len(eventSettings.BlueGoalLightsAddress) != 0 {
conn, err := net.Dial("udp4", eventSettings.BlueGoalLightsAddress)
lights.connections["blue"] = &conn
if err != nil {
return err
}
}
lights.newConnections = true
return nil
}
func (lights *Lights) SetHotGoal(alliance string, leftSide bool) {
if leftSide {
lights.packets[alliance].setRgb(0, 0, 0, 0)
lights.packets[alliance].setRgb(1, 0, 0, 0)
lights.packets[alliance].setRgb(2, 0, 0, 0)
lights.packets[alliance].setColor(3, "yellow")
lights.packets[alliance].setColor(4, "yellow")
lights.packets[alliance].setColor(5, "yellow")
lights.hotGoal = "left"
} else {
lights.packets[alliance].setColor(0, "yellow")
lights.packets[alliance].setColor(1, "yellow")
lights.packets[alliance].setColor(2, "yellow")
lights.packets[alliance].setRgb(3, 0, 0, 0)
lights.packets[alliance].setRgb(4, 0, 0, 0)
lights.packets[alliance].setRgb(5, 0, 0, 0)
lights.hotGoal = "right"
}
lights.sendLights()
}
func (lights *Lights) SetAssistGoal(alliance string, numAssists int) {
lights.packets[alliance].setRgb(0, 0, 0, 0)
lights.packets[alliance].setRgb(1, 0, 0, 0)
lights.packets[alliance].setRgb(2, 0, 0, 0)
lights.packets[alliance].setRgb(3, 0, 0, 0)
lights.packets[alliance].setRgb(4, 0, 0, 0)
lights.packets[alliance].setRgb(5, 0, 0, 0)
if numAssists > 0 {
lights.packets[alliance].setColor(2, alliance)
lights.packets[alliance].setColor(3, alliance)
}
if numAssists > 1 {
lights.packets[alliance].setColor(1, alliance)
lights.packets[alliance].setColor(4, alliance)
}
if numAssists > 2 {
lights.packets[alliance].setColor(0, alliance)
lights.packets[alliance].setColor(5, alliance)
}
lights.hotGoal = ""
lights.sendLights()
}
func (lights *Lights) ClearGoal(alliance string) {
lights.SetAssistGoal(alliance, 0)
}
func (lights *Lights) SetPedestal(alliance string) {
if alliance == "red" {
lights.packets["blue"].setColor(6, alliance)
} else {
lights.packets["red"].setColor(6, alliance)
}
lights.sendLights()
}
func (lights *Lights) ClearPedestal(alliance string) {
if alliance == "red" {
lights.packets["blue"].setRgb(6, 0, 0, 0)
} else {
lights.packets["red"].setRgb(6, 0, 0, 0)
}
lights.sendLights()
}
func (lights *Lights) sendLights() {
for alliance, connections := range lights.connections {
if lights.newConnections || *lights.packets[alliance] != *lights.oldPackets[alliance] {
_, err := (*connections).Write(lights.packets[alliance][:])
if err != nil {
log.Printf("Failed to send %s light packet.", alliance)
}
mainArena.hotGoalLightNotifier.Notify(lights.hotGoal)
}
*lights.oldPackets[alliance] = *lights.packets[alliance]
}
lights.newConnections = false
}