Blame |
Last modification |
View Log
| RSS feed
#ifndef _PLANE_HEADER_
#include "plane.h"
#endif
#include <modules/cabs.h>
#define PLANEINFODIST 200
#define MAXPLANEINFO 5
sem_t mutex_i
; /* mutex to protect i */
int i
= 0; /* number of tasks created */
int reg_tasks
[MAX_PLANES
];
int num
=0;
void draw_plane
(int x
, int y
, int c
, int id
, int p_size
)
{
char temp
[3];
sprintf(temp
,"%d",id
);
sem_wait
(&graphics_mutex
);
grx_circle
(x
, y
, p_size
,c
);
grx_text
(temp
,x
-p_size
/2, y
-p_size
/2,black
,c
);
sem_post
(&graphics_mutex
);
}
void i_plus_1
(void)
{
sem_wait
(&mutex_i
);
i
++;
sem_post
(&mutex_i
);
}
int get_i
(void)
{
int j
;
sem_wait
(&mutex_i
);
j
= i
;
sem_post
(&mutex_i
);
return j
;
}
TASK plane
(void *arg
)
{
int ox
, oy
, fx
,fy
,dx
,dy
;
int stepx
, stepy
;
int planeid
= (int)(arg
);
int plane_size
;
int SCALING_FACTOR
;
// char temp1[3];
// char *tempcabptr;
int initx
,inity
;
int fdestx
,fdesty
;
int reached
=0;
char *cab_ptr
;
//char *atc_cab_ptr;
ox
= airports
[aeroplanes
[planeid
].
src_airport_id].
x;
oy
= airports
[aeroplanes
[planeid
].
src_airport_id].
y;
fx
= airports
[aeroplanes
[planeid
].
dest_airport_id].
x;
fy
= airports
[aeroplanes
[planeid
].
dest_airport_id].
y;
plane_size
= planeinfo
[aeroplanes
[planeid
].
model_id].
planesize;
atcplanecabmsg
[planeid
].
written='N';
atcplanecabmsg
[planeid
].
xtemp=fx
;
atcplanecabmsg
[planeid
].
ytemp=fy
;
//tempcabptr=cab_reserve(atc_plane_cab_id[planeid]);
//memcpy(tempcabptr,&atcplanecabmsg[planeid],sizeof(atcplanecab));
//cab_putmes(atc_plane_cab_id[planeid],tempcabptr);
initx
=ox
;
inity
=oy
;
fdestx
=fx
;
fdesty
=fy
;
draw_plane
(ox
, oy
, red
,planeid
,plane_size
);
draw_plane
(fx
, fy
, blue
,planeid
,plane_size
);
int fraction
;
//SCALING_FACTOR = (int)(aeroplanes[planeid].curr_speed/SCALE_DIST);
SCALING_FACTOR
=1;
while(1)
{
dy
= fy
- oy
;
dx
= fx
- ox
;
if (dy
< 0) { dy
= -dy
; stepy
= -1*SCALING_FACTOR
;} else { stepy
= 1*SCALING_FACTOR
;}
if (dx
< 0) { dx
= -dx
; stepx
= -1*SCALING_FACTOR
;} else { stepx
= 1*SCALING_FACTOR
;}
dy
<<= 1; // dy is now 2*dy
dx
<<= 1; // dx is now 2*dx
if (dx
> dy
)
{
fraction
= dy
- (dx
>> 1); // same as 2*dy - dx
while (ox
!= fx
)
{
if (fdestx
-ox
<PLANE_AIRPORT_DIST
)
{
aeroplanes
[planeid
].
curr_speed=aeroplanes
[planeid
].
curr_speed-aeroplanes
[planeid
].
curr_speed/6; //to reduce the speed of the aeroplane while landing
if (abs(stepy
)>1)
stepy
=stepy
/SCALING_FACTOR
;
if (abs(stepx
)>1)
stepx
=stepx
/SCALING_FACTOR
;
}
else if(abs(fx
-ox
)<10)
{
if (abs(stepy
)>1)
stepy
=stepy
/SCALING_FACTOR
;
if (abs(stepx
)>1)
stepx
=stepx
/SCALING_FACTOR
;
}
/*
atc_cab_ptr=cab_getmes(atc_plane_cab_id[planeid]);
memcpy(&atcplanecabmsg[planeid],atc_cab_ptr,sizeof(atcplanecab));
cab_unget(atc_plane_cab_id[planeid],atc_cab_ptr);
sprintf(temp1,"Written:%c Xtemp:%d YTemp:%d",atcplanecabmsg[planeid].written,atcplanecabmsg[planeid].xtemp,atcplanecabmsg[planeid].ytemp);
grx_text(temp1,100,120,white,black);
if (atcplanecabmsg[planeid].written == 'Y')
{
aeroplanes[planeid].xtemp=atcplanecabmsg[planeid].xtemp;
aeroplanes[planeid].ytemp=atcplanecabmsg[planeid].ytemp;
}
*/
if (aeroplanes
[planeid
].
xtemp!=fdestx
|| aeroplanes
[planeid
].
ytemp!=fdesty
) //read from CAB on which ATC writes
{
fx
= aeroplanes
[planeid
].
xtemp; //read from CAB
fy
= aeroplanes
[planeid
].
ytemp; //read from CAB on which ATC writes
aeroplanes
[planeid
].
xtemp=fdestx
;
aeroplanes
[planeid
].
ytemp=fdesty
;
break;
}
draw_plane
(ox
, oy
, black
,planeid
,plane_size
); //to redraw the area on which the plane flew
if (fraction
>= 0)
{
oy
+= stepy
;
fraction
-= dx
; // same as fraction -= 2*dx
}
ox
+= stepx
;
fraction
+= dy
; // same as fraction -= 2*dy
draw_plane
(ox
, oy
, red
,planeid
,plane_size
); //to draw the new plane
aeroplanes
[planeid
].
currx = ox
; //write this data to the CAB for ATC to read
aeroplanes
[planeid
].
curry = oy
; //write this data to the CAB for ATC to read
cab_ptr
=cab_reserve
(plane_atc_cab_id
[planeid
]);
memcpy(cab_ptr
,&aeroplanes
[planeid
],sizeof(aeroplane
));
cab_putmes
(plane_atc_cab_id
[planeid
],cab_ptr
);
task_endcycle
();
}
if (ox
==fx
)
{
if (fx
==fdestx
&& fy
==fdesty
)
reached
=1;
else
{
reached
=0;
fx
=fdestx
;
fy
=fdesty
;
}
}
}
else
{
int fraction
= dx
- (dy
>> 1);
while (oy
!= fy
)
{
if (fdestx
-ox
<PLANE_AIRPORT_DIST
)
{
aeroplanes
[planeid
].
curr_speed=aeroplanes
[planeid
].
curr_speed-aeroplanes
[planeid
].
curr_speed/6; //write on CAB for ATC to read
if (abs(stepy
)>1)
stepy
=stepy
/SCALING_FACTOR
;
if (abs(stepx
)>1)
stepx
=stepx
/SCALING_FACTOR
;
}
else if (abs(fx
-ox
)<10)
{
if (abs(stepy
)>1)
stepy
=stepy
/SCALING_FACTOR
;
if (abs(stepx
)>1)
stepx
=stepx
/SCALING_FACTOR
;
}
/*
atc_cab_ptr=cab_getmes(atc_plane_cab_id[planeid]);
memcpy(&atcplanecabmsg[planeid],atc_cab_ptr,sizeof(atcplanecab));
cab_unget(atc_plane_cab_id[planeid],atc_cab_ptr);
sprintf(temp1,"Written:%c Xtemp:%d YTemp:%d",atcplanecabmsg[planeid].written,atcplanecabmsg[planeid].xtemp,atcplanecabmsg[planeid].ytemp);
grx_text(temp1,100,130,white,black);
if (atcplanecabmsg[planeid].written == 'Y')
{
aeroplanes[planeid].xtemp=atcplanecabmsg[planeid].xtemp;
aeroplanes[planeid].ytemp=atcplanecabmsg[planeid].ytemp;
}
*/
//take mutex to access this structure
if (aeroplanes
[planeid
].
xtemp!=fdestx
|| aeroplanes
[planeid
].
ytemp!=fdesty
) //read from CAB on which ATC writes
{
fx
= aeroplanes
[planeid
].
xtemp; //read from CAB on which ATC writes
fy
= aeroplanes
[planeid
].
ytemp; //read from CAB on which ATC writes
aeroplanes
[planeid
].
xtemp=fdestx
;
aeroplanes
[planeid
].
ytemp=fdesty
;
break;
}
draw_plane
(ox
, oy
, black
,planeid
,plane_size
);
if (fraction
>= 0)
{
ox
+= stepx
;
fraction
-= dy
;
}
oy
+= stepy
;
fraction
+= dx
;
draw_plane
(ox
, oy
, red
,planeid
,plane_size
);
aeroplanes
[planeid
].
currx = ox
; //write on CAB fo ATC to read
aeroplanes
[planeid
].
curry = oy
; //write on CAB fo ATC to read
cab_ptr
=cab_reserve
(plane_atc_cab_id
[planeid
]);
memcpy(cab_ptr
,&aeroplanes
[planeid
],sizeof(aeroplane
));
cab_putmes
(plane_atc_cab_id
[planeid
],cab_ptr
);
task_endcycle
();
}
if (oy
==fy
)
{
if (fx
==fdestx
&& fy
==fdesty
)
reached
=1;
else
{
reached
=0;
fx
=fdestx
;
fy
=fdesty
;
}
}
}
if (reached
==1)
break;
}
aeroplanes
[planeid
].
is_flying=0; //write this, currx and curry on CAb for ATC to read to
cab_ptr
=cab_reserve
(plane_atc_cab_id
[planeid
]);
memcpy(cab_ptr
,&aeroplanes
[planeid
],sizeof(aeroplane
));
cab_putmes
(plane_atc_cab_id
[planeid
],cab_ptr
);
mutex_lock
(&mut_number_of_planes
);
number_of_planes
--;
if (number_of_planes
==0)
{
mutex_unlock
(&mut_number_of_planes
);
mutex_lock
(&mut_STARTSIM
);
if (STARTSIM
== 1)
STARTSIM
= 0;
mutex_unlock
(&mut_STARTSIM
);
}
else
{
mutex_unlock
(&mut_number_of_planes
);
}
}
TASK register_with_ATC
(void *arg
)
{
int myid
=(int)(arg
);
while(1)
{
if (aeroplanes
[myid
].
is_flying==0)
{
break;
}
aeroplanes
[myid
].
zone_id=floor((aeroplanes
[myid
].
currx-XMIN
) / GRID_SIZE
) + 4 * floor((aeroplanes
[myid
].
curry-YMIN
) / GRID_SIZE
);
task_endcycle
();
}
}
TASK display_plane_info
(void *arg
)
{
int tempid
;
int tempi
;
char displayinf
[25];
char display
[MAX_PLANES
];
grx_text
("AEROPLANE INFORMATION",XMIN
,YMAX
+2, white
, black
);
grx_line
(XMIN
, YMAX
+12, XMAX
, YMAX
+12, blue
);
aeroplane temp_aeroplanes
[MAX_PLANES
];
char *plane_cab_ptr
[MAX_PLANES
];
for(tempid
=0;tempid
<MAX_PLANES
;tempid
++)
{
display
[tempid
]='T';
}
while(1)
{
tempi
=get_i
();
sem_wait
(&graphics_mutex
);
for(tempid
=0;tempid
<tempi
;tempid
++)
{
plane_cab_ptr
[tempid
]=cab_getmes
(plane_atc_cab_id
[tempid
]);
memcpy(&temp_aeroplanes
[tempid
],plane_cab_ptr
[tempid
],sizeof(aeroplane
));
cab_unget
(plane_atc_cab_id
[tempid
],plane_cab_ptr
[tempid
]);
if (temp_aeroplanes
[tempid
].
is_flying==1 && display
[tempid
] =='T')
{
sprintf(displayinf
,"Plane Id : %d ",temp_aeroplanes
[tempid
].
id);
grx_text
(displayinf
,((tempid
%MAXPLANEINFO
)*PLANEINFODIST
)+XMIN
,YMAX
+20, white
, black
);
sprintf(displayinf
,"Model : %s ",planeinfo
[temp_aeroplanes
[tempid
].
model_id].
model);
grx_text
(displayinf
,((tempid
%MAXPLANEINFO
)*PLANEINFODIST
)+XMIN
,YMAX
+30, white
, black
);
sprintf(displayinf
,"Src Airport: %s ",airports
[temp_aeroplanes
[tempid
].
src_airport_id].
airportname);
grx_text
(displayinf
,((tempid
%MAXPLANEINFO
)*PLANEINFODIST
)+XMIN
,YMAX
+40, white
, black
);
sprintf(displayinf
,"Dst Airport: %s ",airports
[temp_aeroplanes
[tempid
].
dest_airport_id].
airportname);
grx_text
(displayinf
,((tempid
%MAXPLANEINFO
)*PLANEINFODIST
)+XMIN
,YMAX
+50, white
, black
);
sprintf(displayinf
,"Dept Time : %d ",temp_aeroplanes
[tempid
].
dept_time);
grx_text
(displayinf
,((tempid
%MAXPLANEINFO
)*PLANEINFODIST
)+XMIN
,YMAX
+60, white
, black
);
sprintf(displayinf
,"Arr Time : %d ",temp_aeroplanes
[tempid
].
arr_time);
grx_text
(displayinf
,((tempid
%MAXPLANEINFO
)*PLANEINFODIST
)+XMIN
,YMAX
+70, white
, black
);
sprintf(displayinf
,"Curr Speed : %d ",temp_aeroplanes
[tempid
].
curr_speed);
grx_text
(displayinf
,((tempid
%MAXPLANEINFO
)*PLANEINFODIST
)+XMIN
,YMAX
+80, white
, black
);
sprintf(displayinf
,"Curr X : %d ",temp_aeroplanes
[tempid
].
currx);
grx_text
(displayinf
,((tempid
%MAXPLANEINFO
)*PLANEINFODIST
)+XMIN
,YMAX
+90, white
, black
);
sprintf(displayinf
,"Curr Y : %d ",temp_aeroplanes
[tempid
].
curry);
grx_text
(displayinf
,((tempid
%MAXPLANEINFO
)*PLANEINFODIST
)+XMIN
,YMAX
+100, white
, black
);
sprintf(displayinf
,"Is Flying : %d ",temp_aeroplanes
[tempid
].
is_flying);
grx_text
(displayinf
,((tempid
%MAXPLANEINFO
)*PLANEINFODIST
)+XMIN
,YMAX
+110, white
, black
);
}
else if (temp_aeroplanes
[tempid
].
is_flying==0 && display
[tempid
] =='T' )
{
grx_box
(((tempid
%MAXPLANEINFO
)*PLANEINFODIST
)+XMIN
,YMAX
+20,((tempid
%MAXPLANEINFO
)*PLANEINFODIST
)+XMIN
+PLANEINFODIST
,YMAX
+120,black
);
display
[tempid
]='F';
}
}
sem_post
(&graphics_mutex
);
task_endcycle
();
}
}
void init_planes
()
{
char c
; /* character from keyboard */
number_of_planes
= 0; /* number of tasks created */
TIME temptime
,temptime2
;
struct timespec planetime
;
int src
,dest
;
int ox
,oy
,fx
,fy
;
int planeid
;
SOFT_TASK_MODEL m
; //model for the TASK to plane to move
SOFT_TASK_MODEL reg_msg
; //model for the TASK to register with ATC
SOFT_TASK_MODEL disp_info
; //model for the TASK to display the information of the planes
int local_i
=0; /* local copy of i */
sem_init
(&mutex_i
,0,1);
int local_no_of_planes
=0;
/* The program waits a space to create a plane */
c
= keyb_getch
(BLOCK
);
//activate the display plane info TASK
soft_task_default_model
(disp_info
);
soft_task_def_level
(disp_info
,1);
soft_task_def_ctrl_jet
(disp_info
);
//soft_task_def_arg (disp_info, (void *)local_i);
soft_task_def_met
(disp_info
, DISPPLANEINFOWCET
);
soft_task_def_group
(disp_info
, PLANEGROUP
); //modify this later
soft_task_def_period
(disp_info
, DISPPLANEINFOPERIOD
);
soft_task_def_usemath
(disp_info
);
disp
= task_create
("DspPlane", display_plane_info
, &disp_info
, NULL
);
if (disp
== NIL
)
{
grx_close
();
perror("Could not create task <RegWithATC>");
sys_abort
(1);
}
task_activate
(disp
);
do {
planeid
= local_i
= get_i
();
mutex_lock
(&mut_number_of_planes
);
local_no_of_planes
=number_of_planes
;
mutex_unlock
(&mut_number_of_planes
);
if ((c
== ' ') && (local_i
< MAX_PLANES
) && (local_no_of_planes
<MAX_SIMUL_PLANES
))
{
srand(sys_gettime
(NULL
));
src
= (int)rand()%(NUM_OF_AIRPORTS
); // generate random source and destination airports
//check that the previous 2 aeroplanes have not started from the same airport
dest
= (int)rand()%(NUM_OF_AIRPORTS
);
if (dest
==src
)
{
if (dest
==0)
dest
=NUM_OF_AIRPORTS
-1;
else
dest
=(dest
+src
)%NUM_OF_AIRPORTS
;
}
ox
= airports
[src
].
x;
oy
= airports
[src
].
y;
fx
= airports
[dest
].
x;
fy
= airports
[dest
].
y;
temptime
= sys_gettime
(&planetime
);
temptime
= ((planetime.
tv_sec / TIME_SPEED
) % 24) * 100 ;
//populate the aeroplane structure with data
aeroplanes
[planeid
].
id = planeid
;
aeroplanes
[planeid
].
model_id = planeid
%NUM_OF_AEROPLANE_MODELS
;
aeroplanes
[planeid
].
src_airport_id = airports
[src
].
id;
aeroplanes
[planeid
].
dest_airport_id = airports
[dest
].
id;
aeroplanes
[planeid
].
xtemp=fx
;
aeroplanes
[planeid
].
ytemp=fy
;
aeroplanes
[planeid
].
curr_speed=planeinfo
[aeroplanes
[planeid
].
model_id].
max_speed;
temptime2
= temptime
+ ((sqrt((fy
-oy
)*(fy
-oy
)+(fx
-ox
)*(fx
-ox
))*SCALE_DIST
) / aeroplanes
[planeid
].
curr_speed);
aeroplanes
[planeid
].
curr_altitude=(int)((rand()%1)*planeinfo
[aeroplanes
[planeid
].
model_id].
max_altitude);
aeroplanes
[planeid
].
dept_time = temptime
;
aeroplanes
[planeid
].
arr_time = temptime2
;
aeroplanes
[planeid
].
is_flying=1;
//create the CABS
plane_atc_cab_id
[planeid
]= cab_create
(plane_atc
[planeid
],sizeof(aeroplane
),2); //this cab will be used by the plane task to write in. The ATC will read from this task
// atc_plane_cab_id[planeid]= cab_create(atc_plane[planeid],sizeof(atcplanecab),2);
//this cab will be used by the ATC to write new coordinates to the plane
soft_task_default_model
(m
);
soft_task_def_level
(m
,1);
soft_task_def_ctrl_jet
(m
);
soft_task_def_arg
(m
, (void *)local_i
);
soft_task_def_met
(m
, PLANEWCET
);
soft_task_def_period
(m
, PLANEPERIOD
);
soft_task_def_group
(m
, PLANEGROUP
);
soft_task_def_usemath
(m
);
pid
[local_i
] = task_create
("Plane", plane
, &m
, NULL
);
if (pid
[local_i
] == NIL
)
{
grx_close
();
perror("Could not create task <plane>");
sys_abort
(1);
}
task_activate
(pid
[local_i
]);
//activate the register message TASK
soft_task_default_model
(reg_msg
);
soft_task_def_level
(reg_msg
,1);
soft_task_def_ctrl_jet
(reg_msg
);
soft_task_def_arg
(reg_msg
, (void *)local_i
);
soft_task_def_met
(reg_msg
, REGWITHATCWCET
);
soft_task_def_group
(reg_msg
, PLANEGROUP
); //modify this later
soft_task_def_period
(reg_msg
, REGWITHATCPERIOD
);
soft_task_def_usemath
(reg_msg
);
pid2
= task_create
("RegToATC", register_with_ATC
, ®_msg
, NULL
);
if (pid2
== NIL
)
{
grx_close
();
perror("Could not create task <RegToATC>");
sys_abort
(1);
}
task_activate
(pid2
);
i_plus_1
();
mutex_lock
(&mut_number_of_planes
);
++number_of_planes
;
mutex_unlock
(&mut_number_of_planes
);
if (local_i
+1>0)
{
mutex_lock
(&mut_STARTSIM
);
STARTSIM
= 1;
mutex_unlock
(&mut_STARTSIM
);
}
}
c
= keyb_getch
(BLOCK
);
} while (c
!= ESC
);
sys_end
();
}