Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1664 pj 1
#include "carfinal.h"
2
#include<modules/cabs.h>
3
 
4
/*--adding petrol station to cabs lets make it work baby!!----*/
5
/*----------------------------------------------------------------------
6
graphics functions:
7
1. hide_car: it repaints the screen after the car moves from an old position
8
2. draw_car: draws the car at its current position.The color of cars vary with their speeds
9
 
10
-------------------------------------------------------------------------*/
11
 
12
typedef struct{
13
        int x;
14
        int y;
15
        }Position;
16
Position ps;
17
CAB fuel;
18
 
19
/*[(MAX_C+2)]; all cars are readers and keyboard and mouse are writers*/
20
 
21
int  cari = 0;
22
sem_t carim;
23
 
24
Position itemp;
25
char *mcabptr,*kcabptr;
26
 
27
int hide_car(int x,int y)
28
{
29
        mutex_lock(&display_mutex);
30
                grx_box(x,y,x+10,y+10,background);
31
        mutex_unlock(&display_mutex);
32
        return 0;
33
 
34
}
35
 
36
int draw_car(int x,int y,int vmax)
37
{
38
        int x1 = (x+10)/2 - 2;
39
        int y1 = (y+10)/2;
40
        int x2 = (x+10)/2 + 2;
41
        int col;
42
        switch(vmax)
43
        {
44
                case 4:
45
                {
46
                        col = white;
47
                        break;
48
                }
49
                case 6:
50
                {
51
                        col = gray;
52
                        break;
53
                }
54
                case 8:
55
                {
56
                        col = blue;
57
                        break;
58
                }
59
                default:
60
                        col = yellow;
61
        }
62
        mutex_lock(&display_mutex);
63
                grx_box(x,y,x1,y1,background);
64
                grx_box(x,y,x+10,y+10,col);
65
                grx_box(x,y,x2,y1,background);
66
        mutex_unlock(&display_mutex);
67
        return 0;
68
}
69
/*--------------------Graphics functions End--------------------------------*/
70
 
71
/*-------------------------------------------------------------------------
72
TASK car:
73
Description:
74
        Modeling the car as a hard task
75
Time period:car_period as in carfinal.h
76
wcet:car_wcet as in carfinal.h
77
 
78
possible improvements:
79
The task could be subdivided into four tasks:
80
1. update(samples the current position of the physical task
81
2. Target find: gives the direction of destination(petrol station in this case)
82
3. Collision : tries to inform the car about impending collision
83
4. Display: tries to draw the car on the screen based on the desicions taken by update
84
In this model update and target are hard tasks while Display and collision are soft tasks
85
-------------------------------------------------------------------------*/
86
 
