Wiki source code of Tutorial 3 - als
Last modified by Alexander Schulz-Rosengarten on 2025/01/30 12:05
Show last authors
author | version | line-number | content |
---|---|---|---|
1 | == T3A1: Round and Round! == | ||
2 | |||
3 | {{code title="SCCharts Header" linenumbers="true" language="cpp" collapse="true"}} | ||
4 | #include <stdio.h> | ||
5 | #include "railway.h" | ||
6 | #include "kicking.h" | ||
7 | #define NL "\n" | ||
8 | extern int second; | ||
9 | extern int contact[48][2]; | ||
10 | extern struct railway_system *railway; | ||
11 | int tick(); | ||
12 | int reset(); | ||
13 | {{/code}} | ||
14 | |||
15 | {{code title="Main.c" linenumbers="true" language="cpp" collapse="true"}} | ||
16 | #include <time.h> | ||
17 | #include "ControllerTick.h" | ||
18 | struct railway_system *railway; | ||
19 | int contact[48][2]; | ||
20 | int main(int argc, char *argv[]) | ||
21 | { | ||
22 | //initialize the railway system (and simulation) | ||
23 | railway = railway_initsystem(&kicking); | ||
24 | railway_openlinks_udp(railway,"node%02i","/dev/ttyS0"); | ||
25 | railway_startcontrol(railway,0,0); | ||
26 | |||
27 | reset(); | ||
28 | time_t t_new; | ||
29 | time_t t_old; | ||
30 | time(&t_old); | ||
31 | time(&t_new); | ||
32 | |||
33 | while(railway_alive(railway)) { | ||
34 | t_old = t_new; | ||
35 | time(&t_new); | ||
36 | |||
37 | if (t_new > t_old) { | ||
38 | second = 1; | ||
39 | } else { | ||
40 | second = 0; | ||
41 | } | ||
42 | //read contacts | ||
43 | int i; | ||
44 | for (i = 0; i < 48; i++) { | ||
45 | if (i != IC_JCT_0 && | ||
46 | i != IC_ST_0 && | ||
47 | i != IC_ST_4 && | ||
48 | i != KH_ST_0 && | ||
49 | i != KH_ST_6 && | ||
50 | i != OC_JCT_0 && | ||
51 | i != OC_ST_0 && | ||
52 | i != OC_ST_4) { //skip tracks with no contacts | ||
53 | contact[i][0] = getcontact(railway, i, 0, 0); | ||
54 | contact[i][1] = getcontact(railway, i, 1, 0); | ||
55 | } | ||
56 | } | ||
57 | tick(); | ||
58 | second = 0; | ||
59 | usleep(100); | ||
60 | } | ||
61 | // shut the system down | ||
62 | railway_stopcontrol(railway, 1); | ||
63 | railway_closelinks(railway); | ||
64 | railway_donesystem(railway); | ||
65 | return 0; | ||
66 | } | ||
67 | {{/code}} | ||
68 | |||
69 | {{code title="T3A1 SCChart" linenumbers="true" collapse="true"}} | ||
70 | scchart Task2Controller { | ||
71 | input bool second; | ||
72 | initial state leave_IC_ST_2_TO_IC_LN_0 { | ||
73 | entry / 'printf("leave_IC_ST_2_TO_IC_LN_0%s",NL)'; | ||
74 | entry / 'setsignal(railway, IC_ST_2, 1, GREEN)'; | ||
75 | entry / 'setpoint(railway, 23, BRANCH)'; | ||
76 | entry / 'setpoint(railway, 24, BRANCH)'; | ||
77 | entry / 'setpoint(railway, 29, STRAIGHT)'; | ||
78 | entry / 'settrack(railway, IC_ST_2, FWD, 100)'; | ||
79 | entry / 'settrack(railway, IC_ST_4, FWD, 100)'; | ||
80 | entry / 'settrack(railway, IC_LN_0, FWD, 100)'; | ||
81 | exit / 'settrack(railway, IC_ST_2, OFF, 0)'; | ||
82 | exit / 'setsignal(railway, IC_ST_2, 1, RED)'; | ||
83 | } | ||
84 | --> enter_IC_LN_0 with 'contact[IC_LN_0][0]'; | ||
85 | state enter_IC_LN_0 { | ||
86 | entry / 'printf("enter_IC_LN_0%s",NL)'; | ||
87 | } | ||
88 | --> travel_IC_LN_0 with 'contact[IC_LN_0][0]'; | ||
89 | state travel_IC_LN_0 { | ||
90 | entry / 'printf("travel_IC_LN_0%s",NL)'; | ||
91 | entry / 'settrack(railway, IC_ST_4, OFF, 0)'; | ||
92 | } | ||
93 | --> leave_IC_LN_0 with 'contact[IC_LN_0][1]'; | ||
94 | state leave_IC_LN_0 { | ||
95 | entry / 'printf("leave_IC_LN_0%s",NL)'; | ||
96 | entry / 'setsignal(railway, IC_LN_0, 1, GREEN)'; | ||
97 | entry / 'settrack(railway, IC_LN_0, FWD, 100)'; | ||
98 | entry / 'settrack(railway, IC_LN_1, FWD, 100)'; | ||
99 | exit / 'setsignal(railway, IC_LN_0, 1, RED)'; | ||
100 | } | ||
101 | --> enter_IC_LN_1 with 'contact[IC_LN_1][0]'; | ||
102 | state enter_IC_LN_1 { | ||
103 | entry / 'printf("enter_IC_LN_1%s",NL)'; | ||
104 | } | ||
105 | --> travel_IC_LN_1 with 'contact[IC_LN_1][0]'; | ||
106 | state travel_IC_LN_1 { | ||
107 | entry / 'printf("travel_IC_LN_1%s",NL)'; | ||
108 | entry / 'settrack(railway, IC_LN_0, OFF, 0)'; | ||
109 | } | ||
110 | --> leave_IC_LN_1 with 'contact[IC_LN_1][1]'; | ||
111 | state leave_IC_LN_1 { | ||
112 | entry / 'printf("leave_IC_LN_1%s",NL)'; | ||
113 | entry / 'setsignal(railway, IC_LN_1, 1, GREEN)'; | ||
114 | entry / 'settrack(railway, IC_LN_1, FWD, 100)'; | ||
115 | entry / 'settrack(railway, IC_LN_2, FWD, 100)'; | ||
116 | exit / 'setsignal(railway, IC_LN_1, 1, RED)'; | ||
117 | } | ||
118 | --> enter_IC_LN_2 with 'contact[IC_LN_2][0]'; | ||
119 | state enter_IC_LN_2 { | ||
120 | entry / 'printf("enter_IC_LN_2%s",NL)'; | ||
121 | } | ||
122 | --> travel_IC_LN_2 with 'contact[IC_LN_2][0]'; | ||
123 | state travel_IC_LN_2 { | ||
124 | entry / 'printf("travel_IC_LN_2%s",NL)'; | ||
125 | entry / 'settrack(railway, IC_LN_1, OFF, 0)'; | ||
126 | } | ||
127 | --> leave_IC_LN_2 with 'contact[IC_LN_2][1]'; | ||
128 | state leave_IC_LN_2 { | ||
129 | entry / 'printf("leave_IC_LN_2%s",NL)'; | ||
130 | entry / 'setsignal(railway, IC_LN_2, 1, GREEN)'; | ||
131 | entry / 'settrack(railway, IC_LN_2, FWD, 100)'; | ||
132 | entry / 'settrack(railway, IC_LN_3, FWD, 100)'; | ||
133 | exit / 'setsignal(railway, IC_LN_2, 1, RED)'; | ||
134 | } | ||
135 | --> enter_IC_LN_3 with 'contact[IC_LN_3][0]'; | ||
136 | state enter_IC_LN_3 { | ||
137 | entry / 'printf("enter_IC_LN_3%s",NL)'; | ||
138 | } | ||
139 | --> travel_IC_LN_3 with 'contact[IC_LN_3][0]'; | ||
140 | state travel_IC_LN_3 { | ||
141 | entry / 'printf("travel_IC_LN_3%s",NL)'; | ||
142 | entry / 'settrack(railway, IC_LN_2, OFF, 0)'; | ||
143 | } | ||
144 | --> leave_IC_LN_3 with 'contact[IC_LN_3][1]'; | ||
145 | state leave_IC_LN_3 { | ||
146 | entry / 'printf("leave_IC_LN_3%s",NL)'; | ||
147 | entry / 'setsignal(railway, IC_LN_3, 1, GREEN)'; | ||
148 | entry / 'settrack(railway, IC_LN_3, FWD, 100)'; | ||
149 | entry / 'settrack(railway, IC_LN_4, FWD, 100)'; | ||
150 | exit / 'setsignal(railway, IC_LN_3, 1, RED)'; | ||
151 | } | ||
152 | --> enter_IC_LN_4 with 'contact[IC_LN_4][0]'; | ||
153 | state enter_IC_LN_4 { | ||
154 | entry / 'printf("enter_IC_LN_4%s",NL)'; | ||
155 | } | ||
156 | --> travel_IC_LN_4 with 'contact[IC_LN_4][0]'; | ||
157 | state travel_IC_LN_4 { | ||
158 | entry / 'printf("travel_IC_LN_4%s",NL)'; | ||
159 | entry / 'settrack(railway, IC_LN_3, OFF, 0)'; | ||
160 | } | ||
161 | --> leave_IC_LN_4 with 'contact[IC_LN_4][1]'; | ||
162 | state leave_IC_LN_4 { | ||
163 | entry / 'printf("leave_IC_LN_4%s",NL)'; | ||
164 | entry / 'setsignal(railway, IC_LN_4, 1, GREEN)'; | ||
165 | entry / 'settrack(railway, IC_LN_4, FWD, 100)'; | ||
166 | entry / 'setpoint(railway, 11, STRAIGHT)'; | ||
167 | entry / 'setpoint(railway, 13, STRAIGHT)'; | ||
168 | entry / 'settrack(railway, IC_JCT_0, FWD, 100)'; | ||
169 | entry / 'settrack(railway, IC_LN_5, FWD, 100)'; | ||
170 | exit / 'setsignal(railway, IC_LN_4, 1, RED)'; | ||
171 | } | ||
172 | --> enter_IC_LN_5 with 'contact[IC_LN_5][0]'; | ||
173 | state enter_IC_LN_5 { | ||
174 | entry / 'printf("enter_IC_LN_5%s",NL)'; | ||
175 | } | ||
176 | --> travel_IC_LN_5 with 'contact[IC_LN_5][0]'; | ||
177 | state travel_IC_LN_5 { | ||
178 | entry / 'printf("travel_IC_LN_5%s",NL)'; | ||
179 | entry / 'settrack(railway, IC_LN_4, OFF, 0)'; | ||
180 | entry / 'settrack(railway, IC_JCT_0, OFF, 0)'; | ||
181 | } | ||
182 | --> leave_IC_LN_5_TO_IC_ST_2 with 'contact[IC_LN_5][1]'; | ||
183 | state leave_IC_LN_5_TO_IC_ST_2 { | ||
184 | entry / 'printf("leave_IC_LN_5_TO_IC_ST_2%s",NL)'; | ||
185 | entry / 'setsignal(railway, IC_LN_5, 1, GREEN)'; | ||
186 | entry / 'settrack(railway, IC_LN_5, FWD, 100)'; | ||
187 | entry / 'setpoint(railway, 18, STRAIGHT)'; | ||
188 | entry / 'setpoint(railway, 20, BRANCH)'; | ||
189 | entry / 'setpoint(railway, 19, BRANCH)'; | ||
190 | entry / 'settrack(railway, IC_ST_0, FWD, 100)'; | ||
191 | entry / 'settrack(railway, IC_ST_2, FWD, 100)'; | ||
192 | exit / 'setsignal(railway, IC_LN_5, 1, RED)'; | ||
193 | } | ||
194 | --> enter_IC_ST_2 with 'contact[IC_ST_2][0]'; | ||
195 | state enter_IC_ST_2 { | ||
196 | entry / 'printf("enter_IC_ST_2%s",NL)'; | ||
197 | entry / 'settrack(railway, IC_LN_5, OFF, 0)'; | ||
198 | entry / 'settrack(railway, IC_ST_0, FWD, 40)'; | ||
199 | entry / 'settrack(railway, IC_ST_2, FWD, 40)'; | ||
200 | } | ||
201 | --> travel_IC_ST_2 with 'contact[IC_ST_2][0]'; | ||
202 | state travel_IC_ST_2 { | ||
203 | entry / 'printf("travel_IC_ST_2%s",NL)'; | ||
204 | entry / 'settrack(railway, IC_ST_0, OFF, 0)'; | ||
205 | } | ||
206 | --> stop_and_wait_IC_ST_2 with 'contact[IC_ST_2][1]'; | ||
207 | state stop_and_wait_IC_ST_2 { | ||
208 | entry / 'printf("stop_and_wait_IC_ST_2%s",NL)'; | ||
209 | entry / 'settrack(railway, IC_ST_2, BRAKE, 0)'; | ||
210 | initial state wait_0 | ||
211 | --> wait_1 with second; | ||
212 | state wait_1 | ||
213 | --> wait_2 with second; | ||
214 | state wait_2 | ||
215 | --> wait_3 with second; | ||
216 | state wait_3 | ||
217 | --> wait_4 with second; | ||
218 | state wait_4 | ||
219 | --> wait_5 with second; | ||
220 | state wait_5 | ||
221 | --> wait_6 with second; | ||
222 | state wait_6 | ||
223 | --> wait_7 with second; | ||
224 | state wait_7 | ||
225 | --> wait_8 with second; | ||
226 | state wait_8 | ||
227 | --> wait_9 with second; | ||
228 | state wait_9 | ||
229 | --> wait_10 with second; | ||
230 | final state wait_10; | ||
231 | } | ||
232 | >-> leave_IC_ST_2_TO_IC_LN_0; | ||
233 | } | ||
234 | {{/code}} | ||
235 | |||
236 | Testet with simulation and real railway. | ||
237 | |||
238 | == T3A2: To boldly model where no one has modeled before... == | ||
239 | |||
240 | {{code title="T3A2 SCChart" linenumbers="true" collapse="true"}} | ||
241 | @VHLayout | ||
242 | scchart Task2Controller { | ||
243 | input bool second; | ||
244 | bool REQ_T1_IC_ST_0 = false; | ||
245 | bool REQ_T1_IC_ST_4 = false; | ||
246 | bool REQ_T1_IC_ST_2 = true; | ||
247 | bool PEM_T1_IC_ST_0 = false; | ||
248 | bool PEM_T1_IC_ST_4 = false; | ||
249 | bool PEM_T1_IC_ST_2 = true; | ||
250 | bool REQ_T2_IC_ST_0 = false; | ||
251 | bool REQ_T2_IC_ST_4 = false; | ||
252 | bool REQ_T2_IC_ST_2 = false; | ||
253 | bool PEM_T2_IC_ST_0 = false; | ||
254 | bool PEM_T2_IC_ST_4 = false; | ||
255 | bool PEM_T2_IC_ST_2 = false; | ||
256 | entry / 'setsignal(railway, -1, -1, RED)'; | ||
257 | region innerCircle_T1: | ||
258 | initial state leave_IC_ST_2_TO_IC_LN_0 { | ||
259 | entry / 'printf("leave_IC_ST_2_TO_IC_LN_0%s",NL)'; | ||
260 | entry / 'setsignal(railway, IC_ST_2, 1, GREEN)'; | ||
261 | entry / 'setpoint(railway, 23, BRANCH)'; | ||
262 | entry / 'setpoint(railway, 24, BRANCH)'; | ||
263 | entry / 'setpoint(railway, 29, STRAIGHT)'; | ||
264 | entry / 'settrack(railway, IC_ST_2, FWD, 100)'; | ||
265 | entry / 'settrack(railway, IC_ST_4, FWD, 100)'; | ||
266 | entry / 'settrack(railway, IC_LN_0, FWD, 100)'; | ||
267 | exit / 'settrack(railway, IC_ST_2, OFF, 0)'; | ||
268 | exit / REQ_T1_IC_ST_2 = false; | ||
269 | exit / 'setsignal(railway, IC_ST_2, 1, RED)'; | ||
270 | } | ||
271 | --> enter_IC_LN_0 with 'contact[IC_LN_0][0]'; | ||
272 | state enter_IC_LN_0 { | ||
273 | entry / 'printf("enter_IC_LN_0%s",NL)'; | ||
274 | } | ||
275 | --> travel_IC_LN_0 with 'contact[IC_LN_0][0]'; | ||
276 | state travel_IC_LN_0 { | ||
277 | entry / 'printf("travel_IC_LN_0%s",NL)'; | ||
278 | entry / 'settrack(railway, IC_ST_4, OFF, 0)'; | ||
279 | entry / REQ_T1_IC_ST_4 = false; | ||
280 | } | ||
281 | --> leave_IC_LN_0 with 'contact[IC_LN_0][1]'; | ||
282 | state leave_IC_LN_0 { | ||
283 | entry / 'printf("leave_IC_LN_0%s",NL)'; | ||
284 | entry / 'setsignal(railway, IC_LN_0, 1, GREEN)'; | ||
285 | entry / 'settrack(railway, IC_LN_0, FWD, 100)'; | ||
286 | entry / 'settrack(railway, IC_LN_1, FWD, 100)'; | ||
287 | exit / 'setsignal(railway, IC_LN_0, 1, RED)'; | ||
288 | } | ||
289 | --> enter_IC_LN_1 with 'contact[IC_LN_1][0]'; | ||
290 | state enter_IC_LN_1 { | ||
291 | entry / 'printf("enter_IC_LN_1%s",NL)'; | ||
292 | } | ||
293 | --> travel_IC_LN_1 with 'contact[IC_LN_1][0]'; | ||
294 | state travel_IC_LN_1 { | ||
295 | entry / 'printf("travel_IC_LN_1%s",NL)'; | ||
296 | entry / 'settrack(railway, IC_LN_0, OFF, 0)'; | ||
297 | } | ||
298 | --> leave_IC_LN_1 with 'contact[IC_LN_1][1]'; | ||
299 | state leave_IC_LN_1 { | ||
300 | entry / 'printf("leave_IC_LN_1%s",NL)'; | ||
301 | entry / 'setsignal(railway, IC_LN_1, 1, GREEN)'; | ||
302 | entry / 'settrack(railway, IC_LN_1, FWD, 100)'; | ||
303 | entry / 'settrack(railway, IC_LN_2, FWD, 100)'; | ||
304 | exit / 'setsignal(railway, IC_LN_1, 1, RED)'; | ||
305 | } | ||
306 | --> enter_IC_LN_2 with 'contact[IC_LN_2][0]'; | ||
307 | state enter_IC_LN_2 { | ||
308 | entry / 'printf("enter_IC_LN_2%s",NL)'; | ||
309 | } | ||
310 | --> travel_IC_LN_2 with 'contact[IC_LN_2][0]'; | ||
311 | state travel_IC_LN_2 { | ||
312 | entry / 'printf("travel_IC_LN_2%s",NL)'; | ||
313 | entry / 'settrack(railway, IC_LN_1, OFF, 0)'; | ||
314 | } | ||
315 | --> leave_IC_LN_2 with 'contact[IC_LN_2][1]'; | ||
316 | state leave_IC_LN_2 { | ||
317 | entry / 'printf("leave_IC_LN_2%s",NL)'; | ||
318 | entry / 'setsignal(railway, IC_LN_2, 1, GREEN)'; | ||
319 | entry / 'settrack(railway, IC_LN_2, FWD, 100)'; | ||
320 | entry / 'settrack(railway, IC_LN_3, FWD, 100)'; | ||
321 | exit / 'setsignal(railway, IC_LN_2, 1, RED)'; | ||
322 | } | ||
323 | --> enter_IC_LN_3 with 'contact[IC_LN_3][0]'; | ||
324 | state enter_IC_LN_3 { | ||
325 | entry / 'printf("enter_IC_LN_3%s",NL)'; | ||
326 | } | ||
327 | --> travel_IC_LN_3 with 'contact[IC_LN_3][0]'; | ||
328 | state travel_IC_LN_3 { | ||
329 | entry / 'printf("travel_IC_LN_3%s",NL)'; | ||
330 | entry / 'settrack(railway, IC_LN_2, OFF, 0)'; | ||
331 | } | ||
332 | --> leave_IC_LN_3 with 'contact[IC_LN_3][1]'; | ||
333 | state leave_IC_LN_3 { | ||
334 | entry / 'printf("leave_IC_LN_3%s",NL)'; | ||
335 | entry / 'setsignal(railway, IC_LN_3, 1, GREEN)'; | ||
336 | entry / 'settrack(railway, IC_LN_3, FWD, 100)'; | ||
337 | entry / 'settrack(railway, IC_LN_4, FWD, 100)'; | ||
338 | exit / 'setsignal(railway, IC_LN_3, 1, RED)'; | ||
339 | } | ||
340 | --> enter_IC_LN_4 with 'contact[IC_LN_4][0]'; | ||
341 | state enter_IC_LN_4 { | ||
342 | entry / 'printf("enter_IC_LN_4%s",NL)'; | ||
343 | } | ||
344 | --> travel_IC_LN_4 with 'contact[IC_LN_4][0]'; | ||
345 | state travel_IC_LN_4 { | ||
346 | entry / 'printf("travel_IC_LN_4%s",NL)'; | ||
347 | entry / 'settrack(railway, IC_LN_3, OFF, 0)'; | ||
348 | } | ||
349 | --> leave_IC_LN_4 with 'contact[IC_LN_4][1]'; | ||
350 | state leave_IC_LN_4 { | ||
351 | entry / 'printf("leave_IC_LN_4%s",NL)'; | ||
352 | entry / 'setsignal(railway, IC_LN_4, 1, GREEN)'; | ||
353 | entry / 'settrack(railway, IC_LN_4, FWD, 100)'; | ||
354 | entry / 'setpoint(railway, 11, STRAIGHT)'; | ||
355 | entry / 'setpoint(railway, 13, STRAIGHT)'; | ||
356 | entry / 'settrack(railway, IC_JCT_0, FWD, 100)'; | ||
357 | entry / 'settrack(railway, IC_LN_5, FWD, 100)'; | ||
358 | exit / 'setsignal(railway, IC_LN_4, 1, RED)'; | ||
359 | } | ||
360 | --> enter_IC_LN_5 with 'contact[IC_LN_5][0]'; | ||
361 | state enter_IC_LN_5 { | ||
362 | entry / 'printf("enter_IC_LN_5%s",NL)'; | ||
363 | } | ||
364 | --> travel_IC_LN_5 with 'contact[IC_LN_5][0]'; | ||
365 | state travel_IC_LN_5 { | ||
366 | entry / 'printf("travel_IC_LN_5%s",NL)'; | ||
367 | entry / 'settrack(railway, IC_LN_4, OFF, 0)'; | ||
368 | entry / 'settrack(railway, IC_JCT_0, OFF, 0)'; | ||
369 | } | ||
370 | --> try_leave_IC_LN_5_TO_IC_ST_2 with 'contact[IC_LN_5][1]'; | ||
371 | state try_leave_IC_LN_5_TO_IC_ST_2 { | ||
372 | entry / REQ_T1_IC_ST_0 = true; | ||
373 | entry / REQ_T1_IC_ST_2 = true; | ||
374 | entry / 'printf("try_leave_IC_LN_5_TO_IC_ST_2%s",NL)'; | ||
375 | } | ||
376 | --> leave_IC_LN_5_TO_IC_ST_2 immediate with PEM_T1_IC_ST_0 && PEM_T1_IC_ST_2 | ||
377 | --> wait_leave_IC_LN_5_TO_IC_ST_2 immediate; | ||
378 | state wait_leave_IC_LN_5_TO_IC_ST_2 { | ||
379 | entry / 'printf("wait_leave_IC_LN_5_TO_IC_ST_2%s",NL)'; | ||
380 | entry / 'settrack(railway, IC_LN_5, BRAKE, 0)'; | ||
381 | } | ||
382 | --> leave_IC_LN_5_TO_IC_ST_2 with PEM_T1_IC_ST_0 && PEM_T1_IC_ST_2; | ||
383 | state leave_IC_LN_5_TO_IC_ST_2 { | ||
384 | entry / 'printf("leave_IC_LN_5_TO_IC_ST_2%s",NL)'; | ||
385 | entry / 'setsignal(railway, IC_LN_5, 1, GREEN)'; | ||
386 | entry / 'settrack(railway, IC_LN_5, FWD, 100)'; | ||
387 | entry / 'setpoint(railway, 18, STRAIGHT)'; | ||
388 | entry / 'setpoint(railway, 20, BRANCH)'; | ||
389 | entry / 'setpoint(railway, 19, BRANCH)'; | ||
390 | entry / 'settrack(railway, IC_ST_0, FWD, 100)'; | ||
391 | entry / 'settrack(railway, IC_ST_2, FWD, 100)'; | ||
392 | exit / 'setsignal(railway, IC_LN_5, 1, RED)'; | ||
393 | } | ||
394 | --> enter_IC_ST_2 with 'contact[IC_ST_2][0]'; | ||
395 | state enter_IC_ST_2 { | ||
396 | entry / 'printf("enter_IC_ST_2%s",NL)'; | ||
397 | entry / 'settrack(railway, IC_LN_5, OFF, 0)'; | ||
398 | entry / 'settrack(railway, IC_ST_0, FWD, 40)'; | ||
399 | entry / 'settrack(railway, IC_ST_2, FWD, 40)'; | ||
400 | } | ||
401 | --> travel_IC_ST_2 with 'contact[IC_ST_2][0]'; | ||
402 | state travel_IC_ST_2 { | ||
403 | entry / 'printf("travel_IC_ST_2%s",NL)'; | ||
404 | entry / 'settrack(railway, IC_ST_0, OFF, 0)'; | ||
405 | entry / REQ_T1_IC_ST_0 = false; | ||
406 | } | ||
407 | --> stop_and_wait_IC_ST_2 with 'contact[IC_ST_2][1]'; | ||
408 | state stop_and_wait_IC_ST_2 { | ||
409 | entry / 'printf("stop_and_wait_IC_ST_2%s",NL)'; | ||
410 | entry / 'settrack(railway, IC_ST_2, BRAKE, 0)'; | ||
411 | initial state wait_0 | ||
412 | --> wait_1 with second; | ||
413 | state wait_1 | ||
414 | --> wait_2 with second; | ||
415 | state wait_2 | ||
416 | --> wait_3 with second; | ||
417 | state wait_3 | ||
418 | --> wait_4 with second; | ||
419 | state wait_4 | ||
420 | --> wait_5 with second; | ||
421 | final state wait_5; | ||
422 | } | ||
423 | >-> try_leave_IC_ST_2_TO_IC_LN_0; | ||
424 | state try_leave_IC_ST_2_TO_IC_LN_0 { | ||
425 | entry / REQ_T1_IC_ST_4 = true; | ||
426 | entry / 'printf("try_leave_IC_ST_2_TO_IC_LN_0%s",NL)'; | ||
427 | } | ||
428 | --> leave_IC_ST_2_TO_IC_LN_0 immediate with PEM_T1_IC_ST_4 | ||
429 | --> wait_leave_IC_ST_2_TO_IC_LN_0 immediate; | ||
430 | state wait_leave_IC_ST_2_TO_IC_LN_0 { | ||
431 | entry / 'printf("wait_leave_IC_ST_2_TO_IC_LN_0%s",NL)'; | ||
432 | entry / 'settrack(railway, IC_ST_2, BRAKE, 0)'; | ||
433 | } | ||
434 | --> leave_IC_ST_2_TO_IC_LN_0 with PEM_T1_IC_ST_4; | ||
435 | region kicking_T2: //--KICKING-- | ||
436 | initial state leave_KH_ST_3_TO_KIO_LN_0 { | ||
437 | entry / 'printf("leave_KH_ST_3_TO_KIO_LN_0%s",NL)'; | ||
438 | entry / 'setsignal(railway, KH_ST_3, 0, GREEN)'; | ||
439 | entry / 'setpoint(railway, 0, BRANCH)'; | ||
440 | entry / 'setpoint(railway, 1, BRANCH)'; | ||
441 | entry / 'setpoint(railway, 2, BRANCH)'; | ||
442 | entry / 'setpoint(railway, 3, BRANCH)'; | ||
443 | entry / 'settrack(railway, KH_ST_3, REV, 100)'; | ||
444 | entry / 'settrack(railway, KH_ST_0, REV, 100)'; | ||
445 | entry / 'settrack(railway, KIO_LN_0, REV, 100)'; | ||
446 | exit / 'settrack(railway, KH_ST_3, OFF, 0)'; | ||
447 | exit / 'setsignal(railway, KH_ST_3, 0, RED)'; | ||
448 | } | ||
449 | --> enter_KIO_LN_0 with 'contact[KIO_LN_0][1]'; | ||
450 | state enter_KIO_LN_0 { | ||
451 | entry / 'printf("enter_KIO_LN_0%s",NL)'; | ||
452 | } | ||
453 | --> travel_KIO_LN_0 with 'contact[KIO_LN_0][1]'; | ||
454 | state travel_KIO_LN_0 { | ||
455 | entry / 'printf("travel_KIO_LN_0%s",NL)'; | ||
456 | entry / 'settrack(railway, KH_ST_0, OFF, 0)'; | ||
457 | } | ||
458 | --> try_leave_KIO_LN_0_TO_IC_ST_2 with 'contact[KIO_LN_0][0]'; | ||
459 | state try_leave_KIO_LN_0_TO_IC_ST_2 { | ||
460 | entry / 'printf("try_leave_KIO_LN_0_TO_IC_ST_2%s",NL)'; | ||
461 | entry / REQ_T2_IC_ST_0 = true; | ||
462 | entry / REQ_T2_IC_ST_2 = true; | ||
463 | } | ||
464 | --> leave_KIO_LN_0_TO_IC_ST_2 immediate with PEM_T2_IC_ST_0 && PEM_T2_IC_ST_2 | ||
465 | --> wait_leave_KIO_LN_0_TO_IC_ST_2 immediate; | ||
466 | state wait_leave_KIO_LN_0_TO_IC_ST_2 { | ||
467 | entry / 'printf("wait_leave_KIO_LN_0_TO_IC_ST_2%s",NL)'; | ||
468 | entry / 'settrack(railway, KIO_LN_0, BRAKE, 0)'; | ||
469 | } | ||
470 | --> leave_KIO_LN_0_TO_IC_ST_2 with PEM_T2_IC_ST_0 && PEM_T2_IC_ST_2; | ||
471 | state leave_KIO_LN_0_TO_IC_ST_2 { | ||
472 | entry / 'printf("leave_KIO_LN_0_TO_IC_ST_2%s",NL)'; | ||
473 | entry / 'setsignal(railway, KIO_LN_0, 0, GREEN)'; | ||
474 | entry / 'settrack(railway, KIO_LN_0, REV, 100)'; | ||
475 | entry / 'setpoint(railway, 16, BRANCH)'; | ||
476 | entry / 'setpoint(railway, 17, BRANCH)'; | ||
477 | entry / 'setpoint(railway, 18, BRANCH)'; | ||
478 | entry / 'setpoint(railway, 19, BRANCH)'; | ||
479 | entry / 'setpoint(railway, 20, BRANCH)'; | ||
480 | entry / 'settrack(railway, KIO_LN_0, REV, 100)'; | ||
481 | entry / 'settrack(railway, OC_ST_4, REV, 100)'; | ||
482 | entry / 'settrack(railway, IC_ST_0, FWD, 100)'; | ||
483 | entry / 'settrack(railway, IC_ST_2, FWD, 100)'; | ||
484 | exit / 'setsignal(railway, KIO_LN_0, 0, RED)'; | ||
485 | } | ||
486 | --> enter_IC_ST_2 with 'contact[IC_ST_2][0]'; | ||
487 | state enter_IC_ST_2 { | ||
488 | entry / 'printf("enter_IC_ST_2%s",NL)'; | ||
489 | entry / 'settrack(railway, KIO_LN_0, OFF, 0)'; | ||
490 | entry / 'settrack(railway, OC_ST_4, OFF, 0)'; | ||
491 | entry / 'settrack(railway, IC_ST_0, FWD, 40)'; | ||
492 | entry / 'settrack(railway, IC_ST_2, FWD, 40)'; | ||
493 | } | ||
494 | --> travel_IC_ST_2 with 'contact[IC_ST_2][0]'; | ||
495 | state travel_IC_ST_2 { | ||
496 | entry / 'printf("travel_IC_ST_2%s",NL)'; | ||
497 | entry / 'settrack(railway, IC_ST_0, OFF, 0)'; | ||
498 | entry / REQ_T2_IC_ST_0 = false; | ||
499 | } | ||
500 | --> stop_and_wait_IC_ST_2 with 'contact[IC_ST_2][1]'; | ||
501 | state stop_and_wait_IC_ST_2 { | ||
502 | entry / 'printf("stop_and_wait_IC_ST_2%s",NL)'; | ||
503 | entry / 'settrack(railway, IC_ST_2, BRAKE, 0)'; | ||
504 | initial state wait_0 | ||
505 | --> wait_1 with second; | ||
506 | state wait_1 | ||
507 | --> wait_2 with second; | ||
508 | state wait_2 | ||
509 | --> wait_3 with second; | ||
510 | state wait_3 | ||
511 | --> wait_4 with second; | ||
512 | state wait_4 | ||
513 | --> wait_5 with second; | ||
514 | final state wait_5; | ||
515 | } | ||
516 | >-> try_leave_IC_ST_2_TO_KIO_LN_1; | ||
517 | state try_leave_IC_ST_2_TO_KIO_LN_1 { | ||
518 | entry / REQ_T2_IC_ST_4 = true; | ||
519 | entry / 'printf("try_leave_IC_ST_2_TO_KIO_LN_1%s",NL)'; | ||
520 | } | ||
521 | --> leave_IC_ST_2_TO_KIO_LN_1 immediate with PEM_T2_IC_ST_4 | ||
522 | --> wait_leave_IC_ST_2_TO_KIO_LN_1 immediate; | ||
523 | state wait_leave_IC_ST_2_TO_KIO_LN_1 { | ||
524 | entry / 'printf("wait_leave_IC_ST_2_TO_KIO_LN_1%s",NL)'; | ||
525 | entry / 'settrack(railway, IC_ST_2, BRAKE, 0)'; | ||
526 | } | ||
527 | --> leave_IC_ST_2_TO_KIO_LN_1 with PEM_T2_IC_ST_4; | ||
528 | state leave_IC_ST_2_TO_KIO_LN_1 { | ||
529 | entry / 'printf("leave_IC_ST_2_TO_KIO_LN_1%s",NL)'; | ||
530 | entry / 'setsignal(railway, IC_ST_2, 1, GREEN)'; | ||
531 | entry / 'setpoint(railway, 23, BRANCH)'; | ||
532 | entry / 'setpoint(railway, 24, BRANCH)'; | ||
533 | entry / 'setpoint(railway, 29, BRANCH)'; | ||
534 | entry / 'setpoint(railway, 27, STRAIGHT)'; | ||
535 | entry / 'setpoint(railway, 28, STRAIGHT)'; | ||
536 | entry / 'settrack(railway, IC_ST_2, FWD, 100)'; | ||
537 | entry / 'settrack(railway, IC_ST_4, FWD, 100)'; | ||
538 | entry / 'settrack(railway, OC_ST_0, REV, 100)'; | ||
539 | entry / 'settrack(railway, KIO_LN_1, REV, 100)'; | ||
540 | exit / 'settrack(railway, IC_ST_2, OFF, 0)'; | ||
541 | exit / REQ_T2_IC_ST_2 = false; | ||
542 | exit / 'setsignal(railway, IC_ST_2, 1, RED)'; | ||
543 | } | ||
544 | --> enter_KIO_LN_1 with 'contact[KIO_LN_1][1]'; | ||
545 | state enter_KIO_LN_1 { | ||
546 | entry / 'printf("enter_KIO_LN_1%s",NL)'; | ||
547 | } | ||
548 | --> travel_KIO_LN_1 with 'contact[KIO_LN_1][1]'; | ||
549 | state travel_KIO_LN_1 { | ||
550 | entry / 'printf("travel_KIO_LN_1%s",NL)'; | ||
551 | entry / 'settrack(railway, IC_ST_4, OFF, 0)'; | ||
552 | entry / 'settrack(railway, OC_ST_0, OFF, 0)'; | ||
553 | entry / REQ_T2_IC_ST_4 = false; | ||
554 | } | ||
555 | --> leave_KIO_LN_1_TO_KH_ST_3 with 'contact[KIO_LN_1][0]'; | ||
556 | state leave_KIO_LN_1_TO_KH_ST_3 { | ||
557 | entry / 'printf("leave_KIO_LN_1_TO_KH_ST_3%s",NL)'; | ||
558 | entry / 'setsignal(railway, KIO_LN_1, 0, GREEN)'; | ||
559 | entry / 'setpoint(railway, 9, BRANCH)'; | ||
560 | entry / 'setpoint(railway, 8, BRANCH)'; | ||
561 | entry / 'setpoint(railway, 7, BRANCH)'; | ||
562 | entry / 'setpoint(railway, 6, BRANCH)'; | ||
563 | entry / 'settrack(railway, KIO_LN_1, REV, 100)'; | ||
564 | entry / 'settrack(railway, KH_ST_6, REV, 100)'; | ||
565 | entry / 'settrack(railway, KH_ST_3, REV, 100)'; | ||
566 | exit / 'setsignal(railway, KIO_LN_1, 0, RED)'; | ||
567 | } | ||
568 | --> enter_KH_ST_3 with 'contact[KH_ST_3][1]'; | ||
569 | state enter_KH_ST_3 { | ||
570 | entry / 'printf("enter_KH_ST_3%s",NL)'; | ||
571 | entry / 'settrack(railway, KIO_LN_1, OFF, 0)'; | ||
572 | entry / 'settrack(railway, KH_ST_6, REV, 40)'; | ||
573 | entry / 'settrack(railway, KH_ST_3, REV, 40)'; | ||
574 | } | ||
575 | --> travel_KH_ST_3 with 'contact[KH_ST_3][1]'; | ||
576 | state travel_KH_ST_3 { | ||
577 | entry / 'printf("travel_KH_ST_3%s",NL)'; | ||
578 | entry / 'settrack(railway, KH_ST_6, OFF, 0)'; | ||
579 | } | ||
580 | --> stop_and_wait_KH_ST_3 with 'contact[KH_ST_3][0]'; | ||
581 | state stop_and_wait_KH_ST_3 { | ||
582 | entry / 'printf("stop_and_wait_KH_ST_3%s",NL)'; | ||
583 | entry / 'settrack(railway, KH_ST_3, BRAKE, 0)'; | ||
584 | initial state wait_0 | ||
585 | --> wait_1 with second; | ||
586 | state wait_1 | ||
587 | --> wait_2 with second; | ||
588 | state wait_2 | ||
589 | --> wait_3 with second; | ||
590 | state wait_3 | ||
591 | --> wait_4 with second; | ||
592 | state wait_4 | ||
593 | --> wait_5 with second; | ||
594 | final state wait_5; | ||
595 | } | ||
596 | >-> leave_KH_ST_3_TO_KIO_LN_0; | ||
597 | region Mutual_Exclusion_Handler: | ||
598 | initial state lock_IC_ST_0 | ||
599 | //hold lock | ||
600 | --> lock_IC_ST_2 immediate with REQ_T1_IC_ST_0 && PEM_T1_IC_ST_0 / PEM_T1_IC_ST_0 = true | ||
601 | --> lock_IC_ST_2 immediate with REQ_T2_IC_ST_0 && PEM_T2_IC_ST_0 / PEM_T2_IC_ST_0 = true | ||
602 | //switch lock | ||
603 | --> lock_IC_ST_2 immediate with !REQ_T1_IC_ST_0 && PEM_T1_IC_ST_0 && REQ_T2_IC_ST_0 / PEM_T1_IC_ST_0 = false; PEM_T2_IC_ST_0 = true | ||
604 | --> lock_IC_ST_2 immediate with !REQ_T2_IC_ST_0 && PEM_T2_IC_ST_0 && REQ_T1_IC_ST_0 / PEM_T1_IC_ST_0 = true; PEM_T2_IC_ST_0 = false | ||
605 | //take lock | ||
606 | --> lock_IC_ST_2 immediate with REQ_T1_IC_ST_0 && !PEM_T1_IC_ST_0 / PEM_T1_IC_ST_0 = true | ||
607 | --> lock_IC_ST_2 immediate with REQ_T2_IC_ST_0 && !PEM_T2_IC_ST_0 / PEM_T2_IC_ST_0 = true | ||
608 | //release | ||
609 | --> lock_IC_ST_2 immediate with !REQ_T1_IC_ST_0 && PEM_T1_IC_ST_0 / PEM_T1_IC_ST_0 = false | ||
610 | --> lock_IC_ST_2 immediate with !REQ_T2_IC_ST_0 && PEM_T2_IC_ST_0 / PEM_T2_IC_ST_0 = false | ||
611 | //change nothing | ||
612 | --> lock_IC_ST_2 immediate; | ||
613 | state lock_IC_ST_2 | ||
614 | //hold lock | ||
615 | --> lock_IC_ST_4 immediate with REQ_T1_IC_ST_2 && PEM_T1_IC_ST_2 / PEM_T1_IC_ST_2 = true | ||
616 | --> lock_IC_ST_4 immediate with REQ_T2_IC_ST_2 && PEM_T2_IC_ST_2 / PEM_T2_IC_ST_2 = true | ||
617 | //switch lock | ||
618 | --> lock_IC_ST_4 immediate with !REQ_T1_IC_ST_2 && PEM_T1_IC_ST_2 && REQ_T2_IC_ST_2 / PEM_T1_IC_ST_2 = false; PEM_T2_IC_ST_2 = true | ||
619 | --> lock_IC_ST_4 immediate with !REQ_T2_IC_ST_2 && PEM_T2_IC_ST_2 && REQ_T1_IC_ST_2 / PEM_T1_IC_ST_2 = true; PEM_T2_IC_ST_2 = false | ||
620 | //take lock | ||
621 | --> lock_IC_ST_4 immediate with REQ_T1_IC_ST_2 && !PEM_T1_IC_ST_2 / PEM_T1_IC_ST_2 = true | ||
622 | --> lock_IC_ST_4 immediate with REQ_T2_IC_ST_2 && !PEM_T2_IC_ST_2 / PEM_T2_IC_ST_2 = true | ||
623 | //release | ||
624 | --> lock_IC_ST_4 immediate with !REQ_T1_IC_ST_2 && PEM_T1_IC_ST_2 / PEM_T1_IC_ST_2 = false | ||
625 | --> lock_IC_ST_4 immediate with !REQ_T2_IC_ST_2 && PEM_T2_IC_ST_2 / PEM_T2_IC_ST_2 = false | ||
626 | //change nothing | ||
627 | --> lock_IC_ST_4 immediate; | ||
628 | state lock_IC_ST_4 | ||
629 | //hold lock | ||
630 | --> redo immediate with REQ_T1_IC_ST_4 && PEM_T1_IC_ST_4 / PEM_T1_IC_ST_4 = true | ||
631 | --> redo immediate with REQ_T2_IC_ST_4 && PEM_T2_IC_ST_4 / PEM_T2_IC_ST_4 = true | ||
632 | //switch lock | ||
633 | --> redo immediate with !REQ_T1_IC_ST_4 && PEM_T1_IC_ST_4 && REQ_T2_IC_ST_4 / PEM_T1_IC_ST_4 = false; PEM_T2_IC_ST_4 = true | ||
634 | --> redo immediate with !REQ_T2_IC_ST_4 && PEM_T2_IC_ST_4 && REQ_T1_IC_ST_4 / PEM_T1_IC_ST_4 = true; PEM_T2_IC_ST_4 = false | ||
635 | //take lock | ||
636 | --> redo immediate with REQ_T1_IC_ST_4 && !PEM_T1_IC_ST_4 / PEM_T1_IC_ST_4 = true | ||
637 | --> redo immediate with REQ_T2_IC_ST_4 && !PEM_T2_IC_ST_4 / PEM_T2_IC_ST_4 = true | ||
638 | //release | ||
639 | --> redo immediate with !REQ_T1_IC_ST_4 && PEM_T1_IC_ST_4 / PEM_T1_IC_ST_4 = false | ||
640 | --> redo immediate with !REQ_T2_IC_ST_4 && PEM_T2_IC_ST_4 / PEM_T2_IC_ST_4 = false | ||
641 | //change nothing | ||
642 | --> redo immediate; | ||
643 | state redo | ||
644 | --> lock_IC_ST_0; | ||
645 | } | ||
646 | {{/code}} | ||
647 | |||
648 | Untested due to tool restrictions. | ||
649 | |||
650 | == T3A3: Important Thoughts == | ||
651 | |||
652 | 1. Modules | ||
653 | 1*. Encapsulation of functionality | ||
654 | 1*. Separation of modules in single files | ||
655 | 1*. Re-usability | ||
656 | 1*. Customizability by module parameters | ||
657 | 1. Arrays | ||
658 | 1*. Arrays of SCCharts variables | ||
659 | 1*. correct dependency detection? | ||
660 | 1**. handling the complete array as one variable may cause numerous w-w-dependencies | ||
661 | 1**. requiring constant indices will undo advantages (variable index) of arrays | ||
662 | hostcode indices may be hart to compute but would be nice. e.g. is_free[IC_LN_3] | ||
663 | 1. Scheduling constraints | ||
664 | 1*. Ability to exclude some variables from dependency calculations or setting constraints | ||
665 | 1*. Overcome conservative scheduler and allow semantically excluded parallel writes | ||
666 | 1*. Simplifies implementation of mutual exclusion |