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 }