87
TASK  Car(void *arg)
88
{
89
 
90
/*organise the declarations*/
91
 
92
        int carid;
93
        int angv;
94
        char tmyprint[40];      /*characteristic of car*/
95
        int vc = 0,vmax,acc;
96
        float slope;
97
        int collisioncount = 0;
98
        /*for writing on the ports ..collision handling*/
99
        char namex[7],cordx[4]; //namex is :carx+<1..>cordx: the sampled coordiate data on screen*/
100
        char namey[7],cordy[4];
101
        char tmyprintx[40], tmyprinty[40];
102
 
103
                /*****************/
104
 
105
        /*position and color for the graphic*/
106
        int     x, y;
107
        int     ox, oy;
108
        float    dx, dy, da;
109
        double  alpha;
110
        Position carps;
111
        char *carcabptr;
112
 
113
        char carname[40];
114
 
115
        enum mybool warning,collide;
116
        unsigned long colw,colg,colr,coly;
117
 
118
        //cprintf("color value: %ul",i);
119
 
120
        collide = warning = false;
121
 
122
        /***this section:
123
        1. increment carcount
124
        2. give unique id to car
125
        3. creates ports for writing(sampling) its own position
126
        *****/
127
 
128
 
129
        carid = carcount++;
130
        sprintf (namex,"carx%d",carid); //converting the carid to string
131
        sprintf(namey,"cary%d",carid);
132
        px[carid] = port_create(namex,7*sizeof(char),1,STICK,WRITE);
133
        port_send(px[carid],"0",BLOCK);
134
        py[carid] = port_create(namey,7*sizeof(char),1,STICK,WRITE);
135
        port_send(py[carid],"0",carid);
136
 
137
/*******************/
138
 
139
        vmax = VEL- 2*(carid%3);
140
        cprintf(" vmax = %d" ,vmax);
141
        cprintf(" carid = %d",carid);    //possible values: 4,6,8
142
        angv = 30 + 15*(carid%3); //possible values: 30,45,60 depending on carid
143
        cprintf(" angv = %d",angv);
144
        acc = 1+ carid%2;        //possible values of acceleration : 1,2
145
/*********/
146
        cprintf("here i am 1");
147
        x= randomnumber(XMIN,XMAX);  /*if out of range start in the middle*/                    y=randomnumber(YMIN,YMAX);
148
        da =randomangle();
149
        cprintf("here i am 2");
150
 
151
        //converting to radians
152
        alpha = da * PI/180;
153
        colw = rgb16(255,255,255);      /* color car*/
154
        colg = rgb16(0,255,0);
155
        colr = rgb16(255,0,0);
156
        coly= rgb16(0,255,255);
157
        /*if(carid == 1)
158
                mutex_lock(&display_mutex);
159
  grx_text("I am here!!",XMIN,YMENU +80,30,0 );
160
                mutex_unlock(&display_mutex);
161
        cprintf("before the while loop");*/
162
        task_endcycle();
163
while (1/*collide == false*/)
164
{
165
        ox = x; /*saving the previous values*/
166
        oy = y;
167
 
168
        carcabptr = cab_getmes(fuel);
169
                memcpy(&carps,carcabptr,sizeof(Position));
170
        cab_unget(fuel,carcabptr);
171
 
172
        Px = carps.x;
173
        Py = carps.y;
174
 
175
        if(collisioncount == 0)
176
        {
177
 
178
                if(vc != vmax)
179
                {
180
                        vc+=acc;
181
                        if(vc>vmax)
182
                                vc = vmax;
183
                }
184
                if(Px - x != 0)
185
                {
186
                        slope = (Py - y)/(Px -x);
187
                        alpha = atan(slope);
188
                        if((Px-x)<0)
189
                        {
190
                                alpha = alpha+PI; //chaged here..in this verison
191
                        }
192
 
193
                }
194
                else
195
                        alpha = PI/2;
196
 
197
                }
198
                else
199
                {
200
                        collisioncount--;
201
                        if(collisioncount == 0)
202
                                warning = false;
203
                }
204
 
205
/*Collision Handling :syncronising with the tasks which have written to the ports*/
206
/**count is guaranteed to be equal to that of those taks that have written to the port*/
207
        func_collision(carid, x, y,&collisioncount,&collide,&warning,&alpha);
208
/***collsiion handling ends**********/
209
 
210
        if(warning == true)
211
        {
212
                if(vc >vmax/2)
213
                {
214
                        vc = vc - acc;
215
                        if(vc<vmax/2)
216
                                vc = vmax/2;
217
                }
218
        }
219
        dx = (float)(vc * cos(alpha)); //round of instead of error
220
        dy = (float)(vc * sin(alpha));
221
        x += dx;
222
        y += dy;
223
 
224
                        /*now check one thing :
225
                        1. is the new location close to petrol station
226
                        */
227
                /*checking if it reaches boundary*/
228
        boundary_check(&x,&y);
229
 
230
 
231
 
232
 
233
                /*checking if it reaches petrol station*/
234
        if((x == Px||x== Px-1||x== Px+1) && (y == Py||y == Py-1 ||y == Py+1))
235
        {
236
                x = randomnumber(XMIN,XMAX);
237
                y = randomnumber(YMIN,YMAX);
238
                da = randomangle();
239
                alpha = da * PI/180;
240
                sprintf(carname,"%d",carid);
241
                strcat(carname,"reached the station");
242
                mutex_lock(&display_mutex);
243
                grx_text(carname,XMIN,YMENU +70,30,0 );
244
                mutex_unlock(&display_mutex);
245
        /**behaviour expected: starts again at a diff position */
246
        }
247
 
248
        /*checking if it has collided*/
249
        if(collide == true)
250
        {
251
                /*sem_wait(&carim);
252
                cari--;
253
                sem_post(&carim);*/
254
 
255
                x = randomnumber(XMIN,XMAX);
256
                y=randomnumber(YMIN,YMAX);
257
                da =randomangle();
258
                alpha = da * PI/180;
259
                sprintf(carname,"%d",carid);
260
                strcat(carname,"collided!!");
261
                mutex_lock(&display_mutex);
262
                grx_text(carname,XMIN, YMENU +50,30,0 );
263
                mutex_unlock(&display_mutex);
264
                collide = false;
265
        }
266
 
267
        sprintf(cordx, "%d", x);        //sampling
268
        sprintf(cordy,"%d",y);          //sampling
269
        sprintf(tmyprintx,"X cord=%s ",cordx);
270
        sprintf(tmyprinty,"Y cord=%s ",cordy);
271
        sprintf(tmyprint,"CARID= %d",carid);
272
        strcat(tmyprintx,tmyprinty);
273
        strcat(tmyprint,tmyprintx);
274
        mutex_lock(&display_mutex);
275
        grx_text(tmyprint,XMIN,YMENU +110,30,0 );
276
        mutex_unlock(&display_mutex);
277
        port_send(px[carid],cordx,BLOCK);
278
        port_send(py[carid],cordy,BLOCK);
279
        hide_car(ox, oy);
280
        draw_car(x,y,vmax);
281
        task_endcycle();
282
 }
283
 
284
 
285
}
286
/*----------------------Task Car Ends --------------------------------------*/
287
 
