-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFSM.go
149 lines (120 loc) · 3.33 KB
/
FSM.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package FSM
import (
"../driver"
"../structs"
"log"
"time"
)
const doorPeriod = 3 * time.Second
type FSM_state int
const (
idle = 0
door_open = 1
moving = 2
stuck = -1
)
func init(
floor_event <- chan int
//FSM -> elev_driver
setmotordir chan<- int,
doorstate chan<- bool,
//Order_distr. -> FSM
ordermotordir <-chan int,
//Order_handler -> FSM
newtargetfloor <-chan int,
isorder <-chan bool,
timer <-chan int,
//FSM -> order_distr.
state chan<- ElevState
){
target_floor := -1
state := idle
stuck_timer := time.NewTimer(time.Second*5)
for{
select {
case <- stuck:
FSM_state = stuck
//Kø til heis skal merges med andre heiser
//Stuck sendes på channel til order distribution
case motordir := <- ordermotordir:
fmt.Printf("Setting motor direction: ", motordir)
driver.SetMotorDirection(motordir)
FSM_state = moving
Elev_state.crrent_direction = motordir
case <- isorder:
driver.SetMotorDirection(driver.DirnStop)
doorstate <- true
FSM_state = doorOpen
sleep(doorPeriod)
doorstate <- false
FSM_state = idle
case <- stuck_timer.C: //Går inn her om timeren går ut
fmt.Printf("Elevator timed out. state=stuck")
FSM_state = stuck
case floor := <- new_target_floor:
if floor != target_floor{
// funksjon for å resette timer (for å sjekke stuck)
}
target_floor = floor
fmt.Printf("New target floor is %d", target_floor+1)
switch FSM_state {
case idle:
if target_floor == -1 {
break
}
else if target_floor < Elev_state.LastPassedFloor{
driver.SetMotorDirection(driver.DirnDown)
Elev_state.CurrentDirection = driver.DirnDown
}
else if target_floor > Elev_state.LastPassedFloor{
driver.SetMotorDirection(driver.DirnUp)
Elev_state.CurrentDirection = driver.DirnUp
}
else {
driver.SetMotorDirection(driver.DirnStop)
FSM_state = door_open
}
case moving:
// skal ikke gjøre noe som helst
case door_open:
driver.SetDoorOpenLamp(1)
FSM_state = doorOpen
sleep(doorPeriod)
driver.SetDoorOpenLamp(0)
FMS_state = idle
case stuck:
case floor := <- floor_event:
driver.SetFloorIndicator(floor)
//Sjekke om heisen er stuck
if (floor == 0) || (floor == driver.numFloors-1){
Elev_state.current_direction = driver.DirnStop
}
Elev_state.last_past_floor = floor
switch FSM_state {
case idle:
fmt.Printf("STATE [idle]; reached floor %d", floor+1)
case moving:
fmt.Printf("STATE [moving]; reached floor %d", floor+1)
stuck_timer.Reset(5*time.Second) //resetter timeren
if target_floor == -1 {
break
}
else if target_floor < Elev_state.LastPassedFloor{
driver.SetMotorDirection(driver.DirnDown)
Elev_state.current_direction = driver.DirnDown
}
else if target_floor > Elev_state.LastPassedFloor{
driver.set_motor_direction(driver.DirnUp)
Elev_state.current_direction = driver.DirnUp
}
else {
driver.SetMotorDirection(driver.DirnStop)
FSM_state = door_open
}
case door_open:
fmt.Printf("STATE [doors open]; reached floor %d", floor+1)
case stuck:
}
}
}
}