Subversion Repositories shark

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

#include <kernel/kern.h>   //include the SHARK kernel header
#include <drivers/glib.h>  //include the graphics library
#include <drivers/keyb.h>  //include the keyboard library
#include <semaphore.h>     //include the semaphore library
#include <stdlib.h>        //include the standard library
#include <math.h>          //include the math library for random
#include <string.h>

#ifndef _ATCSIM_HEADER_
#include "atcsim.h"
#endif

#ifndef _SIM_AREA_HEADER_
#include "sim_area.h"
#endif

#ifndef _INPUT_
#include "input.h"
#endif

#ifndef _CONST_
#include "constants.h"
#endif

extern sem_t mut_planeinzone[MAX_ATCS][MAX_PLANES];
char *plane_cab_ptr1[MAX_PLANES];
aeroplane cabmsg_aeroplanes1[MAX_PLANES];
PID tid[MAX_ATCS];

extern int STARTSIM;
extern int get_i();
extern aeroplane aeroplanes[MAX_PLANES];

extern airport airports[NUM_OF_AIRPORTS];
extern atc atcs[MAX_ATCS];
extern mutex_t mut_number_of_planes;

aeroplane cabmsg_aeroplanes2[MAX_PLANES];
atcplanecab cabmsg_atc[MAX_PLANES];

int planeinzone[MAX_ATCS][MAX_PLANES];

