Subversion Repositories shark

Rev

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
}