288
 
289
/*------------------------------SYSTEM TERMINATION--------------------------
290
 This function is called when the system exits
291
---------------------------------------------------------------------------*/
292
 
293
void byebye(void *arg)
294
{
295
  grx_close();
296
  cprintf("Termination.");
297
}
298
 
299
/*---------------------------------------------------------------------------*/
300
 
301
 
302
/*---------------------------------------------------------------------
303
TASK Repaint_border
304
Description: created to repaint the borders
305
 
306
        NAME repaint_border
307
        met: car_wcet   (could be changed if required)
308
        Type:Soft Task
309
 
310
-----------------------------------------------------------------------*/
311
 
312
 
313
TASK repaint_border(void *arg)
314
{
315
        Position r;
316
        char *rcabptr;
317
 
318
  while(1)
319
    {
320
        rcabptr = cab_getmes(fuel);
321
                memcpy(&r,rcabptr,sizeof(Position));
322
        cab_unget(fuel,rcabptr);
323
 
324
      mutex_lock(&display_mutex);
325
      grx_rect(XMIN-D, YMIN-D, XMAX+D+2, YMAX+D+2, rgb16(0,255,0));
326
      grx_box(r.x,r.y,r.x+10,r.y+10,rgb16(255,255,0));
327
      mutex_unlock(&display_mutex);
328
      task_endcycle();
329
    }
330
}
331
/*----------------------------------TASK Repaint ends ----------------*/
332
 
333
 
334
/*-------io device handler functions---------------------------*/
335
/***handler for keyboard***/
336
void myhook(KEY_EVT *key1)
337
{
338
        int x,y,ox,oy;
339
        ox=itemp.x;
340
        oy=itemp.y;
341
 
342
        mutex_lock(&display_mutex);
343
        grx_rect(ox, oy, ox+10, oy+10, rgb16(0,0,0));
344
        mutex_unlock(&display_mutex);
345
 
346
        switch(key1->ascii)
347
        {
348
          case 'k':{itemp.y++;;break;}
349
          case 'j':{itemp.x--;break;}
350
          case 'i':{itemp.y--;break;}
351
          case 'l':{itemp.x++;break;}
352
        }
353
        x = itemp.x;
354
        y = itemp.y;
355
 
356
        kcabptr = cab_reserve(fuel);
357
                memcpy(kcabptr,&itemp,sizeof(Position));
358
        cab_putmes(fuel,kcabptr);
359
 
360
        mutex_lock(&display_mutex);
361
        grx_box(x, y, x+10, y+10, rgb16(255,255,0));
362
        mutex_unlock(&display_mutex);
363
}
364
 
365
 
366
 