void DoesCollide(int myid,int no_of_planes)
{
        int id,id2;
        int currx1,curry1,destx1,desty1,speed1,currx2,curry2,destx2,desty2,speed2,srcx2,srcy2,srcx1,srcy1;

        int src_apid1,dest_apid2,tempx1,tempx2,tempy1,tempy2,resx,resy;
        int gxmin,gymin,gxmax,gymax;

        int cx1mmd,cx1pmd,cx2mmd,cx2pmd,cy1mmd,cy1pmd,cy2mmd,cy2pmd;
        float pdistance,a1,a2,b1,b2,c1,c2,d1,d2,delta;
        char *plane_cab_ptr2[MAX_PLANES];
//      char *atc_cab_ptr1,*atc_cab_ptr2;

        char temp[100];

        int finalx1=-1,finalx2=-1,finaly1=-1,finaly2=-1;


        for(id=0;id<no_of_planes;id++)
        {
                        plane_cab_ptr2[id]=cab_getmes(plane_atc_cab_id[id]);
                        memcpy(&cabmsg_aeroplanes2[id],plane_cab_ptr2[id],sizeof(aeroplane));
                        cab_unget(plane_atc_cab_id[id],plane_cab_ptr2[id]);
        }

        //Getting the starting and ending co-ordinates of the 2 planes
        for(id=0;id<no_of_planes-1;id++)
        {
                sem_wait(&mut_planeinzone[myid][id]);
                if (planeinzone[myid][id]!=NOTMYZONE && cabmsg_aeroplanes2[planeinzone[myid][id]].is_flying == 1)
                {
                        currx1=cabmsg_aeroplanes2[planeinzone[myid][id]].currx;
                        curry1=cabmsg_aeroplanes2[planeinzone[myid][id]].curry;

                        tempx1=cabmsg_aeroplanes2[planeinzone[myid][id]].xtemp;
                        tempy1=cabmsg_aeroplanes2[planeinzone[myid][id]].ytemp;

                        destx1=airports[cabmsg_aeroplanes2[planeinzone[myid][id]].dest_airport_id].x;
                        desty1=airports[cabmsg_aeroplanes2[planeinzone[myid][id]].dest_airport_id].y;

                        srcx1=airports[cabmsg_aeroplanes2[planeinzone[myid][id]].src_airport_id].x;
                        srcy1=airports[cabmsg_aeroplanes2[planeinzone[myid][id]].src_airport_id].y;

                        speed1=cabmsg_aeroplanes2[planeinzone[myid][id]].curr_speed;

                        src_apid1  = cabmsg_aeroplanes2[planeinzone[myid][id]].src_airport_id;

                        sem_post(&mut_planeinzone[myid][id]);

                        cx1mmd = currx1-MIN_DIST/2;
                        if (cx1mmd < XMIN) cx1mmd = XMIN+10;

                        cx1pmd = currx1+MIN_DIST/2;
                        if (cx1pmd > XMAX) cx1pmd = XMAX-10;

                        cy1mmd = curry1-MIN_DIST/2;
                        if (cy1mmd < YMIN) cy1mmd = YMIN+10;

                        cy1pmd = curry1+MIN_DIST/2;
                        if (cy1pmd > YMAX) cy1pmd = YMAX-10;

                        for( id2 = id+1 ; id2 < no_of_planes; id2++ )
                        {
                                sem_wait(&mut_planeinzone[myid][id2]);
                                if (planeinzone[myid][id2]!=NOTMYZONE && cabmsg_aeroplanes2[planeinzone[myid][id2]].is_flying == 1)
                                {
                                        dest_apid2 = cabmsg_aeroplanes2[planeinzone[myid][id2]].dest_airport_id;

                                        currx2=cabmsg_aeroplanes2[planeinzone[myid][id2]].currx;
                                        curry2=cabmsg_aeroplanes2[planeinzone[myid][id2]].curry;

                                        tempx2=cabmsg_aeroplanes2[planeinzone[myid][id2]].xtemp;
                                        tempy2=cabmsg_aeroplanes2[planeinzone[myid][id2]].ytemp;

                                        destx2=airports[cabmsg_aeroplanes2[planeinzone[myid][id2]].dest_airport_id].x;
                                        desty2=airports[cabmsg_aeroplanes2[planeinzone[myid][id2]].dest_airport_id].y;

                                        srcx2=airports[cabmsg_aeroplanes2[planeinzone[myid][id2]].src_airport_id].x;
                                        srcy2=airports[cabmsg_aeroplanes2[planeinzone[myid][id2]].src_airport_id].y;

                                        speed2=cabmsg_aeroplanes2[planeinzone[myid][id2]].curr_speed;
                                        sem_post(&mut_planeinzone[myid][id2]);
                                        cx2mmd = currx2-MIN_DIST/2;
                                        if (cx2mmd < XMIN) cx2mmd = XMIN+10;

                                        cx2pmd = currx2+MIN_DIST/2;
                                        if (cx2pmd > XMAX) cx2pmd = XMAX-10;

                                        cy2mmd = curry2-MIN_DIST/2;
                                        if (cy2mmd < YMIN) cy2mmd = YMIN+10;

                                        cy2pmd = curry2+MIN_DIST/2;
                                        if (cy2pmd > YMAX) cy2pmd = YMAX-10;

                                        pdistance=sqrt((currx2-currx1)*(currx2-currx1) + (curry2-curry1)*(curry2-curry1));
                                        if ( pdistance < MIN_DIST )
                                        {
                                                if((currx1-destx1)!=0)  a1 = (curry1-desty1)/(currx1-destx1);
                                                else    a1 = 0.0;
                                                b1=-1;c1=-curry1;
                                                if ((currx2-destx2)!=0) a2=(curry2-desty2)/(currx2-destx2);
                                                        else    a2=0.0;
                                                b2=-1;c2=-curry2;
                                                delta=a1*b2-a2*b1;//The determinant used for division
                                                resx=0;resy=0;  //The result of solving the two equations.
                                                if(delta)
                                                {
                                                        resx=(int)((c1*b2-c2*b1)/delta);
                                                        resy=(int)((a1*c2-a2*c1)/delta);

                                                        gxmin = atcs[myid].x-GRID_SIZE/2;
                                                        gxmax = atcs[myid].x+GRID_SIZE/2;
                                                        gymin = atcs[myid].y-GRID_SIZE/2;
                                                        gymax = atcs[myid].y+GRID_SIZE/2;

                                                        //Now to check if the lines really collide within the simulation area
                                                        if ((resx > gxmin)  && (resx < gxmax) && (resy > gymin) && (resy < gymax))
                                                        {
                                                                //There is definitely an intersection within the area but need not be a collision
                                                                //So calculate the distance of the two planes from the colliding point
                                                                //And based on their speeds get whether they reach there at the same time
                                                                        d1=sqrt((resx-currx1)*(resx-currx1) + (resy-curry1)*(resy-curry1));
                                                                        d2=sqrt((resx-currx2)*(resx-currx2) + (resy-curry2)*(resy-curry2));
                                                                //These are the 2 distances of the 2 planes from the intersecting point.
                                                                //if ((abs((d1*SCALE_DIST/speed1)*60-(d2*SCALE_DIST/speed2)*60))<5)
                                                                if (floor(d1/speed1) == floor(d2/speed2))
                                                                {
                                                                        //Condition for no collision
                                                                        if(((curry1<curry2)&&(tempy1<tempy2))||((currx1<currx2)&&(tempx1<tempx2))){}
                                                                        else if(currx1<tempx1)//&&curry1>tempy1)
                                                                                finalx1=cx1pmd;
                                                                        else if(curry1<tempy1)//&&curry1>tempy1)
                                                                                finaly1=cy1pmd;

                                                                }
                                                        }
                                                        //else The planes collide outside our area;
                                                }
                                                else
                                                {
                                                        if (srcx1 == tempx2 && srcy1 == tempy2)
                                                        {
                                                                finalx1=cx1pmd+30;
                                                                //finaly1=cy1pmd;
                                                                //finalx2=cx2mmd;
                                                                //finaly2=cy2pmd;
                                                        }
                                                        else if (srcx1 == tempx2 && tempy1 > tempy2)
                                                        {
                                                                finalx1=cx1pmd;
                                                                finaly1=cy1pmd;
                                                                finalx2=cx2mmd;
                                                                finaly2=cy2mmd;
                                                        }
                                                        else if (srcx1 == tempx2 && tempy1 < tempy2)
                                                        {
                                                                finalx1=cx1mmd;
                                                                finaly1=cy1mmd;
                                                                finalx2=cx2pmd;
                                                                finaly2=cy2pmd;
                                                        }
                                                        else if (srcy1 == tempy2 && tempx1 > tempx2)
                                                        {
                                                                finalx1=cx1pmd;
                                                                finaly1=cy1mmd;
                                                                finalx2=cx2mmd;
                                                                finaly2=cy2pmd;
                                                        }
                                                        else if (srcy1 == tempy2 && tempx1 < tempx2)
                                                        {
                                                                finalx1=cx1mmd;
                                                                finaly1=cy1pmd;
                                                                finalx2=cx2pmd;
                                                                finaly2=cy2mmd;
                                                        }
                                                        else if ((srcx1-srcx2+tempx1-tempx2) && (tempy1 > tempy2))
                                                        {
                                                                finalx1=cx1pmd;
                                                                finaly1=cy1pmd;
                                                                finalx2=cx2mmd;
                                                                finaly2=cy2mmd;

                                                        }
                                                        else if ((srcx1-srcx2+tempx1-tempx2) && (tempy1 < tempy2))
                                                        {
                                                                finalx1=cx1mmd;
                                                                finaly1=cy1mmd;
                                                                finalx2=cx2pmd;
                                                                finaly2=cy2pmd;
                                                        }
                                                        else if ((srcy1-srcy2+tempy1-tempy2) && (tempx1 > tempx2))
                                                        {
                                                                finalx1=cx1pmd;
                                                                finaly1=cy1mmd;
                                                                finalx2=cx2mmd;
                                                                finaly2=cy2pmd;
                                                        }
                                                        else if ((srcy1-srcy2+tempy1-tempy2) && (tempx1 < tempx2))
                                                        {
                                                                finalx1=cx1mmd;
                                                                finaly1=cy1pmd;
                                                                finalx2=cx2pmd;
                                                                finaly2=cy2mmd;
                                                        }

                                                }
                                                //keep mutex for the aeroplane
                                                sem_wait(&mut_planeinzone[myid][id]);
                                                if (finalx1!=-1)
                                                        aeroplanes[planeinzone[myid][id]].xtemp=finalx1;
                                                if (finaly1!=-1)
                                                        aeroplanes[planeinzone[myid][id]].ytemp=finaly1;
                                                sem_post(&mut_planeinzone[myid][id]);
                                                sem_wait(&mut_planeinzone[myid][id2]);
                                                if (finalx2!=-1)
                                                        aeroplanes[planeinzone[myid][id2]].xtemp=finalx2;
                                                if (finaly2!=-1)
                                                        aeroplanes[planeinzone[myid][id2]].ytemp=finaly2;
                                                sem_post(&mut_planeinzone[myid][id2]);

                                                if ((finalx1 != -1 || finaly1 != -1) || (finalx2 != -1 || finaly2 != -1))
                                                {
                                        //              cabmsg_atc[id].written='Y';
                                        //              cabmsg_atc[id2].written='Y';
                                        //              cabmsg_atc[id].xtemp=cx1mmd;
                                                //      cabmsg_atc[id].ytemp=cy1pmd;
                                        //              cabmsg_atc[id2].xtemp=cx2pmd;
                                                //      cabmsg_atc[id2].ytemp=cy2mmd;

                                                //      atc_cab_ptr1=cab_reserve(atc_plane_cab_id[id]);
                                                //      memcpy(atc_cab_ptr1,&cabmsg_atc[id],sizeof(atcplanecab));
                                                //      cab_putmes(atc_plane_cab_id[id],atc_cab_ptr1);

                                                        //atc_cab_ptr2=cab_reserve(atc_plane_cab_id[id2]);
                                                        //memcpy(atc_cab_ptr2,&cabmsg_atc[id2],sizeof(atcplanecab));
                                                        //cab_putmes(atc_plane_cab_id[id2],atc_cab_ptr2);

                                                        sprintf(temp,"ATC %d detected collision between %d and %d     ",myid,id,id2);
                                                        grx_text(temp,XMIN,YMIN-10,red,black);
                                                }
                                        }//end of if loop inside the second for
                                }
                                else
                                {
                                        sem_post(&mut_planeinzone[myid][id2]);
                                }
                        }
                }
                else
                {
                        sem_post(&mut_planeinzone[myid][id]);
                }
        }
}  // End of DoesCollide

