119 lines
2.5 KiB
Go
119 lines
2.5 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
// barrier represents a multi-position light barrier attached to a motor.
|
||
|
type barrier struct {
|
||
|
// npos is the number of the positions of the light barrier.
|
||
|
npos uint
|
||
|
// cur is the current position of the motor.
|
||
|
cur float64
|
||
|
}
|
||
|
|
||
|
// pins returns an npos-length array representing the interruption state of the
|
||
|
// barrier given cur. An interrupted light barrier is represented by a true
|
||
|
// value, an uninterrupted one with a false value.
|
||
|
//
|
||
|
// Every light barrier position is half a unit away from eachother, with the
|
||
|
// first light barrier at unit 1.
|
||
|
func (b *barrier) pins() []bool {
|
||
|
res := make([]bool, b.npos)
|
||
|
for i := uint(0); i < b.npos; i++ {
|
||
|
pos := float64(i) * float64(1.0)
|
||
|
pos += 1.0
|
||
|
if b.cur*2.0 >= pos {
|
||
|
res[i] = true
|
||
|
}
|
||
|
}
|
||
|
return res
|
||
|
}
|
||
|
|
||
|
// status returns a human-readable status of the barrier like '||..' for a
|
||
|
// 4-position light barrier with the first two barrier interrupted.
|
||
|
func (b *barrier) status() string {
|
||
|
res := ""
|
||
|
for _, v := range b.pins() {
|
||
|
if v {
|
||
|
res += "|"
|
||
|
} else {
|
||
|
res += "."
|
||
|
}
|
||
|
}
|
||
|
return res
|
||
|
}
|
||
|
|
||
|
// motor represents an electrical motor which drives a linear actuator at 1 unit per second.
|
||
|
type motor struct {
|
||
|
// en is true if the motor is enabled.
|
||
|
en bool
|
||
|
// dir is used to select the direction of the motor. If true, the motor
|
||
|
// actuator moves towards positive values.
|
||
|
dir bool
|
||
|
// pos is the current position of the motor actuator.
|
||
|
pos float64
|
||
|
|
||
|
// barrier attached to this motor, will be automatically updated when the
|
||
|
// motor simulation runs.
|
||
|
barrier *barrier
|
||
|
}
|
||
|
|
||
|
// status returns a human-readable staus of the motor like '<-ID ' indicating
|
||
|
// whether the motor is moving, and if so, in which direction.
|
||
|
func (s *motor) status(id string) string {
|
||
|
res := ""
|
||
|
if s.en {
|
||
|
if s.dir {
|
||
|
res += fmt.Sprintf(" %s->", id)
|
||
|
} else {
|
||
|
res += fmt.Sprintf("<-%s ", id)
|
||
|
}
|
||
|
} else {
|
||
|
res += fmt.Sprintf(" %s ", id)
|
||
|
}
|
||
|
return res
|
||
|
}
|
||
|
|
||
|
// sim runs a simulation step of the motor given a delta time.
|
||
|
func (s *motor) sim(dt time.Duration) {
|
||
|
if !s.en {
|
||
|
return
|
||
|
}
|
||
|
d := dt.Seconds()
|
||
|
if s.dir {
|
||
|
s.pos += d
|
||
|
} else {
|
||
|
s.pos -= d
|
||
|
}
|
||
|
s.barrier.cur = s.pos
|
||
|
}
|
||
|
|
||
|
type indicators struct {
|
||
|
indEvac bool
|
||
|
indHTReadyN bool
|
||
|
indPumpDown bool
|
||
|
}
|
||
|
|
||
|
func (i indicators) String() string {
|
||
|
res := ""
|
||
|
if i.indEvac {
|
||
|
res += "EVAC "
|
||
|
} else {
|
||
|
res += "---- "
|
||
|
}
|
||
|
if !i.indHTReadyN {
|
||
|
res += "HT READY "
|
||
|
} else {
|
||
|
res += "-------- "
|
||
|
}
|
||
|
if i.indPumpDown {
|
||
|
res += "PUMP DOWN "
|
||
|
} else {
|
||
|
res += "VENT "
|
||
|
}
|
||
|
|
||
|
return res
|
||
|
}
|