jeol-t330a/modules/ph00524/emu/scope.go

119 lines
2.5 KiB
Go
Raw Normal View History

2024-08-16 10:31:59 +00:00
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
}