TASK recv_reg(void *arg)
{
        int atc_id = (int)(arg);
        int plane_id;
        int count=0;
        while(1)
        {
                for(plane_id=0;plane_id<get_i();++plane_id)
                {
                        sem_wait(&mut_planeinzone[atc_id][plane_id]);
                        if (planeinzone[atc_id][plane_id]==plane_id)
                                ++count;
                        sem_post(&mut_planeinzone[atc_id][plane_id]);
                }

                if(count>1)
                {
                        DoesCollide(atc_id,plane_id); //check if all the planes in my zone collide
                }
                count=0;
                task_endcycle();
        }
}

TASK manager_ATC(void *arg)
{
        int plane_id,atc_id;
        while(1)
        {
                for (atc_id=0;atc_id<MAX_ATCS;atc_id++)
                {
                        for(plane_id=0;plane_id<get_i();++plane_id)
                        {
                                //check if the plane is actually flying
                                plane_cab_ptr1[plane_id]=cab_getmes(plane_atc_cab_id[plane_id]);
                                memcpy(&cabmsg_aeroplanes1[plane_id],plane_cab_ptr1[plane_id],sizeof(aeroplane));
                                cab_unget(plane_atc_cab_id[plane_id],plane_cab_ptr1[plane_id]);

                                if (cabmsg_aeroplanes1[plane_id].is_flying == 1)  //this value will be read from the CAB
                                {
                                        if (cabmsg_aeroplanes1[plane_id].zone_id == atc_id)  //this zone id will be compared by the manager ATC thread and that will activate the ATC of that zone
                                        {
                                                sem_wait(&mut_planeinzone[atc_id][plane_id]);
                                                planeinzone[atc_id][plane_id]=plane_id;
                                                sem_post(&mut_planeinzone[atc_id][plane_id]);
                                                task_activate(tid[atc_id]);
                                        }
                                        else
                                        {
                                                sem_wait(&mut_planeinzone[atc_id][plane_id]);
                                                planeinzone[atc_id][plane_id]=NOTMYZONE;  //since plane is not flying
                                                sem_post(&mut_planeinzone[atc_id][plane_id]);
                                                task_disable(tid[atc_id]);
                                        }
                                }
                                else
                                {
                                        sem_wait(&mut_planeinzone[atc_id][plane_id]);
                                        planeinzone[atc_id][plane_id]=NOTMYZONE;
                                        sem_post(&mut_planeinzone[atc_id][plane_id]);
                                        task_disable(tid[atc_id]);
                                }
                        }
                }
                task_endcycle();
        }
}


