//Called by executeOrder //Start the elevator ordered direction. Also starts the motorstop timer func goToFloor(currentFloor uint, status *driver.LiftStatus, stopFloor *uint, motorDirectionCh chan<- driver.MotorDirection, statusCh chan<- driver.LiftStatus) { if !status.Door && !status.Running { if currentFloor < *stopFloor { motorDirectionCh <- driver.MD_up status.Direction = true } else { motorDirectionCh <- driver.MD_down status.Direction = false } motorStopTimerRunning = true timeGoToFloor = time.Now() status.Running = true statusCh <- *status } }
//Called by RunLift func runQueue(liftStatus driver.LiftStatus, floorOrder chan<- uint) { floor := liftStatus.Floor if liftStatus.Running { if liftStatus.Direction { floor++ } else { floor-- } } order, direction := localqueue.GetOrder(floor, liftStatus.Direction) if liftStatus.Floor == order && liftStatus.Door { removeFromQueue(order, direction) lastOrder = 0 liftStatus.Door = true time.Sleep(20 * time.Millisecond) } else if order == 0 && !liftStatus.Door { isIdle = true } else if order != 0 { isIdle = false if lastOrder != order && !liftStatus.Door { lastOrder = order floorOrder <- order } } }
//Called by executeOrder //Stops at ordered floor, sets lights,motor and door. Also detects motorstop func stopAtFloor(currentFloor uint, status *driver.LiftStatus, stopFloor *uint, motorDirectionCh chan<- driver.MotorDirection, lightCh chan<- driver.Light, statusCh chan<- driver.LiftStatus, doorTimerCh chan<- bool, motorStopCh chan<- bool) { if status.Floor == *stopFloor { motorDirectionCh <- driver.MD_stop status.Running = false status.Door = true lightCh <- driver.Light{0, driver.Door, true} go func() { time.Sleep(3 * time.Second) doorTimerCh <- true }() *stopFloor = 0 motorStopCh <- false statusCh <- *status } else if time.Now().Sub(timeGoToFloor) > time.Duration(motorStopTimeoutBase)*time.Second && motorStopTimerRunning { //motorstop detected motorStopTimerRunning = false motorStopCh <- true } }
//Called by executeOrder func updateStatus(currentFloor uint, status *driver.LiftStatus, motorDirectionCh chan<- driver.MotorDirection, statusCh chan<- driver.LiftStatus) { switch currentFloor { case 0: if status.Door { log.Fatal("lift should not be moving, door is open") } if !status.Running { log.Fatal("lift should not be moving, motor is off") } return case 1, 4: motorDirectionCh <- driver.MD_stop status.Floor = currentFloor status.Running = false statusCh <- *status case 2, 3: if currentFloor != status.Floor { status.Floor = currentFloor statusCh <- *status } default: log.Println("found unknown floor", currentFloor) } }
//Called by Init func executeOrder(orderedFloorCh <-chan uint, lightCh chan<- driver.Light, statusCh chan<- driver.LiftStatus, floorSensorCh <-chan uint, doorTimerCh chan bool, motorDirectionCh chan<- driver.MotorDirection, motorStopCh chan<- bool, quitCh <-chan bool) { var ( currentFloor uint stopFloor uint status driver.LiftStatus ) status.Direction = true // not in state, go up until floor motorDirectionCh <- driver.MD_up for { currentFloor = <-floorSensorCh if currentFloor != 0 { log.Println("found floor") break } } motorDirectionCh <- driver.MD_stop status.Floor = currentFloor log.Println(currentFloor) status.Running = false status.Door = false statusCh <- status for { select { case <-quitCh: return case stopFloor = <-orderedFloorCh: //Got new stopFloor case <-doorTimerCh: lightCh <- driver.Light{0, driver.Door, false} status.Door = false statusCh <- status case currentFloor = <-floorSensorCh: updateStatus(currentFloor, &status, motorDirectionCh, statusCh) default: time.Sleep(5 * time.Millisecond) if stopFloor != 0 { stopAtFloor(currentFloor, &status, &stopFloor, motorDirectionCh, lightCh, statusCh, doorTimerCh, motorStopCh) goToFloor(currentFloor, &status, &stopFloor, motorDirectionCh, statusCh) } } } }