367
/**********mouse control*********************/
368
void mouseHandler(MOUSE_EVT* evt)
369
{
370
        int x,y,ox,oy;
371
        char mx[20],my[20];
372
        ox=itemp.x;
373
        oy=itemp.y;
374
 
375
        x = itemp.x = evt->x;
376
        y = itemp.y = evt->y;
377
 
378
        mutex_lock(&display_mutex);
379
        grx_box(ox,oy,ox+10,oy+10,0);
380
        mutex_unlock(&display_mutex);
381
 
382
        mcabptr = cab_reserve(fuel);
383
                memcpy(mcabptr,&itemp,sizeof(Position));
384
        cab_putmes(fuel,mcabptr);
385
 
386
        mutex_lock(&display_mutex);
387
        grx_box(x,y,x+10,y+10,rgb16(255,255,0));
388
        mutex_unlock(&display_mutex);
389
 
390
 
391
 
392
        sprintf(mx,"x = %d", x);
393
        sprintf(my,"y = %d",y);
394
}
395
/*-------------------io device handler functions end---------------------*/
396
 
397
 
398
/*------------------------------------------------------------------------------
399
 
400
MAIN function :
401
 
402
        this function is called when the application starts.
403
        it does the following:
404
        1.setup the keyborad hook
405
        2.setup the mouse hook
406
        3.create tasks:There are five categories of tasks in teh system.three are for jetcontrol.One for Repainting.One for the car.The first four tasks are soft taks while the car task is hard task.
407
 
408
-------------------------------------------------------------------------------*/
409
int main(int argc, char **argv)
410
{
411
        HARD_TASK_MODEL m;  /*for task Car*/
412
        SOFT_TASK_MODEL r; /*for task Repaint*/
413
        carcount = 0;       /*current number of cars in the system*/
414
        char c;             /* character from keyboard      */
415
                /* number of tasks created      */
416
        TIME sem;          /* used to init the random seed */
417
        KEY_EVT key;
418
        MOUSE_PARMS params = BASE_MOUSE;
419
        int forMouse;
420
 
421
        char cabname[] = "fuelcab"; /*name of the cab..only for debugging*/
422
        int cno = MAX_C + 3;
423
        char *cabptr;
424
        Position temp;
425
        temp.x = 200;   /*initial location of the fuel station*/
426
        temp.y = 250;
427
        itemp = temp;
428
        sem_init(carim,0,1);
429
        if(app_mutex_init(&display_mutex)<0)
430
                cprintf("mutex attribute can't be initialised");
431
        else
432
                cprintf("mutex attribute properly initialised");
433
 
434
        /*creating and initialising the cab*/
435
                fuel = cab_create(cabname,sizeof(Position),cno);
436
 
437
                cabptr = cab_reserve(fuel);
438
                memcpy(cabptr,&temp,sizeof(Position));
439
                cab_putmes(fuel,cabptr);
440
        /*-------------------cab handling ends-----------------*/
441
    /*key scan for changing the position of the petrol station*/                key.ascii = 'k';
442
        key.scan = KEY_K;
443
        key.flag=CNTL_BIT;
444
        keyb_hook(key,myhook);
445
        key.ascii = 'j';
446
        key.scan = KEY_J;
447
        key.flag=CNTL_BIT;
448
        keyb_hook(key,myhook);
449
        key.ascii = 'i';
450
        key.scan = KEY_I;
451
        key.flag=CNTL_BIT;
452
        keyb_hook(key,myhook);
453
        key.ascii = 'l';
454
        key.scan = KEY_L;
455
        key.flag=CNTL_BIT;
456
        keyb_hook(key,myhook);
457
        /*****************end keyboard*******************/
458
 
459
/*********mouse handling *************/
460
        forMouse = mouse_init(&params);
461
        mouse_limit(XMIN-D, YMIN-D,XMAX+D+2,YMAX+D+2);
462
        mouse_on();
463
        if(forMouse != 0)
464
        {
465
                grx_text("Mouse cannot be initialised",XMIN, YMENU+110, 13, 0);
466
        }
467
        mouse_on();
468
        mouse_grxcursor(ENABLE);
469
        mouse_position(200, 200);
470
        mouse_hook(mouseHandler);
471
 
472
/********************mouse handling ends*******************/
473
 
474
     /* Set the closing function */
475
        sys_atrunlevel(byebye, NULL, RUNLEVEL_BEFORE_EXIT);
476
 
477
    /* graphic card Initialization */
478
        if (grx_init() < 1)
479
        {
480
                sys_abort(1);
481
        }
482
 
483
        if (grx_open(640, 480, 16) < 0)
484
        {
485
                cprintf("GRX Err");
486
                sys_abort(1);
487
        }
488
        //grx_close /*uncomment it when you want to debug in text mode*/
489
 
490
        mutex_lock(&display_mutex);
491
        grx_rect(XMIN-D, YMIN-D, XMAX+D+2, YMAX+D+2, rgb16(0,255,0));
492
        grx_text("Car Game", XMIN+50, YMENU+10, rgb16(255,255,0),rgb16(0,0,0));
493
        grx_text("Press SPACE bar create a new car", XMIN,YMENU+20, rgb16(255,0,0),rgb16(0,0,0));
494
    grx_text("ESC   exit Game", XMIN, YMENU+40, rgb16(255,0,0),rgb16(0,0,0));
495
    grx_text("Use  Mouse to Move the Petrol Station", XMIN, YMENU+30, rgb16(255,0,0),rgb16(0,0,0));
496
        mutex_unlock(&display_mutex);
497
 
498
        scenario_jetcontrol();
499
        init_jetcontrol();
500
 
501
        /*Px = randomnumber(XMIN/2,XMAX/2);   */  //randomise it later;
502
        /*Py = randomnumber(YMIN/2,YMAX/2);    */ //rqaandomise it later.
503
        grx_box(temp.x, temp.y, temp.x+10, temp.y+10,rgb16(255,255,0));
504
    /* The program waits a space to create a car */
505
        c = keyb_getch(BLOCK);
506
    /* randomize!!!! */
507
        sem = sys_gettime(NULL);
508
        srand(sem);
509
 
510
        soft_task_default_model(r);
511
        soft_task_def_arg      (r, (void *)cari);
512
        soft_task_def_level(r,1);
513
        soft_task_def_period(r, car_period);
514
        soft_task_def_met(r, car_wcet);
515
        soft_task_def_ctrl_jet(r);
516
 
517
        rid = task_create("repaint", repaint_border, &r, NULL);
518
 
519
        if(task_activate(rid)==-1)
520
                grx_text("Unable to repaint", XMIN, YMENU+130, 12, 0);
521
 
522
 
523
        do
524
        {
525
                if ((c == ' ') && (cari < MAX_C))
526
                {
527
                        hard_task_default_model(m);
528
                        hard_task_def_ctrl_jet (m);
529
                        hard_task_def_arg      (m, (void *)cari);
530
                        hard_task_def_wcet     (m, car_wcet);
531
                        hard_task_def_mit      (m, car_period);
532
                        hard_task_def_group    (m, CARGROUP);
533
                        hard_task_def_usemath  (m);
534
 
535
                        pid = task_create("car", Car, &m, NULL);
536
 
537
                        if (pid == NIL)
538
                        {
539
                                grx_close();
540
                                perror("Could not create task <car>");
541
                                sys_abort(1);
542
                        }
543
 
544
                        if(task_activate(pid)==-1)
545
                        {
546
                                grx_close();
547
                                perror("Error activating the task!!");
548
                                sys_abort(1);
549
                        }
550
 
551
                        /*sem_wait(&carim);*/
552
                        cari++;
553
                        /*sem_post(&carim);*/
554
                }
555
                c = keyb_getch(BLOCK);
556
 
557
        }while (c != ESC);
558
 
559
        sys_end();
560
        return 0;
561
}
562
 