TASK display_ATC_info(void *arg)  //this shud also display which planes are colliding
{
        int i,j;
        char temp[100];
        int printed[MAX_ATCS];
        int no_of_planes_in_zone[MAX_ATCS];

        char temp_p_in[3];
        char p_in_zone[100];
        strcpy(p_in_zone," ");
        char clear[30];
        sem_wait(&graphics_mutex);
        grx_text("ATC     PLANES IN ZONE",XMAX+10,(int)(YMIN+YMAX/1.5),green,black);
        grx_text("----------------------",XMAX+10,(int)(10+YMIN+YMAX/1.5),green,black);
        for (i=0;i<MAX_ATCS;i++)
        {
                sprintf(temp," %d  : ",i);
                grx_text(temp,XMAX+10,(int)((i*10)+YMIN+YMAX/1.5+20),green,black);
                printed[i]=0;
                no_of_planes_in_zone[i]=0;
        }
        sem_post(&graphics_mutex);
        while(1)
        {
                for (i=0;i<MAX_ATCS;i++)
                {
                        for (j=0;j<MAX_PLANES;j++)
                        {
                                sem_wait(&mut_planeinzone[i][j]);
                                if (cabmsg_aeroplanes1[j].is_flying==1 && planeinzone[i][j]==j)
                                {
                                        sem_post(&mut_planeinzone[i][j]);
                                        sprintf(temp_p_in,"%d ",j);
                                        strcat(p_in_zone,temp_p_in);
                                        ++no_of_planes_in_zone[i];
                                }
                                else
                                {
                                        sem_post(&mut_planeinzone[i][j]);
                                }

                                if (no_of_planes_in_zone[i] < printed[i])
                                {
                                        strcpy(clear,"                  ");
                                        sem_wait(&graphics_mutex);
                                        grx_text(clear,XMAX+65,(int)((i*10)+YMIN+YMAX/1.5+20),black,black);
                                        sem_post(&graphics_mutex);
                                        printed[i]=0;
                                        strcpy(p_in_zone," ");
                                }
                                else
                                {
                                        printed[i]=no_of_planes_in_zone[i];
                                        sem_wait(&graphics_mutex);
                                        grx_text(p_in_zone,XMAX+65,(int)((i*10)+YMIN+(YMAX/1.5)+20),white,black);
                                        sem_post(&graphics_mutex);
                                }
                        }
                        no_of_planes_in_zone[i]=0;
                        strcpy(p_in_zone," ");
                }
                task_endcycle();
        }
}

