-
Notifications
You must be signed in to change notification settings - Fork 0
/
logic.c
202 lines (166 loc) · 4.55 KB
/
logic.c
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
#ifndef __INCLUDE_LOGIC_C__
#define __INCLUDE_LOGIC_C__
#include "logic.h"
// returns the desired direction based on the current floor and the targeted floor
int desiredDirection(state* current)
{
// if we're at the target, the current direction should be DIRN_STOP / 0
if ((current->floor) == (current->target))
{
return 0;
}
// if the target is above the current floor, then the current direction should be DIRN_UP / 1
else if ((current->floor) < (current->target))
{
return 1;
}
// if the target is below the current floor, then the current direction should be DIRN_DOWN / -1
else
{
return -1;
}
}
// checks intersecting floor(s) on the way to the current target floor and returns 1 if we need to stop
int toStop(state* current)
{
if ((current->buttons)[BUTTON_COMMAND][current->floor])
{
return 1;
}
if ( (current->floor != 3) && ((current->buttons)[BUTTON_CALL_UP][current->floor]) )
{
if (current->dir == 1)
{
return 1;
}
}
if ( (current->floor != 0) && ((current->buttons)[BUTTON_CALL_DOWN][current->floor]) )
{
if (current->dir == -1)
{
return 1;
}
}
return 0;
}
// target is -1, find new target. returns 1 if there's a new target
int nextTarget(state* current)
{
//prioritizes the ground and 4th floors, so that we will go through all the floors
int priorityList[4] = {0, 3, 1, 2};
for (int i = 0; i < 4; ++i)
{
// cannot set new target to be the current floor
if ((current->floor) != priorityList[i])
{
// checks if there are any buttons pressed on the current floor
if ( ((current->buttons)[BUTTON_COMMAND][priorityList[i]]) ||
((priorityList[i] != 3) && ((current->buttons)[BUTTON_CALL_UP][priorityList[i]])) ||
((priorityList[i] != 0) && ((current->buttons)[BUTTON_CALL_DOWN][priorityList[i]])) )
{
current->target = priorityList[i];
current->dir = desiredDirection(current);
break;
}
}
}
return ((current->target) != -1);
}
//logic for what to do in case the stop button is pressed
void handleEmergency(state* current)
{
// stops the elevator and updates the necessary values in the state
elev_set_stop_lamp(1);
elev_set_motor_direction(DIRN_STOP);
current->dir = DIRN_STOP;
current->target = -1;
while (current->emergency)
{
// update the emergency variable
current->emergency = elev_get_stop_signal();
// clears all the floor requests
for (int i = 0; i < 4; ++i)
{
clearButtons(i, current);
}
if (!(current->emergency))
{
elev_set_stop_lamp(0);
elev_set_motor_direction(0);
if (elev_get_floor_sensor_signal() != -1)
{
// opens door if we're in a defined state
current->timer = time(NULL);
elev_set_door_open_lamp(1);
}
}
}
}
int updateFloor(state* current)
{
// checks for a valid floor
int floor = elev_get_floor_sensor_signal();
if ( floor != -1 )
{
// checks for a new floor
if ( (floor != (current->floor)) || ((current->floor) == -1) )
{
// changes the floor and returns 1 to show that a change has happened
current->floor = floor;
return 1;
}
}
// returns 0 as there's been no change in floor
return 0;
}
void checkFloor(state* current)
{
// changes which floor light is on
floorLight(current->floor);
// update state if we've reached the target
if ((current->floor) == (current->target))
{
current->target = -1;
current->dir = 0;
openDoor(current);
clearButtons((current->floor), current);
}
// if we haven't reached the target, have a temporary stop if needed
else if (toStop(current))
{
openDoor(current);
clearButtons((current->floor), current);
}
}
void findNewTargets(state* current)
{
// special case, elevator has stopped and someone wants to open
// the door in the current floor
if (((current->floor != 3) && (elev_get_button_signal(BUTTON_CALL_UP, current->floor))) ||
((current->floor != 0) && (elev_get_button_signal(BUTTON_CALL_DOWN, current->floor))) ||
(elev_get_button_signal(BUTTON_COMMAND, current->floor)) )
{
openDoor(current);
}
// updates the target, returns 1 if there is a new target
else if (nextTarget(current))
{
// sets the new direction based on the changes in target
current->dir = desiredDirection(current);
}
else
{
// target has been reached, if necessary a new target
// will be set next
current->target = -1;
current->dir = 0;
// if we're in an undefined state (shouldn't happen as it's handled in state_init)
// there should be set a target for 1st floor
if (current->floor == -1)
{
current->target = 0;
current->dir = -1;
}
}
}
#endif // #ifndef __INCLUDE_LOGIC_C__