563
/*------------------------------main ends-------------------------------------*/
564
 
565
 
566
 
567
/*------------------------------------------------------------------------
568
helper functions:
569
1.randomnumber
570
2.randomangle
571
3. boundary check
572
--------------------------------------------------------------------------*/
573
int randomnumber(int min, int max)
574
{       int temp;
575
        temp=rand()%((min+max)/2);  //old and new values to some random initial value
576
        if(temp > max || temp < min)
577
                temp = min+max/2;
578
        return temp;
579
}
580
 
581
int randomangle()
582
{       int temp;
583
        temp=rand()%(2*ANG) - ANG;
584
        if (temp > 360) temp -= 360;
585
        if (temp < 0) temp+= 360;
586
        return temp;
587
}
588
 
589
 
590
int boundary_check(int *x, int *y)
591
{
592
 
593
        int outx, outy;
594
        outx = (*x >= XMAX) || (*x <= XMIN);
595
        outy = (*y >= YMAX) || (*y <= YMIN);
596
        if (outx || outy)
597
        {
598
                if(*x >= XMAX) *x = XMIN+1;
599
                if(*y >=YMAX) *y = YMIN+1;
600
                if(*x<=XMIN) *x=XMAX-1;
601
                if(*y<=YMIN) *y=YMAX-1;
602
        }
603
        return 0;
604
}
605
/*------------------helper funtions end------------------------------------*/
606
 