void init_atcs()
{
        PID tid2,m_tid;
        int n_atcs;
        int i,j;
        SOFT_TASK_MODEL m;
        SOFT_TASK_MODEL manager_atc;
        SOFT_TASK_MODEL disp_atc;

        for (i=0;i<MAX_ATCS;i++)
                for (j=0;j<MAX_PLANES;j++)
                {
                        sem_wait(&mut_planeinzone[i][j]);
                        planeinzone[i][j]=NOTMYZONE;
                        sem_post(&mut_planeinzone[i][j]);
                }

        soft_task_default_model(manager_atc);
        soft_task_def_level(manager_atc,1);
        soft_task_def_ctrl_jet (manager_atc);
        //soft_task_def_arg (manager_atc, (void *)n_atcs);
        soft_task_def_met (manager_atc, MANAGERATCWCET);
        soft_task_def_group (manager_atc, ATCGROUP);  //modify this later
        soft_task_def_period (manager_atc, MANAGERATCPERIOD);
        soft_task_def_usemath (manager_atc);
        m_tid = task_create("MgrATC", manager_ATC, &manager_atc, NULL);
        if (m_tid == NIL)
        {
                grx_close();
                cprintf("Could not create task <MgrATC>");
                sys_end();
        }
        task_activate(m_tid); //manager task will activate and deactivate the other ATC tasks as planes go in their zone



        for (n_atcs=0;n_atcs<MAX_ATCS;n_atcs++)  //create all the ATC tasks but do not activate them
        //the manager thread will activate and deactivate these tasks
        {
                //activate the receive message TASK
                soft_task_default_model(m);
                soft_task_def_level(m,1);
                soft_task_def_ctrl_jet (m);
                soft_task_def_arg (m, (void *)n_atcs);
                soft_task_def_met (m, RECVMSGWCET);
                soft_task_def_group (m, ATCGROUP);  //modify this later
                soft_task_def_period (m, RECVMSGPERIOD);
                soft_task_def_usemath (m);
                tid[n_atcs] = task_create("recv_reg", recv_reg, &m, NULL);
                if (tid[n_atcs] == NIL)
                {
                        grx_close();
                        cprintf("Could not create task <Recv_reg>");
                        sys_end();
                }
        }

        //activate the display ATC info TASK
        soft_task_default_model(disp_atc);
        soft_task_def_level(disp_atc,1);
        soft_task_def_ctrl_jet (disp_atc);
        soft_task_def_arg (disp_atc, (void *)n_atcs);
        soft_task_def_met (disp_atc, DISPATCWCET);
        soft_task_def_group (disp_atc, ATCGROUP);  //modify this later
        soft_task_def_period (disp_atc, DISPATCPERIOD);
        soft_task_def_usemath (disp_atc);
        tid2 = task_create("DispATC", display_ATC_info, &disp_atc, NULL);
        if (tid2 == NIL)
        {
                grx_close();
                cprintf("Could not create task <DispATC>");
                sys_end();
        }
        task_activate(tid2);
}