-
Notifications
You must be signed in to change notification settings - Fork 0
/
prgMain.ST.bak
457 lines (413 loc) · 10.2 KB
/
prgMain.ST.bak
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
(* Queue methods *)
FUNCTION VisualizeQueue : BOOL
VAR
index : INT;
END_VAR
stringQueueRepresentation := '';
FOR index := 0 TO queueSize - 1 DO
stringQueueRepresentation := stringQueueRepresentation + ';' + INT_TO_STRING(queue[index]);
END_FOR;
END_FUNCTION
FUNCTION EnqueueFloor : BOOL
VAR_INPUT
floorToEnqueue : INT;
END_VAR
VAR
index : INT;
END_VAR
FOR index := 0 TO queueSize - 1 DO
IF queue[index] = queueDefaultValue THEN
queue[index] := floorToEnqueue;
EXIT;//index := 1000; // break
END_IF;
END_FOR;
END_FUNCTION
FUNCTION EnqueueUpperFloor : BOOL
VAR_INPUT
floorToEnqueue : INT;
END_VAR
VAR
index : INT;
END_VAR
FOR index := 0 TO queueSize - 1 DO
IF queueUpperFloors[index] = queueDefaultValue THEN
queueUpperFloors[index] := floorToEnqueue;
EXIT;
END_IF;
END_FOR;
END_FUNCTION
FUNCTION EnqueueLowerFloor : BOOL
VAR_INPUT
floorToEnqueue : INT;
END_VAR
VAR
index : INT;
END_VAR
FOR index := 0 TO queueSize - 1 DO
IF queueLowerFloors[index] = queueDefaultValue THEN
queueLowerFloors[index] := floorToEnqueue;
EXIT;
END_IF;
END_FOR;
END_FUNCTION
FUNCTION EmptyUpperAndLowerQueue : BOOL
VAR
index : INT;
END_VAR
FOR index := 0 TO queueSize - 1 DO
queueUpperFloors[index] := queueDefaultValue;
queueLowerFloors[index] := queueDefaultValue;
END_FOR;
END_FUNCTION
FUNCTION ShiftQueueLeft : BOOL
VAR
index : INT;
nextIndex : INT;
temp : INT;
END_VAR
FOR index := 0 TO queueSize - 2 DO // - 2 because not for last element
nextIndex := index + 1;
temp := queue[index];
queue[index] := queue[nextIndex];
queue[nextIndex] := temp;
END_FOR;
END_FUNCTION
(* not used *)
FUNCTION DequeueFloor : INT
VAR
dequeuedFloor : INT;
END_VAR;
dequeuedFloor := queue[0];
queue[0] := queueDefaultValue;
ShiftQueueLeft();
DequeueFloor := dequeuedFloor;
END_FUNCTION
FUNCTION IsFloorAlreadyEnqueued : BOOL
VAR
index : INT;
END_VAR
VAR_INPUT
floor : INT;
END_VAR
IsFloorAlreadyEnqueued := FALSE;
FOR index := 0 TO queueSize - 1 DO
IF queue[index] = floor THEN
IsFloorAlreadyEnqueued := TRUE;
EXIT;
END_IF;
END_FOR;
END_FUNCTION
FUNCTION IsQueueEmpty : BOOL
VAR
index : INT;
empty : BOOL := TRUE;
END_VAR
FOR index := 0 TO queueSize - 1 DO
IF NOT queue[index] = queueDefaultValue THEN
empty := FALSE;
index := 1000;
END_IF;
END_FOR;
IsQueueEmpty := empty;
END_FUNCTION
FUNCTION BubbleSortQueueLower : BOOL
VAR
i : INT;
j : INT;
itemLeft : INT;
itemRight : INT;
temp : INT;
END_VAR
FOR i := 0 TO queueSize - 2 DO
FOR j := 0 TO queueSize - 2 DO
itemLeft := queueLowerFloors[j];
itemRight := queueLowerFloors[j + 1];
IF itemLeft < itemRight THEN
temp := queueLowerFloors[j];
queueLowerFloors[j] := queueLowerFloors[j + 1];
queueLowerFloors[j + 1] := temp;
END_IF;
END_FOR;
END_FOR;
END_FUNCTION
FUNCTION BubbleSortQueueUpper : BOOL
VAR
i : INT;
j : INT;
itemLeft : INT;
itemRight : INT;
temp : INT;
END_VAR
FOR i := 0 TO queueSize - 2 DO
FOR j := 0 TO queueSize - 2 DO
itemLeft := queueUpperFloors[j];
itemRight := queueUpperFloors[j + 1];
IF itemLeft < itemRight THEN
temp := queueUpperFloors[j];
queueUpperFloors[j] := queueUpperFloors[j + 1];
queueUpperFloors[j + 1] := temp;
END_IF;
END_FOR;
END_FOR;
END_FUNCTION
FUNCTION BubbleSortQueue : BOOL
VAR
i : INT;
j : INT;
itemLeft : INT;
itemRight : INT;
temp : INT;
END_VAR
FOR i := 0 TO queueSize - 2 DO
FOR j := 0 TO queueSize - 2 DO
itemLeft := queue[j];
itemRight := queue[j + 1];
IF itemLeft < itemRight THEN
temp := queue[j];
queue[j] := queue[j + 1];
queue[j + 1] := temp;
END_IF;
END_FOR;
END_FOR;
END_FUNCTION
FUNCTION ElevatorSortQueue : BOOL
VAR
index : INT;
item : INT;
index2 : INT;
changes : INT := 0;
END_VAR
FOR index := 0 TO queueSize - 1 DO
item := queue[index];
IF item > elevatorFloorStart THEN
EnqueueUpperFloor(item);
ELSIF item < elevatorFloorStart THEN
EnqueueLowerFloor(item);
END_IF;
END_FOR;
IF sortLowerFloors THEN BubbleSortQueueLower(); END_IF;
IF sortUpperFloors THEN BubbleSortQueueUpper(); END_IF;
FOR index := 0 TO queueSize - 1 DO
item := queueLowerFloors[index];
IF NOT item = queueDefaultValue THEN
queue[index] := item;
changes := changes + 1;
ELSE
EXIT;
END_IF;
END_FOR;
FOR index2 := 0 TO queueSize - 1 DO
item := queueUpperFloors[index2];
IF NOT item = queueDefaultValue THEN
queue[index2 + changes] := item;
ELSE
EXIT;
END_IF;
END_FOR;
EmptyUpperAndLowerQueue();
END_FUNCTION
(* End of queue code *)
FUNCTION IsAnyDoorOpened : BOOL
VAR
index: INT;
anyDoorOpened : BOOL := FALSE;
END_VAR
FOR index := 0 TO highestFloor - 1 DO
IF elevatorDoorsOpened[index] THEN
anyDoorOpened := TRUE;
ELSE
EXIT;
END_IF;
END_FOR;
IsAnyDoorOpened := anyDoorOpened;
END_FUNCTION
FUNCTION CloseAllDoors : BOOL
VAR
index : INT;
END_VAR
FOR index := 0 TO highestFloor - 1 DO
elevatorDoorsOpened[index] := FALSE;
END_FOR;
END_FUNCTION
FUNCTION CloseAllDoorsExceptForArg : BOOL
VAR
index : INT;
END_VAR
VAR_INPUT
floorDoorToOpen : INT;
END_VAR
FOR index := 0 TO highestFloor - 1 DO
IF index = floorDoorToOpen THEN
elevatorDoorsOpened[index] := TRUE;
ELSE
elevatorDoorsOpened[index] := FALSE;
END_IF;
END_FOR;
END_FUNCTION
FUNCTION HandleDoors : BOOL
IF forceOpenCurrentElevatorFloorDoor OR stopSignActivated THEN
elevatorDoorsOpened[elevatorFloor] := TRUE;
ELSIF elevatorDirection = 0 THEN
// open doors of the floor the elevator is at
CloseAllDoorsExceptForArg(elevatorFloor);
ELSE
CloseAllDoors();
END_IF;
END_FUNCTION
FUNCTION ResetAllButtons : BOOL
VAR
index : INT;
END_VAR
FOR index := 0 TO highestFloor - 1 DO
elevatorButtonsPressed[index] := FALSE;
END_FOR;
END_FUNCTION
FUNCTION HandleFloorSelection : BOOL
IF NOT elevatorFloor = targetFloor AND NOT IsFloorAlreadyEnqueued(targetFloor) THEN
EnqueueFloor(targetFloor);
floorSetAsElevStop[targetFloor] := TRUE;
pressedButtonsQueueDebug := pressedButtonsQueueDebug + INT_TO_STRING(targetFloor);
ELSE
elevatorDirectionIndicator := 1;
END_IF;
ResetAllButtons();
END_FUNCTION
FUNCTION IsAnyButtonPressed : BOOL
VAR
index : INT;
END_VAR;
FOR index := 0 TO highestFloor - 1 DO
IF elevatorButtonsPressed[index] THEN
anyFloorButtonPressed := TRUE;
IsAnyButtonPressed := TRUE;
END_IF;
END_FOR;
END_FUNCTION
FUNCTION HandleButtons : BOOL
VAR
index : INT;
END_VAR
IsAnyButtonPressed();
FOR index := 0 TO highestFloor - 1 DO
IF elevatorButtonsPressed[index] THEN
targetFloor := index;
HandleFloorSelection();
END_IF;
END_FOR;
END_FUNCTION
FUNCTION HandleMovement : BOOL
IF NOT stopSignActivated THEN
IF NOT queue[0] = elevatorFloor THEN
IF elevatorDirection = -1 THEN
elevatorFloor := elevatorFloor - 1;
ELSIF elevatorDirection = 1 THEN
elevatorFloor := elevatorFloor + 1;
END_IF;
HandleMovement := FALSE;
ELSE
floorSetAsElevStop[elevatorFloor] := FALSE;
queue[0] := queueDefaultValue;
ShiftQueueLeft();
elevatorDirection := 0;
HandleMovement := TRUE; // floor stop
END_IF;
ELSE
// obstacle detected, wait for doors
HandleMovement := TRUE;
END_IF;
END_FUNCTION
FUNCTION IsAnyObstaclePresent : BOOL
VAR
index : INT;
END_VAR
anyObstacleDetected := FALSE;
FOR index := 0 TO highestFloor - 1 DO
IF obstaclesBlockingDoors[index] OR obstacleElevator THEN
anyObstacleDetected := TRUE;
END_IF;
END_FOR;
END_FUNCTION
FUNCTION HandleStopConditions : BOOL
stopSignActivated :=
anyObstacleDetected
OR elevatorButtonStopPressed
OR elevatorWeight > elevatorMaximumWeight;
END_FUNCTION
PROGRAM prgMain
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
index : INT;
queuedFloor : INT;
floorDifference : INT;
anyDoorOpened : BOOL := FALSE;
END_VAR
VAR_TEMP
END_VAR
(* configuration *)
IF NOT configured THEN
FOR index := 0 TO queueSize - 1 DO
queue[index] := queueDefaultValue;
queueLowerFloors[index] := queueDefaultValue;
queueUpperFloors[index] := queueDefaultValue;
END_FOR;
elevatorDoorsOpened[elevatorFloor] := TRUE;
configured := TRUE;
END_IF;
IsAnyObstaclePresent();
HandleStopConditions();
HandleButtons();
IF NOT IsQueueEmpty() THEN
// store movement start floor - for queue sorting (option 2)
IF elevatorDirection = 0 THEN
elevatorFloorStart := elevatorFloor;
END_IF;
IF selectedSortOption = 1 THEN BubbleSortQueue();
ELSIF selectedSortOption = 2 THEN ElevatorSortQueue();
END_IF;
queuedFloor := queue[0];
floorDifference := elevatorFloor - queuedFloor;
IF floorDifference > 0 THEN
elevatorDirection := -1;
ELSE
elevatorDirection := 1;
END_IF;
END_IF;
VisualizeQueue();
HandleDoors();
elevatorDirectionIndicator := elevatorDirection + 1;
CASE switchCase OF
0:
timeDelayed := timePLC + waitTime;
switchCase := 1;
waitTime := elevatorFloorTravelTime;
1:
IF timeDelayed = timePLC THEN
IF NOT elevatorDirection = 0 THEN
anyDoorOpened := IsAnyDoorOpened();
IF NOT anyDoorOpened THEN
// floor stop
IF HandleMovement() THEN
// at floor queue[0] (first desired)
waitTime := elevatorFloorDoorsOpenTime;
forceOpenCurrentElevatorFloorDoor := TRUE;
ELSE
forceOpenCurrentElevatorFloorDoor := FALSE;
END_IF;
switchCase := 0;
ELSE
forceOpenCurrentElevatorFloorDoor := TRUE;
timeDelayed := timeDelayed + elevatorFloorDoorsOpenTime;
switchCase := 2;
END_IF;
END_IF;
END_IF;
2:
IF timeDelayed = timePLC THEN
forceOpenCurrentElevatorFloorDoor := FALSE;
switchCase := 0;
END_IF;
END_CASE;
END_PROGRAM