607
 
608
 
609
 
610
 
611
/*-------------------------------------------------------------------------------
612
        Function name:func_collision
613
        description:
614
        the collsion avoidance strategy is not very robust.This is true even in real life if we take unpredictable situations.the car should however react as soon as possible.so we have to check it there is a collision and terminate the task then
615
 
616
        input parameters:
617
                carid:
618
                x,y : position of the car
619
                collisioncount: current value of collision count
620
        output parameters:
621
                collisioncount: current value of coolision count
622
                collide: set if the car has to collide
623
                warning: set if the car is on collision course
624
                alpha: the current value of angle in radians
625
        return type:
626
                void
627
 
628
the function for handling the collsion avoidance
629
this function uses a lot of parameters at present as we tried to reorganise our code ..it can definately be improoved!!
630
------------------------------------------------------------------------------*/
631
void func_collision(int carid, int x, int y, int *collisioncount,enum mybool *collide,enum mybool *warning, double *alpha)
632
{
633
        int ti,xoc,yoc;
634
        PORT ptx,pty;
635
        char tmyprint[40];
636
        int count;
637
        count=carcount;
638
        char tnamex[7],tnamey[7],tcordx[4],tcordy[4];
639
        float angdiff, diff;
640
        float angv;
641
        angv = 30 + 15*(carid%3);
642
        double collisionangle;
643
 
644
        count=carcount;
645
        for(ti=0; ti<count; ti++)
646
        {
647
                if(ti==carid)
648
                    continue; //car will always be close to itself!!
649
                sprintf (tnamex,"carx%d",ti);
650
                sprintf(tnamey,"cary%d",ti);
651
                ptx = port_connect(tnamex, 7*sizeof(char), STICK, READ);
652
                pty = port_connect(tnamey, 7*sizeof(char),STICK, READ);
653
                port_receive(ptx, tcordx, BLOCK);
654
                port_receive(pty, tcordy, BLOCK);
655
                sscanf(tcordx,"%d",&xoc);
656
                sscanf(tcordy,"%d",&yoc);
657
                port_disconnect(ptx);
658
                port_disconnect(pty);
659
                diff = sqrt((x-xoc)*(x-xoc) + (y-yoc)*(y-yoc)); //distance between cars                 //computing angle of approach of cars in range(collision angle)
660
                if(x-xoc == 0)
661
                {
662
                        if(y-yoc > 0)
663
                                collisionangle = PI/2;
664
                        else
665
                                collisionangle = 3*PI/2;
666
                }
667
                else
668
                {
669
                        collisionangle =  atan((y-yoc)/(x-xoc)); //angle of aproaching
670
                        angdiff = abs(*alpha - collisionangle)* 180/PI; //convering to degrees
671
                /*checking if there is a chancee of collsion or collsion*/
672
                        if(diff < MINDIST && angdiff < 10)
673
                        {
674
                                if(diff <= COLDIST && angdiff < 5)
675
                                {
676
                                        *collide = true;
677
                                        break;
678
                                }
679
                                *collisioncount = 4;
680
                                if(*warning != true)
681
                                {
682
                                        *warning = true;
683
                                        if(*alpha >= collisionangle)
684
                                                *alpha = *alpha+angv;
685
                                        if(*alpha<collisionangle)
686
                                                *alpha = *alpha -angv;
687
                                }
688
                                                                                                                sprintf(tmyprint,"%d",carid);
689
                                /*mutex_lock(&display_mutex);
690
                                grx_text(tmyprint,XMIN+20,YMENU +60,25,0);
691
                                mutex_unlock(&display_mutex);*/
692
                                break; //get out of the for loop for the first collsion detected
693
                        }
694
 
695
 
696
                }
697
        }
698
 
699
}
700
 
701
/*----------------------------func_collision ends----------------------------*/
702