Subversion Repositories shark

Rev

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, &reg_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();
}