Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1655 | giacomo | 1 | /*************************************************************************** |
2 | ************************************************************************** |
||
3 | *** Universita' di Pavia *** |
||
4 | *** Corso : Informatoca Industriale *** |
||
5 | ************************************************************************** |
||
6 | *** Progetto : MONITORAGGIO AUTOSTRADA *** |
||
7 | ************************************************************************** |
||
8 | *** Realizzato da : Nino Verzellesi e Quadrubbi Giacomo *** |
||
9 | ************************************************************************** |
||
10 | ***************************************************************************/ |
||
11 | |||
12 | |||
13 | /* ----------------------------------------------------------------------------- */ |
||
14 | |||
15 | #include <kernel/kern.h> |
||
16 | #include <drivers/glib.h> |
||
17 | #include <drivers/keyb.h> |
||
18 | #include <semaphore.h> |
||
19 | #include <stdlib.h> |
||
20 | #include <math.h> |
||
21 | |||
22 | /* ----------------------------------------------------------------------------- */ |
||
23 | |||
24 | |||
25 | /********************* DEFINIZIONE DELLE COSTANTI **************************/ |
||
26 | |||
27 | #define ESC 27 /* codice ASCII del tasto ESCAPE */ |
||
28 | #define MAX_V 35 /* massimo numero di veicoli */ |
||
29 | #define GRUPPO 1 |
||
30 | #define LUNGCAMION 40 /* lunghezza del camion */ |
||
31 | #define LARGCAMION 10 /* larghezza del camion */ |
||
32 | #define LUNGLENTA 16 /* lunghezza della macchina lenta */ |
||
33 | #define LARGLENTA 8 /* larghezza della macchina lenta */ |
||
34 | #define LUNGVELOCE 20 /* lunghezza della macchina veloce */ |
||
35 | #define LARGVELOCE 8 /* larghezza della macchina veloce */ |
||
36 | #define DT 0.04 /* passo del campionamento */ |
||
37 | #define CENTROCORSIA1 477 /* coordinata del centro della corsia 1 */ |
||
38 | #define CENTROCORSIA2 459 /* coordinata del centro della corsia 2 */ |
||
39 | #define CENTROCARREGGIATA 469 /* coordinata del centro della carreggiata */ |
||
40 | |||
41 | |||
42 | /* ----------------------------------------------------------------------------- */ |
||
43 | |||
44 | |||
45 | /****************** DEFINIZIONE DELLE VARIABILI GLOBALI ********************/ |
||
46 | |||
47 | double tick = 1.0; /* system tick = 1 ms */ |
||
48 | int periodo = 40000; /* periodo */ |
||
49 | int wcet = 1000; /* deadline */ |
||
50 | PID pid; |
||
51 | sem_t mutex; /* semaforo per la grafica */ |
||
52 | sem_t strada; /* semaforo per le variabili corsia1 e corsia2 */ |
||
53 | int MAX_X; /* dimensione x della modalita' di visualizzazione dello schermo */ |
||
54 | int MAX_Y; /* dimensione y della modalita' di visualizzazione dello schermo */ |
||
55 | short corsia1[40000]; /* vettore della corsia1 */ |
||
56 | short corsia2[40000]; /* vettore della corsia2 */ |
||
57 | int xelic; /* cordinata dell'elicottero */ |
||
58 | char c; /* carattere da tastiera */ |
||
59 | |||
60 | |||
61 | /* ----------------------------------------------------------------------------- */ |
||
62 | |||
63 | |||
64 | /****************** FUNZIONE CHE DISEGNA I VEICOLI *************************/ |
||
65 | |||
66 | void draw_veicolo(int x, int y, int colore,int lunghezza,int larghezza) |
||
67 | { |
||
68 | int u; /* indice di ciclo */ |
||
69 | int v; /* variabile ausiliaria per la ricostruzione della segnaletica */ |
||
70 | int xreal; /* coordinata di fine veicolo */ |
||
71 | |||
72 | xreal=x-lunghezza; /* calcola la coordinata di fine veicolo */ |
||
73 | if (xreal<0) /* la pone a zero nel caso in cui sia minore di zero (veicolo non ancora interamente entrato in autostrada) */ |
||
74 | xreal=0; |
||
75 | |||
76 | /* disegna il veicolo nella posizione indicata e con il colore indicato */ |
||
77 | sem_wait(&mutex); |
||
78 | grx_box(xreal,(int)(y-larghezza/2),x,(int)(y+larghezza/2),colore); |
||
79 | sem_post(&mutex); |
||
80 | |||
81 | /* ricostruisce la segnaletica orrizzontale della strada nel caso in cui si sta' cancellando il veicolo dalla posizione precedente (ridisegna solo quella parte che e' stata cancellata) */ |
||
82 | if (colore==0) |
||
83 | for (u=xreal;u<x;u++) |
||
84 | { |
||
85 | v=u%8; |
||
86 | if ((v==0) || (v==1)) |
||
87 | { |
||
88 | sem_wait(&mutex); |
||
89 | grx_plot(u,CENTROCARREGGIATA,rgb16(255,255,255)); |
||
90 | sem_post(&mutex); |
||
91 | } |
||
92 | } |
||
93 | } |
||
94 | |||
95 | |||
96 | /* ----------------------------------------------------------------------------- */ |
||
97 | |||
98 | |||
99 | /** FUNZIONE CHE CALCOLA LA DISTANZA DAL VEICOLO CHE PRECEDE SULLA CORSIA **/ |
||
100 | |||
101 | int dist_ant(int pos_x,int pos_y,int distsic) |
||
102 | { |
||
103 | int libero; /* variabile che indica se l'attuale posizione puntata dal veicolo e' libera */ |
||
104 | int distant; /* distanza dal veicolo che ci precede */ |
||
105 | int fine; /* variabile ausiliaria per capire se sto' arrivando alla fine della strada */ |
||
106 | |||
107 | /* inizializzazione delle variabili */ |
||
108 | libero=0; |
||
109 | distant=0; |
||
110 | |||
111 | /* calcola la distanza da un eventuale veicolo che ci precede */ |
||
112 | sem_wait(&strada); |
||
113 | if (pos_y<CENTROCARREGGIATA) /* controlla se il veicolo e' nella prima corsia, altrimenti e' in seconda corsia */ |
||
114 | while (libero==0 && distant<distsic) /* il calcolo della distanza da un veicolo che ci precede termina quando viene trovato un veicolo o si raggiunge la lunghezza massima di visione del sensore */ |
||
115 | { |
||
116 | fine=pos_x+distant; /* nel caso in cui il veicolo si giunto alla fine dell'autostrada si assume che il sensore ritorni un valore come nel caso in cui non sia preceduto da nessun veicolo */ |
||
117 | if (fine>40000) |
||
118 | distant=distsic; |
||
119 | else |
||
120 | if (corsia2[fine]!=0) /* se la strada e' occupata da un'altro veicolo pongo la variabile libero ad uno (strada occupata), altrimenti in caso contrario incremento la distanza analizzata dal sensore */ |
||
121 | libero=1; |
||
122 | else |
||
123 | distant++; |
||
124 | } |
||
125 | else /* il veicolo e' nella seconda corsia */ |
||
126 | while (libero==0 && distant<distsic) /* il calcolo della distanza da un veicolo che ci precede termina quando viene trovato un veicolo o si raggiunge la lunghezza massima di visione del sensore */ |
||
127 | { |
||
128 | fine=pos_x+distant; /* nel caso in cui il veicolo si giunto alla fine dell'autostrada si assume che il sensore ritorni un valore come nel caso in cui non sia preceduto da nessun veicolo */ |
||
129 | if (fine>40000) |
||
130 | distant=distsic; |
||
131 | else |
||
132 | if (corsia1[fine]!=0) /* se la strada e' occupata da un'altro veicolo pongo la variabile libero ad uno (strada occupata), altrimenti in caso contrario incremento la distanza analizzata dal sensore */ |
||
133 | libero=1; |
||
134 | else |
||
135 | distant++; |
||
136 | } |
||
137 | sem_post(&strada); |
||
138 | |||
139 | return(distant); /* ritorna il valore della distanza misurata dal sensore , se non ha trovato nessun veicolo tale distanza e' pari alla massima lunghezza a cui puo' arrivare il sensore */ |
||
140 | } |
||
141 | |||
142 | |||
143 | /* ----------------------------------------------------------------------------- */ |
||
144 | |||
145 | |||
146 | /** FUNZIONE CHE CALCOLA LA DISTANZA ANTERIORE DESTRA DI UN VEICOLO CHE PRECEDE **/ |
||
147 | |||
148 | int dist_ant_dx(int pos_x,int pos_y,int distsicdx) |
||
149 | { |
||
150 | int distantdx; /* distanza dal veicolo che ci precede a destra */ |
||
151 | int libero; /* variabile che indica se l'attuale posizione puntata dal veicolo e' libera */ |
||
152 | int fine; /* variabile ausiliaria per capire se sto' arrivando alla fine della strada */ |
||
153 | |||
154 | /* inizializzazione delle variabili */ |
||
155 | libero=0; |
||
156 | distantdx=0; |
||
157 | |||
158 | sem_wait(&strada); |
||
159 | while (libero==0 && distantdx<distsicdx) /* il calcolo della distanza da un veicolo che ci precede a destra termina quando viene trovato un veicolo o si raggiunge la lunghezza massima di visione del sensore */ |
||
160 | { |
||
161 | fine=pos_x+distantdx; /* nel caso in cui il veicolo sia giunto alla fine dell'autostrada si assume che il sensore ritorni un valore come nel caso in cui non sia preceduto da nessun veicolo */ |
||
162 | if (fine>40000) |
||
163 | distantdx=distsicdx; |
||
164 | else |
||
165 | if (corsia1[fine]!=0) /* se la strada e' occupata da un'altro veicolo pongo la variabile libero ad uno (strada occupata), altrimenti in caso contrario incremento la distanza analizzata dal sensore */ |
||
166 | libero=1; |
||
167 | else |
||
168 | distantdx++; |
||
169 | } |
||
170 | sem_post(&strada); |
||
171 | |||
172 | return(distantdx); /* ritorna il valore della distanza misurata dal sensore , se non ha trovato nessun veicolo tale distanza e' pari alla massima lunghezza a cui puo' arrivare il sensore */ |
||
173 | } |
||
174 | |||
175 | |||
176 | /* ----------------------------------------------------------------------------- */ |
||
177 | |||
178 | |||
179 | /** FUNZIONE CHE CALCOLA LA DISTANZA ANTERIORE SINISTRA DI UN VEICOLO CHE PRECEDE **/ |
||
180 | |||
181 | int dist_ant_sx(int pos_x,int pos_y,int distsicsx) |
||
182 | { |
||
183 | int distantsx; /* distanza dal veicolo che ci precede a sinistra */ |
||
184 | int libero; /* variabile che indica se l'attuale posizione puntata dal veicolo e' libera */ |
||
185 | int fine; /* variabile ausiliaria per capire se sto' arrivando alla fine della strada */ |
||
186 | |||
187 | /* inizializzazione delle variabili */ |
||
188 | libero=0; |
||
189 | distantsx=0; |
||
190 | |||
191 | sem_wait(&strada); |
||
192 | while (libero==0 && distantsx<distsicsx) /* il calcolo della distanza da un veicolo che ci precede a sinistra termina quando viene trovato un veicolo o si raggiunge la lunghezza massima di visione del sensore */ |
||
193 | { |
||
194 | fine=pos_x+distantsx; /* nel caso in cui il veicolo si giunto alla fine dell'autostrada si assume che il sensore ritorni un valore come nel caso in cui non sia preceduto da nessun veicolo */ |
||
195 | if (fine>40000) |
||
196 | distantsx=distsicsx; |
||
197 | else |
||
198 | if (corsia2[fine]!=0) /* se la strada e' occupata da un'altro veicolo pongo la variabile libero ad uno (strada occupata), altrimenti in caso contrario incremento la distanza analizzata dal sensore */ |
||
199 | libero=1; |
||
200 | else |
||
201 | distantsx++; |
||
202 | } |
||
203 | sem_post(&strada); |
||
204 | |||
205 | return(distantsx); /* ritorna il valore della distanza misurata dal sensore , se non ha trovato nessun veicolo tale distanza e' pari alla massima lunghezza a cui puo' arrivare il sensore */ |
||
206 | } |
||
207 | |||
208 | |||
209 | /* ----------------------------------------------------------------------------- */ |
||
210 | |||
211 | |||
212 | /** FUNZIONE CHE CALCOLA LA DISTANZA POSTERIORE SINISTRA DI UN VEICOLO CHE INSEGUE **/ |
||
213 | |||
214 | int dist_postsx (int pos_x,int pos_y,int distsorp) |
||
215 | { |
||
216 | int distpostsx; /* distanza dal veicolo che ci insegue a sinistra */ |
||
217 | int libero; /* variabile che indica se l'attuale posizione puntata dal veicolo e' libera */ |
||
218 | int inizio; /* variabile ausiliaria per capire se sono all'inizio della strada */ |
||
219 | |||
220 | /* inizializzazione delle variabili */ |
||
221 | distpostsx=0; |
||
222 | libero=0; |
||
223 | |||
224 | sem_wait(&strada); |
||
225 | while (libero==0 && distpostsx<distsorp) /* il calcolo della distanza da un veicolo che ci insegue a sinistra termina quando viene trovato un veicolo o si raggiunge la lunghezza massima di visione del sensore */ |
||
226 | { |
||
227 | inizio=pos_x-distpostsx; /* nel caso in cui il veicolo si giunto alla fine dell'autostrada si assume che il sensore ritorni un valore come nel caso in cui non sia insuguito da nessun veicolo */ |
||
228 | if (inizio<0) |
||
229 | distpostsx=distsorp; |
||
230 | else |
||
231 | if (corsia2[inizio]!=0) /* se la strada e' occupata da un'altro veicolo pongo la variabile libero ad uno (strada occupata), altrimenti in caso contrario incremento la distanza analizzata dal sensore */ |
||
232 | libero=1; |
||
233 | else |
||
234 | distpostsx++; |
||
235 | } |
||
236 | sem_post(&strada); |
||
237 | |||
238 | return(distpostsx); /* ritorna il valore della distanza misurata dal sensore , se non ha trovato nessun veicolo tale distanza e' pari alla massima lunghezza a cui puo' arrivare il sensore */ |
||
239 | } |
||
240 | |||
241 | |||
242 | /* ----------------------------------------------------------------------------- */ |
||
243 | |||
244 | |||
245 | /** FUNZIONE CHE CALCOLA LA DISTANZA POSTERIORE DESTRA DI UN VEICOLO CHE INSEGUE **/ |
||
246 | |||
247 | int dist_postdx (int pos_x,int pos_y,int distrientro) |
||
248 | { |
||
249 | int distpostdx; /* distanza dal veicolo che ci insegue a destra */ |
||
250 | int libero; /* variabile che indica se l'attuale posizione puntata dal veicolo e' libera */ |
||
251 | int inizio; /* variabile ausiliaria per capire se sono all'inizio della strada */ |
||
252 | |||
253 | /* inizializzazione delle variabili */ |
||
254 | libero=0; |
||
255 | distpostdx=0; |
||
256 | |||
257 | sem_wait(&strada); |
||
258 | while (libero==0 && distpostdx<distrientro) /* il calcolo della distanza da un veicolo che ci insegue a destra termina quando viene trovato un veicolo o si raggiunge la lunghezza massima di visione del sensore */ |
||
259 | { |
||
260 | inizio=pos_x-distpostdx; /* nel caso in cui il veicolo si giunto alla fine dell'autostrada si assume che il sensore ritorni un valore come nel caso in cui non sia inseguito da nessun veicolo */ |
||
261 | if (inizio<0) |
||
262 | distpostdx=distrientro; |
||
263 | else |
||
264 | if (corsia1[inizio]!=0) /* se la strada e' occupata da un'altro veicolo pongo la variabile libero ad uno (strada occupata), altrimenti in caso contrario incremento la distanza analizzata dal sensore */ |
||
265 | libero=1; |
||
266 | else |
||
267 | distpostdx++; |
||
268 | } |
||
269 | sem_post(&strada); |
||
270 | |||
271 | return(distpostdx); /* ritorna il valore della distanza misurata dal sensore , se non ha trovato nessun veicolo tale distanza e' pari alla massima lunghezza a cui puo' arrivare il sensore */ |
||
272 | } |
||
273 | |||
274 | |||
275 | /* ----------------------------------------------------------------------------- */ |
||
276 | |||
277 | |||
278 | /**************************** TASK AUTO LENTA ******************************/ |
||
279 | |||
280 | TASK auto_lenta(void *arg) |
||
281 | { |
||
282 | int x; /* posizione x assunta dal veicolo */ |
||
283 | int y; /* posizione y assunta dal veicolo */ |
||
284 | int oxelic; /* posizione vecchia dell'elicottero */ |
||
285 | int ox; /* posizione vecchia x dall'auto lenta */ |
||
286 | int oy; /* posizione vecchia y dall'auto lenta */ |
||
287 | int k; /* indice di ciclo */ |
||
288 | int estremo; /* distanza massima a cui ci possiamo spostare dall'elicottero (sia a destra che a sinistra) */ |
||
289 | int sorpasso; /* indica se il veicolo e' in fase di sorpasso */ |
||
290 | int rientro; /* indica se il veicolo e' in fase di rientro */ |
||
291 | int precedentedritto; /* distanza anteriore da un veicolo */ |
||
292 | int od; /* vecchia distanza anteriore da un veicolo */ |
||
293 | int tot; /* distanza massima raggiungibile del sensore posteriore sinistro */ |
||
294 | int tot3; /* distanza massima raggiungibile del sensore anteriore destro */ |
||
295 | int tot2; /* distanza massima raggiungibile del sensore posteriore destro */ |
||
296 | int i = (int)arg; |
||
297 | int sensore_ant=200; /* distanza massima raggiungibile del sensore anteriore */ |
||
298 | char stri[22]; /* vettore di caratteri */ |
||
299 | char ostri[22]; /* vettore di caratteri */ |
||
300 | float vcrociera; /* velocita' desiderata */ |
||
301 | float vmax2=35.0; /* velocita' massima raggiungibile in seconda corsia */ |
||
302 | float vmax1=25.0; /* velocita' massima raggiungibile in prima corsia */ |
||
303 | float frenata=-7.0; /* valore massimo della frenata */ |
||
304 | float amax=10.0; /* valore massimo dell'accellerazione */ |
||
305 | float v; /* velocita' attuale */ |
||
306 | float a; /* accellerazione attuale */ |
||
307 | float ov; /* velocita' precedente */ |
||
308 | float oa; /* accellerazione precedente */ |
||
309 | |||
310 | /* inizializzazione delle variabili */ |
||
311 | v=5.0; |
||
312 | a=0.0; |
||
313 | x=LUNGLENTA; |
||
314 | y=CENTROCORSIA1; |
||
315 | sorpasso=0; |
||
316 | rientro=0; |
||
317 | tot=100; |
||
318 | tot2=150; |
||
319 | tot3=100; |
||
320 | vcrociera=vmax1; |
||
321 | oa=a; |
||
322 | ov=v; |
||
323 | od=0; |
||
324 | oxelic=xelic; |
||
325 | estremo=(int)((MAX_X/2)-1); |
||
326 | |||
327 | while (1) |
||
328 | { |
||
329 | /* cancella il veicolo se era presente sull'autostrada vista dall'elicottero */ |
||
330 | if (abs(oxelic-ox)<estremo) |
||
331 | draw_veicolo(ox-oxelic+estremo, oy, 0,LUNGLENTA,LARGLENTA); |
||
332 | |||
333 | /* salva le vecchie coordinate */ |
||
334 | ox = x; |
||
335 | oy = y; |
||
336 | |||
337 | /* cancella il veicolo dalla vecchia posizione sulla corsia , andando a cancellarlo nel vettore della corsia in cui si trovava */ |
||
338 | sem_wait(&strada); |
||
339 | for (k=0;k<LUNGLENTA;k++) |
||
340 | { |
||
341 | if ((oy<CENTROCORSIA1) && (oy>CENTROCORSIA2)) |
||
342 | { |
||
343 | corsia1[ox-k]=0; |
||
344 | corsia2[ox-k]=0; |
||
345 | } |
||
346 | else |
||
347 | if (oy==CENTROCORSIA1) |
||
348 | corsia1[ox-k]=0; |
||
349 | else |
||
350 | if (oy==CENTROCORSIA2) |
||
351 | corsia2[ox-k]=0; |
||
352 | } |
||
353 | sem_post(&strada); |
||
354 | |||
355 | /* cancella tutte le vecchie informazioni che compaiono sullo schermo */ |
||
356 | sprintf(stri,"posizione %d",(int)(ox*0.25)); |
||
357 | sem_wait(&mutex); |
||
358 | grx_text(stri,70,50+i*10,rgb16(0,0,0),rgb16(0,0,0)); |
||
359 | sem_post(&mutex); |
||
360 | |||
361 | sprintf(ostri,"a %nf",oa); |
||
362 | sem_wait(&mutex); |
||
363 | grx_text(ostri,300,50+i*10,rgb16(0,0,0),rgb16(0,0,0)); |
||
364 | sem_post(&mutex); |
||
365 | |||
366 | sprintf(ostri,"v %nf",ov); |
||
367 | sem_wait(&mutex); |
||
368 | grx_text(ostri,200,50+i*10,rgb16(0,0,0),rgb16(0,0,0)); |
||
369 | sem_post(&mutex); |
||
370 | |||
371 | /* legge la distanza dal sensore anteriore e nel caso in cui sia attaccato alla macchina che precede vengo eliminato */ |
||
372 | precedentedritto=dist_ant(x,y,sensore_ant); |
||
373 | if (precedentedritto==1) |
||
374 | task_abort(i); |
||
375 | |||
376 | /* disegna il veicolo nella nuova posizione */ |
||
377 | if (abs(xelic-x)<estremo) |
||
378 | draw_veicolo(x-xelic+estremo, y, rgb16(255,0,0),LUNGLENTA,LARGLENTA); |
||
379 | |||
380 | /* varia la massima distanza vista dal sensore posteriore sinistro a seconda della velocita' */ |
||
381 | tot=(int)(v*4); |
||
382 | if (tot<50) |
||
383 | tot=50; |
||
384 | |||
385 | if (precedentedritto<100) /* ci siamo avvicinando troppo alla macchina che ci precede */ |
||
386 | if ((sorpasso==0) && (dist_postsx(x,y,200)>tot)&&(dist_ant_sx(x,y,50)>40)) |
||
387 | { |
||
388 | /* c'e' uno davanti e non sopraggiunge nessuno sulla corsia di sorpasso */ |
||
389 | sorpasso=1; |
||
390 | rientro=0; |
||
391 | vcrociera=vmax2; |
||
392 | } |
||
393 | else |
||
394 | a=frenata; /* c'e qualcuno davanti ,ma non possiamo sorpassare */ |
||
395 | else /* siamo lontani da un veicolo che ci precede o non ci precede nessuno */ |
||
396 | if (v<vcrociera) /* accelleriamo gradualmente fino a portarci alla velocita' di crociera desiderata */ |
||
397 | a=amax-(amax/vcrociera)*v; |
||
398 | else |
||
399 | if(v>vcrociera) /* freniamo per portarci al valore della velocita'di crociera */ |
||
400 | a=frenata/3; |
||
401 | else |
||
402 | a=0.0; /* siamo alla velocita' di crociera */ |
||
403 | |||
404 | /* controlla se e' possibile la manovra di rientro dal sorpasso, aggiustando tutti i parametri nel modo corretto */ |
||
405 | if ((dist_postdx(x,y,200)>tot2) && (dist_ant_dx(x,y,200)>tot3) && (sorpasso==1)) |
||
406 | { |
||
407 | rientro=1; |
||
408 | sorpasso=0; |
||
409 | vcrociera=vmax1; |
||
410 | } |
||
411 | |||
412 | /* aggiusta la cordinata y per far visualizzare il sorpasso o il rientro della macchina in modo graduale */ |
||
413 | if(y>CENTROCORSIA2 && sorpasso==1) |
||
414 | y=y-1; |
||
415 | |||
416 | if(y<CENTROCORSIA1 && rientro==1) |
||
417 | y=y+1; |
||
418 | |||
419 | /* calcola la velocita' e nel caso di v elocita' negative la pone a zero (non sono permesse le retromarcie) */ |
||
420 | v=v+a*DT; |
||
421 | if (v<0) |
||
422 | v=0.0; |
||
423 | |||
424 | /* calcola la cordinata x a cui si trova la macchina */ |
||
425 | x=x+(int)((v*DT)/0.25); |
||
426 | |||
427 | /* scrive a video i nuovi parametri appena calcolati */ |
||
428 | sprintf(stri,"posizione %d",(int)(x*0.25)); |
||
429 | sem_wait(&mutex); |
||
430 | grx_text(stri,70,50+i*10,rgb16(255,255,255),rgb16(0,0,0)); |
||
431 | sem_post(&mutex); |
||
432 | |||
433 | sprintf(ostri,"v %nf",v); |
||
434 | sem_wait(&mutex); |
||
435 | grx_text(ostri,200,50+i*10,rgb16(255,255,255),rgb16(0,0,0)); |
||
436 | sem_post(&mutex); |
||
437 | |||
438 | sprintf(ostri,"a %nf",a); |
||
439 | sem_wait(&mutex); |
||
440 | grx_text(ostri,300,50+i*10,rgb16(255,255,255),rgb16(0,0,0)); |
||
441 | sem_post(&mutex); |
||
442 | |||
443 | /* quando il veicolo arriva alla fine dell'autostrada viene eliminato */ |
||
444 | if (x>=40000) |
||
445 | task_abort(i); |
||
446 | |||
447 | /* salva la nuova posizione del veicolo */ |
||
448 | sem_wait(&strada); |
||
449 | for (k=0;k<LUNGLENTA;k++) |
||
450 | { |
||
451 | if ((y<CENTROCORSIA1) && (y>CENTROCORSIA2)) |
||
452 | { |
||
453 | corsia2[x-k]=1; |
||
454 | corsia1[x-k]=1; |
||
455 | } |
||
456 | else |
||
457 | if (y==CENTROCORSIA1) |
||
458 | corsia1[x-k]=1; |
||
459 | else |
||
460 | if (y==CENTROCORSIA2) |
||
461 | corsia2[x-k]=1; |
||
462 | } |
||
463 | sem_post(&strada); |
||
464 | |||
465 | /* salvo i parametri che occorrono per il prossimo ciclo */ |
||
466 | oxelic=xelic; |
||
467 | od=precedentedritto; |
||
468 | ov=v; |
||
469 | oa=a; |
||
470 | |||
471 | task_endcycle(); /* termina le operazioni che il task deve eseguire */ |
||
472 | } |
||
473 | } |
||
474 | |||
475 | |||
476 | /* ----------------------------------------------------------------------------- */ |
||
477 | |||
478 | |||
479 | /************************** TASK AUTO VELOCE *******************************/ |
||
480 | |||
481 | TASK auto_veloce(void *arg) |
||
482 | { |
||
483 | int x; /* posizione x assunta dal veicolo */ |
||
484 | int y; /* posizione y assunta dal veicolo */ |
||
485 | int oxelic; /* posizione vecchia dell'elicottero */ |
||
486 | int ox; /* posizione vecchia x dall'auto veloce */ |
||
487 | int oy; /* posizione vecchia y dall'auto veloce */ |
||
488 | int k; /* indice di ciclo */ |
||
489 | int estremo; /* distanza massima a cui ci possiamo spostare dall'elicottero (sia a destra che a sinistra) */ |
||
490 | int sorpasso; /* indica se il veicolo e' in fase di sorpasso */ |
||
491 | int rientro; /* indica se il veicolo e' in fase di rientro */ |
||
492 | int precedentedritto; /* distanza anteriore da un veicolo */ |
||
493 | int od; /* vecchia distanza anteriore da un veicolo */ |
||
494 | int tot; /* distanza massima raggiungibile del sensore posteriore sinistro */ |
||
495 | int tot3; /* distanza massima raggiungibile del sensore anteriore destro */ |
||
496 | int tot2; /* distanza massima raggiungibile del sensore posteriore destro */ |
||
497 | int i = (int)arg; |
||
498 | int sensore_ant=200; /* distanza massima raggiungibile del sensore anteriore */ |
||
499 | char stri[22]; /* vettore di caratteri */ |
||
500 | char ostri[22]; /* vettore di caratteri */ |
||
501 | float vcrociera; /* velocita' desiderata */ |
||
502 | float vmax1=35.0; /* velocita' massima raggiungibile in prima corsia */ |
||
503 | float vmax2=40.0; /* velocita' massima raggiungibile in seconda corsia */ |
||
504 | float frenata=-7.0; /* valore massimo della frenata */ |
||
505 | float amax=15.0; /* valore massimo del'accellerazione */ |
||
506 | float v; /* velocita' attuale */ |
||
507 | float a; /* accellerazione attuale */ |
||
508 | float ov; /* velocita' precedente */ |
||
509 | float oa; /* accellerazione precedente */ |
||
510 | |||
511 | /* inizializzazione delle variabili */ |
||
512 | v=5.0; |
||
513 | a=0.0; |
||
514 | x=LUNGVELOCE; |
||
515 | y=CENTROCORSIA1; |
||
516 | sorpasso=0; |
||
517 | rientro=0; |
||
518 | tot=100; |
||
519 | tot2=150; |
||
520 | tot3=100; |
||
521 | oa=a; |
||
522 | vcrociera=vmax1; |
||
523 | ov=v; |
||
524 | od=0; |
||
525 | oxelic=xelic; |
||
526 | estremo=(int)((MAX_X/2)-1); |
||
527 | |||
528 | while (1) |
||
529 | { |
||
530 | /* cancella il veicolo se era presente sull'autostrada vista dall'elicottero */ |
||
531 | if (abs(oxelic-ox)<estremo) |
||
532 | draw_veicolo(ox-oxelic+estremo, oy, 0,LUNGVELOCE,LARGVELOCE); |
||
533 | |||
534 | /* salva le vecchie coordinate */ |
||
535 | ox = x; |
||
536 | oy = y; |
||
537 | |||
538 | /* cancella il veicolo dalla vecchia posizione sulla corsia , andando a cancellarlo nel vettore della corsia in cui si trovava */ |
||
539 | sem_wait(&strada); |
||
540 | for (k=0;k<LUNGVELOCE;k++) |
||
541 | { |
||
542 | if ((oy<CENTROCORSIA1) && (oy>CENTROCORSIA2)) |
||
543 | { |
||
544 | corsia1[ox-k]=0; |
||
545 | corsia2[ox-k]=0; |
||
546 | } |
||
547 | else |
||
548 | if (oy==CENTROCORSIA1) |
||
549 | corsia1[ox-k]=0; |
||
550 | else |
||
551 | if (oy==CENTROCORSIA2) |
||
552 | corsia2[ox-k]=0; |
||
553 | } |
||
554 | sem_post(&strada); |
||
555 | |||
556 | /* cancella tutte le vecchie informazioni che compaiono sullo schermo */ |
||
557 | sprintf(stri,"posizione %d",(int)(ox*0.25)); |
||
558 | sem_wait(&mutex); |
||
559 | grx_text(stri,70,50+i*10,rgb16(0,0,0),rgb16(0,0,0)); |
||
560 | sem_post(&mutex); |
||
561 | |||
562 | sprintf(ostri,"v %nf",ov); |
||
563 | sem_wait(&mutex); |
||
564 | grx_text(ostri,200,50+i*10,rgb16(0,0,0),rgb16(0,0,0)); |
||
565 | sem_post(&mutex); |
||
566 | |||
567 | sprintf(ostri,"a %nf",oa); |
||
568 | sem_wait(&mutex); |
||
569 | grx_text(ostri,300,50+i*10,rgb16(0,0,0),rgb16(0,0,0)); |
||
570 | sem_post(&mutex); |
||
571 | |||
572 | /* legge la distanza dal sensore anteriore e nel caso in cui sia attaccato alla macchina che precede vengo eliminato */ |
||
573 | precedentedritto=dist_ant(x,y,sensore_ant); |
||
574 | if (precedentedritto==1) |
||
575 | task_abort(i); |
||
576 | |||
577 | /* disegna il veicolo nella nuova posizione */ |
||
578 | if (abs(xelic-x)<estremo) |
||
579 | draw_veicolo(x-xelic+estremo, y, rgb16(0,255,0),LUNGVELOCE,LARGVELOCE); |
||
580 | |||
581 | |||
582 | /* varia la massima distanza vista dal sensore posteriore sinistro a seconda della velocita' */ |
||
583 | tot=(int)(v*4); |
||
584 | if (tot<50) |
||
585 | tot=50; |
||
586 | |||
587 | if (precedentedritto<150) /* ci siamo avvicinando troppo alla macchina che ci precede */ |
||
588 | if ((sorpasso==0) && (dist_postsx(x,y,200)>tot)&&(dist_ant_sx(x,y,50)>40)) |
||
589 | { |
||
590 | /* c'e' uno davanti e non sopraggiunge nessuno sulla corsia di sorpasso */ |
||
591 | sorpasso=1; |
||
592 | rientro=0; |
||
593 | vcrociera=vmax2; |
||
594 | } |
||
595 | else /* c'e qualcuno davanti ,ma non possiamo sorpassare */ |
||
596 | a=frenata; |
||
597 | else /* siamo lontani da un veicolo che ci precede o non ci precede nessuno */ |
||
598 | if (v<vcrociera) /* accelleriamo gradualmente fino a portarci alla velocita' di crociera desiderata */ |
||
599 | a=amax-(amax/vcrociera)*v; |
||
600 | else |
||
601 | if(v>vcrociera) /* freniamo per portarci al valore della velocita'di crociera */ |
||
602 | a=frenata/3; |
||
603 | else |
||
604 | a=0.0; /* siamo alla velocita' di crociera */ |
||
605 | |||
606 | /* controlla se e' possibile la manovra di rientro dal sorpasso, aggiustando tutti i parametri nel modo corretto */ |
||
607 | if ((dist_postdx(x,y,200)>tot2) && (dist_ant_dx(x,y,200)>tot3) && (sorpasso==1)) |
||
608 | { |
||
609 | rientro=1; |
||
610 | sorpasso=0; |
||
611 | vcrociera=vmax1; |
||
612 | } |
||
613 | |||
614 | /* aggiusta la cordinata y per far visualizzare il sorpasso o il rientro della macchina in modo graduale */ |
||
615 | if(y>CENTROCORSIA2 && sorpasso==1) |
||
616 | y=y-1; |
||
617 | |||
618 | if(y<CENTROCORSIA1 && rientro==1) |
||
619 | y=y+1; |
||
620 | |||
621 | /* calcola la velocita' e nel caso di v elocita' negative la pone a zero (non sono permesse le retromarcie) */ |
||
622 | v=v+a*DT; |
||
623 | if (v<0) |
||
624 | v=0.0; |
||
625 | |||
626 | /* calcola la cordinata x a cui si trova la macchina */ |
||
627 | x=x+(int)((v*DT)/0.25); |
||
628 | |||
629 | /* scrive a video i nuovi parametri appena calcolati */ |
||
630 | sprintf(stri,"posizione %d",(int)(x*0.25)); |
||
631 | sem_wait(&mutex); |
||
632 | grx_text(stri,70,50+i*10,rgb16(255,255,255),rgb16(0,0,0)); |
||
633 | sem_post(&mutex); |
||
634 | |||
635 | sprintf(ostri,"v %nf",v); |
||
636 | sem_wait(&mutex); |
||
637 | grx_text(ostri,200,50+i*10,rgb16(255,255,255),rgb16(0,0,0)); |
||
638 | sem_post(&mutex); |
||
639 | |||
640 | sprintf(ostri,"a %nf",a); |
||
641 | sem_wait(&mutex); |
||
642 | grx_text(ostri,300,50+i*10,rgb16(255,255,255),rgb16(0,0,0)); |
||
643 | sem_post(&mutex); |
||
644 | |||
645 | /* quando il veicolo arriva alla fine dell'autostrada viene eliminato */ |
||
646 | if (x>=40000) |
||
647 | task_abort(i); |
||
648 | |||
649 | /* salva la nuova posizione del veicolo */ |
||
650 | sem_wait(&strada); |
||
651 | for (k=0;k<LUNGVELOCE;k++) |
||
652 | { |
||
653 | if ((y<CENTROCORSIA1) && (y>CENTROCORSIA2)) |
||
654 | { |
||
655 | corsia2[x-k]=1; |
||
656 | corsia1[x-k]=1; |
||
657 | } |
||
658 | else |
||
659 | if (y==CENTROCORSIA1) |
||
660 | corsia1[x-k]=1; |
||
661 | else |
||
662 | if (y==CENTROCORSIA2) |
||
663 | corsia2[x-k]=1; |
||
664 | } |
||
665 | sem_post(&strada); |
||
666 | |||
667 | /* salvo i parametri che occorrono per il prossimo ciclo */ |
||
668 | oxelic=xelic; |
||
669 | od=precedentedritto; |
||
670 | ov=v; |
||
671 | oa=a; |
||
672 | |||
673 | task_endcycle(); /* termina le operazioni che il task deve eseguire */ |
||
674 | } |
||
675 | } |
||
676 | |||
677 | |||
678 | /* ----------------------------------------------------------------------------- */ |
||
679 | |||
680 | |||
681 | /***************************** TASK AUTOCARRO ******************************/ |
||
682 | |||
683 | TASK auto_carro(void *arg) |
||
684 | { |
||
685 | int x; /* posizione x assunta dal veicolo */ |
||
686 | int y; /* posizione y assunta dal veicolo */ |
||
687 | int oxelic; /* posizione vecchia dell'elicottero */ |
||
688 | int ox; /* posizione vecchia x assunta dal camion */ |
||
689 | int oy; /* posizione vecchia y assunta dal camion */ |
||
690 | int k; /* indice di ciclo */ |
||
691 | int estremo; /* distanza massima a cui ci possiamo spostare dall'elicottero (sia a destra che a sinistra) */ |
||
692 | int sorpasso; /* indica se il veicolo e' in fase di sorpasso */ |
||
693 | int rientro; /* indica se il veicolo e' in fase di rientro */ |
||
694 | int precedentedritto; /* distanza anteriore da un veicolo */ |
||
695 | int od; /* vecchia distanza anteriore da un veicolo */ |
||
696 | int tot; /* distanza massima raggiungibile del sensore posteriore sinistro */ |
||
697 | int tot3; /* distanza massima raggiungibile del sensore anteriore destro */ |
||
698 | int tot2; /* distanza massima raggiungibile del sensore posteriore destro */ |
||
699 | int i = (int)arg; |
||
700 | int sensore_ant=200; /* distanza massima raggiungibile del sensore anteriore */ |
||
701 | char stri[22]; /* vettore di caratteri */ |
||
702 | char ostri[22]; /* vettore di caratteri */ |
||
703 | float vcrociera; /* velocita' desiderata */ |
||
704 | float vmax1=15.0; /* velocita' massima raggiungibile in prima corsia */ |
||
705 | float vmax2=20.0; /* velocita' massima raggiungibile in seconda corsia */ |
||
706 | float frenata=-5.0; /* valore massimo della frenata */ |
||
707 | float amax=3.0; /* valore massimo del'accellerazione */ |
||
708 | float v; /* velocita' attuale */ |
||
709 | float a; /* accellerazione attuale */ |
||
710 | float ov; /* velocita' precedente */ |
||
711 | float oa; /* accellerazione precedente */ |
||
712 | |||
713 | /* inizializzazione delle variabili */ |
||
714 | v=5.0; |
||
715 | a=0.0; |
||
716 | x=LUNGCAMION; |
||
717 | y=CENTROCORSIA1; |
||
718 | sorpasso=0; |
||
719 | rientro=0; |
||
720 | tot=100; |
||
721 | tot2=150; |
||
722 | tot3=100; |
||
723 | oa=a; |
||
724 | vcrociera=vmax1; |
||
725 | ov=v; |
||
726 | od=0; |
||
727 | oxelic=xelic; |
||
728 | estremo=(int)((MAX_X/2)-1); |
||
729 | |||
730 | while (1) |
||
731 | { |
||
732 | /* cancella il veicolo se era presente sull'autostrada vista dall'elicottero */ |
||
733 | if (abs(oxelic-ox)<estremo) |
||
734 | draw_veicolo(ox-oxelic+estremo, oy, 0,LUNGCAMION,LARGCAMION); |
||
735 | |||
736 | /* salva le vecchie coordinate */ |
||
737 | ox = x; |
||
738 | oy = y; |
||
739 | |||
740 | /* cancella il veicolo dalla vecchia posizione sulla corsia , andando a cancellarlo nel vettore della corsia in cui si trovava */ |
||
741 | sem_wait(&strada); |
||
742 | for (k=0;k<LUNGCAMION;k++) |
||
743 | { |
||
744 | if ((oy<CENTROCORSIA1) && (oy>CENTROCORSIA2)) |
||
745 | { |
||
746 | corsia1[ox-k]=0; |
||
747 | corsia2[ox-k]=0; |
||
748 | } |
||
749 | else |
||
750 | if (oy==CENTROCORSIA1) |
||
751 | corsia1[ox-k]=0; |
||
752 | else |
||
753 | if (oy==CENTROCORSIA2) |
||
754 | corsia2[ox-k]=0; |
||
755 | } |
||
756 | sem_post(&strada); |
||
757 | |||
758 | /* cancella tutte le vecchie informazioni che compaiono sullo schermo */ |
||
759 | sprintf(stri,"posizione %d",(int)(ox*0.25)); |
||
760 | sem_wait(&mutex); |
||
761 | grx_text(stri,70,50+i*10,rgb16(0,0,0),rgb16(0,0,0)); |
||
762 | sem_post(&mutex); |
||
763 | |||
764 | sprintf(ostri,"v %nf",ov); |
||
765 | sem_wait(&mutex); |
||
766 | grx_text(ostri,200,50+i*10,rgb16(0,0,0),rgb16(0,0,0)); |
||
767 | sem_post(&mutex); |
||
768 | |||
769 | sprintf(ostri,"a %nf",oa); |
||
770 | sem_wait(&mutex); |
||
771 | grx_text(ostri,300,50+i*10,rgb16(0,0,0),rgb16(0,0,0)); |
||
772 | sem_post(&mutex); |
||
773 | |||
774 | /* legge la distanza dal sensore anteriore e nel caso in cui sia attaccato alla macchina che precede vengo eliminato */ |
||
775 | precedentedritto=dist_ant(x,y,sensore_ant); |
||
776 | if (precedentedritto==1) |
||
777 | task_abort(i); |
||
778 | |||
779 | /* disegna il veicolo nella nuova posizione */ |
||
780 | if (abs(xelic-x)<estremo) |
||
781 | draw_veicolo(x-xelic+estremo, y, rgb16(0,0,255),LUNGCAMION,LARGCAMION); |
||
782 | |||
783 | /* varia la massima distanza vista dal sensore posteriore sinistro a seconda della velocita' */ |
||
784 | tot=(int)(v*4); |
||
785 | if (tot<50) |
||
786 | tot=50; |
||
787 | |||
788 | if (precedentedritto<100) /* ci siamo avvicinando troppo alla macchina che ci precede */ |
||
789 | if ((sorpasso==0) && (dist_postsx(x,y,200)>tot)&&(dist_ant_sx(x,y,50)>40)) |
||
790 | { |
||
791 | /* c'e' uno davanti e non sopraggiunge nessuno sulla corsia di sorpasso */ |
||
792 | sorpasso=1; |
||
793 | rientro=0; |
||
794 | vcrociera=vmax2; |
||
795 | } |
||
796 | else /* c'e qualcuno davanti ,ma non possiamo sorpassare */ |
||
797 | a=frenata; |
||
798 | else /* siamo lontani da un veicolo che ci precede o non ci precede nessuno */ |
||
799 | if (v<vcrociera) /* accelleriamo gradualmente fino a portarci alla velocita' di crociera desiderata */ |
||
800 | a=amax-(amax/vcrociera)*v; |
||
801 | else |
||
802 | if(v>vcrociera) /* freniamo per portarci al valore della velocita'di crociera */ |
||
803 | a=frenata/3; |
||
804 | else |
||
805 | a=0.0; /* siamo alla velocita' di crociera */ |
||
806 | |||
807 | /* controlla se e' possibile la manovra di rientro dal sorpasso, aggiustando tutti i parametri nel modo corretto */ |
||
808 | if ((dist_postdx(x,y,200)>tot2) && (dist_ant_dx(x,y,200)>tot3) && (sorpasso==1)) |
||
809 | { |
||
810 | rientro=1; |
||
811 | sorpasso=0; |
||
812 | vcrociera=vmax1; |
||
813 | } |
||
814 | |||
815 | /* aggiusta la cordinata y per far visualizzare il sorpasso o il rientro della macchina in modo graduale */ |
||
816 | if(y>CENTROCORSIA2 && sorpasso==1) |
||
817 | y=y-1; |
||
818 | |||
819 | if(y<CENTROCORSIA1 && rientro==1) |
||
820 | y=y+1; |
||
821 | |||
822 | /* calcola la velocita' e nel caso di v elocita' negative la pone a zero (non sono permesse le retromarcie) */ |
||
823 | v=v+a*DT; |
||
824 | if (v<0) |
||
825 | v=0.0; |
||
826 | |||
827 | /* calcola la cordinata x a cui si trova la macchina */ |
||
828 | x=x+(int)((v*DT)/0.25); |
||
829 | |||
830 | /* scrive a video i nuovi parametri appena calcolati */ |
||
831 | sprintf(stri,"posizione %d",(int)(x*0.25)); |
||
832 | sem_wait(&mutex); |
||
833 | grx_text(stri,70,50+i*10,rgb16(255,255,255),rgb16(0,0,0)); |
||
834 | sem_post(&mutex); |
||
835 | |||
836 | sprintf(ostri,"v %nf",v); |
||
837 | sem_wait(&mutex); |
||
838 | grx_text(ostri,200,50+i*10,rgb16(255,255,255),rgb16(0,0,0)); |
||
839 | sem_post(&mutex); |
||
840 | |||
841 | sprintf(ostri,"a %nf",a); |
||
842 | sem_wait(&mutex); |
||
843 | grx_text(ostri,300,50+i*10,rgb16(255,255,255),rgb16(0,0,0)); |
||
844 | sem_post(&mutex); |
||
845 | |||
846 | /* quando il veicolo arriva alla fine dell'autostrada viene eliminato */ |
||
847 | if (x>=40000) |
||
848 | task_abort(i); |
||
849 | |||
850 | /* salva la nuova posizione del veicolo */ |
||
851 | sem_wait(&strada); |
||
852 | for (k=0;k<LUNGCAMION;k++) |
||
853 | { |
||
854 | if ((y<CENTROCORSIA1) && (y>CENTROCORSIA2)) |
||
855 | { |
||
856 | corsia2[x-k]=1; |
||
857 | corsia1[x-k]=1; |
||
858 | } |
||
859 | else |
||
860 | if (y==CENTROCORSIA1) |
||
861 | corsia1[x-k]=1; |
||
862 | else |
||
863 | if (y==CENTROCORSIA2) |
||
864 | corsia2[x-k]=1; |
||
865 | } |
||
866 | sem_post(&strada); |
||
867 | |||
868 | /* salvo i parametri che occorrono per il prossimo ciclo */ |
||
869 | oxelic=xelic; |
||
870 | od=precedentedritto; |
||
871 | ov=v; |
||
872 | oa=a; |
||
873 | |||
874 | task_endcycle(); /* termina le operazioni che il task deve eseguire */ |
||
875 | } |
||
876 | } |
||
877 | |||
878 | |||
879 | /* ----------------------------------------------------------------------------- */ |
||
880 | |||
881 | |||
882 | /***************************** TASK ELICOTTERO *****************************/ |
||
883 | |||
884 | TASK eli_cottero(void *arg) |
||
885 | { |
||
886 | int i = (int)arg; |
||
887 | int oxelic; /* vecchia posizione dell'elicottero */ |
||
888 | char stri[22]; /* vettore di caratteri */ |
||
889 | char ostri[22]; /* vettore di caratteri */ |
||
890 | |||
891 | /* disegna le scritte per l'indicatore a barra e finestra della posizione dell'elicottero */ |
||
892 | sprintf(stri,"0 Km"); |
||
893 | sem_wait(&mutex); |
||
894 | grx_text(stri,100,560,rgb16(255,255,255),rgb16(0,0,0)); |
||
895 | sem_post(&mutex); |
||
896 | |||
897 | sprintf(stri,"10 Km"); |
||
898 | sem_wait(&mutex); |
||
899 | grx_text(stri,700,560,rgb16(255,255,255),rgb16(0,0,0)); |
||
900 | sem_post(&mutex); |
||
901 | |||
902 | while (1) |
||
903 | { |
||
904 | oxelic=xelic; /* salva la posizione precedente dell'elicottero */ |
||
905 | |||
906 | if (c == '+') /* sposta l'elicottero a destra (verso la fine dell'autostrada */ |
||
907 | { |
||
908 | xelic=xelic+50; |
||
909 | if (xelic>40000-(int)((MAX_X/2)-1)) |
||
910 | xelic=40000-(int)((MAX_X/2)-1); |
||
911 | } |
||
912 | else |
||
913 | if (c =='-') /* sposta l'elicottero a sinistra (verso l'inizio dell'autostrada */ |
||
914 | { |
||
915 | xelic=xelic-30; |
||
916 | if (xelic<(int)((MAX_X/2)-1)) |
||
917 | xelic=(int)((MAX_X/2)-1); |
||
918 | } |
||
919 | |||
920 | /* disegna le scritte innerenti all'elicottero e il valore della sua posizione (mediante scritta ed indicatore a barra con una finestra scorrevole) */ |
||
921 | sprintf(stri,"- <- xelic %d -> +",(int)(xelic*0.25)); |
||
922 | sprintf(ostri,"- <- xelic %d -> +",(int)(oxelic*0.25)); |
||
923 | |||
924 | sem_wait(&mutex); |
||
925 | grx_text(ostri,MAX_X/2-50,500,rgb16(0,0,0),rgb16(0,0,0)); |
||
926 | grx_text(stri,MAX_X/2-50,500,rgb16(255,255,255),rgb16(0,0,0)); |
||
927 | grx_line(150,560,650,560,rgb16(255,255,255)); |
||
928 | grx_rect((int)((oxelic-(MAX_X/2))/80+150),540,(int)((oxelic+(MAX_X/2))/80+150) ,580 ,rgb16(0,0,0)); |
||
929 | grx_rect((int)((xelic-(MAX_X/2))/80+150),540,(int)((xelic+(MAX_X/2))/80+150) ,580 ,rgb16(255,255,255)); |
||
930 | sem_post(&mutex); |
||
931 | |||
932 | c=' '; /* setta il carattere c */ |
||
933 | |||
934 | task_endcycle(); /* termina le operazioni che il task deve eseguire */ |
||
935 | } |
||
936 | } |
||
937 | |||
938 | |||
939 | /* -----------------------------------------------------------------------------*/ |
||
940 | |||
941 | |||
942 | /************* FUNZIONE DI USCITA DAL SISTEMA ******************************/ |
||
943 | |||
944 | void byebye(void *arg) |
||
945 | { /* questa funzione e' chiamata quando il sistema esce */ |
||
946 | grx_close(); /* chiude la grafica */ |
||
947 | kern_printf("Ciao Ciao "); /* scrive il messaggio indicato sul terminale */ |
||
948 | } |
||
949 | |||
950 | |||
951 | /* -----------------------------------------------------------------------------*/ |
||
952 | |||
953 | |||
954 | /********************************* MAIN ************************************/ |
||
955 | |||
956 | int main(int argc, char **argv) |
||
957 | { |
||
958 | int n_task = 0; /* numero di task creati */ |
||
959 | int u; |
||
960 | int v; |
||
961 | char introduzione[100]; /* vettore di caratteri */ |
||
962 | HARD_TASK_MODEL autolenta; /* task auto lenta */ |
||
963 | HARD_TASK_MODEL autoveloce; /* task auto veloce */ |
||
964 | HARD_TASK_MODEL autocarro; /* task camion */ |
||
965 | HARD_TASK_MODEL elicottero; /* task elicottero */ |
||
966 | |||
967 | |||
968 | /* inizializza le corsie dell'autostrada */ |
||
969 | sem_wait(&strada); |
||
970 | for (u=0;u<=40000;u++) |
||
971 | { |
||
972 | corsia1[u]=0; |
||
973 | corsia2[u]=0; |
||
974 | } |
||
975 | sem_post(&strada); |
||
976 | |||
977 | /* Set the exception handler */ |
||
978 | //set_exchandler_grx(); |
||
979 | |||
980 | /* Set the closing function */ |
||
981 | sys_atrunlevel(byebye, NULL, RUNLEVEL_BEFORE_EXIT); |
||
982 | |||
983 | /* inizializzazione grafica */ |
||
984 | if (grx_init() < 1) |
||
985 | sys_abort(1); |
||
986 | |||
987 | /* scelta automatica della risoluzione applicabile con quella scheda video (scegliendola tra 800*600 e 1024*768 ) */ |
||
988 | if(grx_getmode(1024,768,16)==-1) |
||
989 | { |
||
990 | if (grx_open(800, 600, 16) < 0) |
||
991 | { |
||
992 | kern_printf("GRX Err\n"); |
||
993 | sys_abort(1); |
||
994 | } |
||
995 | MAX_X=800; |
||
996 | MAX_Y=600; |
||
997 | } |
||
998 | else |
||
999 | { |
||
1000 | if (grx_open(1024,768, 16) < 0) |
||
1001 | { |
||
1002 | kern_printf("GRX Err\n"); |
||
1003 | sys_abort(1); |
||
1004 | } |
||
1005 | MAX_X=1024; |
||
1006 | MAX_Y=768; |
||
1007 | } |
||
1008 | |||
1009 | kern_printf("La scheda video va'!!\n"); |
||
1010 | |||
1011 | /* posizione iniziale elicottero */ |
||
1012 | xelic=(int)((MAX_X/2)-1); |
||
1013 | |||
1014 | /* disegna lo scenario della strada ed il menu */ |
||
1015 | sprintf(introduzione,"Monitoraggio dei mezzi che transitano su una autostrada."); |
||
1016 | sem_wait(&mutex); |
||
1017 | grx_text(introduzione,50,10,rgb16(255,255,255),rgb16(0,0,0)); |
||
1018 | sem_post(&mutex); |
||
1019 | |||
1020 | sprintf(introduzione,"Sviluppato da: Verzellesi Quadrubbi"); |
||
1021 | sem_wait(&mutex); |
||
1022 | grx_text(introduzione,50,20,rgb16(255,255,255),rgb16(0,0,0)); |
||
1023 | sem_post(&mutex); |
||
1024 | |||
1025 | sprintf(introduzione,"MENU"); |
||
1026 | sem_wait(&mutex); |
||
1027 | grx_text(introduzione,480,70,rgb16(255,255,255),rgb16(0,0,0)); |
||
1028 | sem_post(&mutex); |
||
1029 | |||
1030 | sprintf(introduzione,"s = macchina sportiva"); |
||
1031 | sem_wait(&mutex); |
||
1032 | grx_text(introduzione,480,80,rgb16(255,255,255),rgb16(0,0,0)); |
||
1033 | sem_post(&mutex); |
||
1034 | |||
1035 | sprintf(introduzione,"c = mezzo pesante"); |
||
1036 | sem_wait(&mutex); |
||
1037 | grx_text(introduzione,480,90,rgb16(255,255,255),rgb16(0,0,0)); |
||
1038 | sem_post(&mutex); |
||
1039 | |||
1040 | sprintf(introduzione,"l = macchina lenta"); |
||
1041 | sem_wait(&mutex); |
||
1042 | grx_text(introduzione,480,100,rgb16(255,255,255),rgb16(0,0,0)); |
||
1043 | sem_post(&mutex); |
||
1044 | |||
1045 | sprintf(introduzione,"+ = sposta l'elicottero verso destra"); |
||
1046 | sem_wait(&mutex); |
||
1047 | grx_text(introduzione,480,110,rgb16(255,255,255),rgb16(0,0,0)); |
||
1048 | sem_post(&mutex); |
||
1049 | |||
1050 | sprintf(introduzione,"- = sposta l'elicottero verso sinistra"); |
||
1051 | sem_wait(&mutex); |
||
1052 | grx_text(introduzione,480,120,rgb16(255,255,255),rgb16(0,0,0)); |
||
1053 | sem_post(&mutex); |
||
1054 | |||
1055 | sprintf(introduzione,"esc = uscita"); |
||
1056 | sem_wait(&mutex); |
||
1057 | grx_text(introduzione,480,130,rgb16(255,255,255),rgb16(0,0,0)); |
||
1058 | sem_post(&mutex); |
||
1059 | |||
1060 | sprintf(introduzione,"NOTA"); |
||
1061 | sem_wait(&mutex); |
||
1062 | grx_text(introduzione,480,140,rgb16(255,0,0),rgb16(0,0,0)); |
||
1063 | sem_post(&mutex); |
||
1064 | |||
1065 | sprintf(introduzione,"Se i veicoli tamponano "); |
||
1066 | sem_wait(&mutex); |
||
1067 | grx_text(introduzione,480,150,rgb16(255,255,255),rgb16(0,0,0)); |
||
1068 | sem_post(&mutex); |
||
1069 | |||
1070 | sprintf(introduzione," vengono eliminati"); |
||
1071 | sem_wait(&mutex); |
||
1072 | grx_text(introduzione,480,160,rgb16(255,255,255),rgb16(0,0,0)); |
||
1073 | sem_post(&mutex); |
||
1074 | |||
1075 | grx_line(1,450,MAX_X,450,rgb16(255,255,255)); |
||
1076 | grx_line(1,486,MAX_X,486,rgb16(255,255,255)); |
||
1077 | |||
1078 | for (u=0;u<MAX_X;u++) |
||
1079 | { |
||
1080 | v=u%8; |
||
1081 | if ((v==0) || (v==1)) |
||
1082 | { |
||
1083 | sem_wait(&mutex); |
||
1084 | grx_plot(u,CENTROCARREGGIATA,rgb16(255,255,255)); |
||
1085 | sem_post(&mutex); |
||
1086 | } |
||
1087 | } |
||
1088 | |||
1089 | n_task=0; /* inizializzazione del numero dei task */ |
||
1090 | |||
1091 | /* definisce e crea il task elicottero */ |
||
1092 | kern_printf("elicottero"); |
||
1093 | hard_task_default_model (elicottero); |
||
1094 | hard_task_def_ctrl_jet (elicottero); |
||
1095 | hard_task_def_arg (elicottero, (void *)n_task); |
||
1096 | hard_task_def_wcet (elicottero,wcet); |
||
1097 | hard_task_def_mit (elicottero, periodo); |
||
1098 | hard_task_def_group (elicottero, GRUPPO); |
||
1099 | hard_task_def_usemath (elicottero); |
||
1100 | pid = task_create ("elicottero",eli_cottero, &elicottero, NULL); |
||
1101 | if (pid == NIL) |
||
1102 | { |
||
1103 | grx_close(); |
||
1104 | perror("Non si puo' creare il task"); |
||
1105 | sys_abort(1); |
||
1106 | } |
||
1107 | task_activate(pid); |
||
1108 | |||
1109 | n_task=1; /* incremente il numero dei task (ha creato l'elicottero */ |
||
1110 | |||
1111 | /*Attesa di un carattere per creare un veicolo */ |
||
1112 | c = keyb_getch(BLOCK); |
||
1113 | do { |
||
1114 | if (((c == 'c')||(c=='s')||(c=='l')) && (n_task < MAX_V)) /* in base al tasto premuto crea il task opportuno */ |
||
1115 | { |
||
1116 | if (c == 'l') /* definisce e crea il task autolenta */ |
||
1117 | { |
||
1118 | kern_printf("lenta"); |
||
1119 | hard_task_default_model (autolenta); |
||
1120 | hard_task_def_ctrl_jet (autolenta); |
||
1121 | hard_task_def_arg (autolenta, (void *)n_task); |
||
1122 | hard_task_def_wcet (autolenta, wcet); |
||
1123 | hard_task_def_mit (autolenta, periodo); |
||
1124 | hard_task_def_group (autolenta, GRUPPO); |
||
1125 | hard_task_def_usemath (autolenta); |
||
1126 | pid = task_create ("autolenta",auto_lenta, &autolenta, NULL); |
||
1127 | } |
||
1128 | else |
||
1129 | if (c == 's') /* definisce e crea il task autoveloce */ |
||
1130 | { |
||
1131 | hard_task_default_model (autoveloce); |
||
1132 | hard_task_def_ctrl_jet (autoveloce); |
||
1133 | hard_task_def_arg (autoveloce, (void *)n_task); |
||
1134 | hard_task_def_wcet (autoveloce, wcet); |
||
1135 | hard_task_def_mit (autoveloce, periodo); |
||
1136 | hard_task_def_group (autoveloce, GRUPPO); |
||
1137 | hard_task_def_usemath (autoveloce); |
||
1138 | pid = task_create ("autoveloce",auto_veloce, &autoveloce, NULL); |
||
1139 | } |
||
1140 | else |
||
1141 | if (c == 'c') /* definisce e crea il task autocarro */ |
||
1142 | { |
||
1143 | hard_task_default_model (autocarro); |
||
1144 | hard_task_def_ctrl_jet (autocarro); |
||
1145 | hard_task_def_arg (autocarro, (void *)n_task); |
||
1146 | hard_task_def_wcet (autocarro, wcet); |
||
1147 | hard_task_def_mit (autocarro, periodo); |
||
1148 | hard_task_def_group (autocarro, GRUPPO); |
||
1149 | hard_task_def_usemath (autocarro); |
||
1150 | pid = task_create ("camion",auto_carro, &autocarro, NULL); |
||
1151 | } |
||
1152 | |||
1153 | if (pid == NIL) /* nel caso in non si possano creare dei task chiude la grafica e con un messaggio segnala l'errore */ |
||
1154 | { |
||
1155 | grx_close(); |
||
1156 | perror("Non si puo' creare il task"); |
||
1157 | sys_abort(1); |
||
1158 | } |
||
1159 | |||
1160 | task_activate(pid); /* attiva i task */ |
||
1161 | n_task++; /* incrementa il numero dei task creati */ |
||
1162 | } |
||
1163 | |||
1164 | c = keyb_getch(BLOCK); |
||
1165 | |||
1166 | } while (c != ESC); /* termino il tutto solo quando e' stato premuto il tasto esc */ |
||
1167 | |||
1168 | sys_end(); /* esco dal sistema */ |
||
1169 | |||
1170 | return 0; |
||
1171 | } |