Project

General

Profile

Statistics
| Revision:

root / trunk / code / behaviors / formation_control / circle_spacing / circle_spacing.c @ 1809

History | View | Annotate | Download (14.4 KB)

1
#include <dragonfly_lib.h>
2
#include <wl_basic.h>
3
#include<encoders.h>
4
#include "circle_spacing.h"
5

    
6
enum role_e {MASTER,SLAVE};
7
enum state_e {INIT, ID, MAPPING, PLANNING, WAIT, SENDING, RECIEVING, FINISH};
8

    
9
enum role_e role = SLAVE;
10
enum state_e current_state = INIT;
11
enum state_e next_state = INIT;
12

    
13
int used[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  // if a robot is here, the value of the indice equal to its id is 1, esle 0
14
int map[17] = {20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20};  // Angular position of the robot which id equals the indice (20 for not here)
15
int neighbour[17] = {20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20}; // clockwise neighbour
16
int gap[17] = {20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20};  // gap to the left of the robot 
17
int stop = 0;
18
struct vector slave_position;
19
int desired_max_bom;
20
int bom_max_counter;
21
int robotid;
22
int centerid = 0;
23
int robotsRecieved=0;
24
int target_slave = 0;
25

    
26

    
27
void set_desired_max_bom(int desired_angle)
28
{
29
        if (desired_angle >= 348 || desired_angle < 11) desired_max_bom = 0;
30
        if (desired_angle >= 11 && desired_angle < 33) desired_max_bom = 1;
31
        if (desired_angle >= 33 && desired_angle < 56) desired_max_bom = 2;
32
        if (desired_angle >= 56 && desired_angle < 78) desired_max_bom = 3;
33
        if (desired_angle >= 78 && desired_angle < 101) desired_max_bom = 4;
34
        if (desired_angle >= 101 && desired_angle < 123) desired_max_bom = 5;
35
        if (desired_angle >= 123 && desired_angle < 145) desired_max_bom = 6;
36
        if (desired_angle >= 145 && desired_angle < 167) desired_max_bom = 7;
37
        if (desired_angle >= 167 && desired_angle < 190) desired_max_bom = 8;
38
        if (desired_angle >= 190 && desired_angle < 212) desired_max_bom = 9;
39
        if (desired_angle >= 212 && desired_angle < 235) desired_max_bom = 10;
40
        if (desired_angle >= 235 && desired_angle < 257) desired_max_bom = 11;
41
        if (desired_angle >= 257 && desired_angle < 280) desired_max_bom = 12;
42
        if (desired_angle >= 280 && desired_angle < 302) desired_max_bom = 13;
43
        if (desired_angle >= 302 && desired_angle < 325) desired_max_bom = 14;
44
        if (desired_angle >= 325 && desired_angle < 348) desired_max_bom = 15;
45
}
46

    
47
// collects the angular position of the slave robots by making them switch their bom one by one.
48

    
49
void map_slaves()
50
{
51
        int bom_max;
52
        
53
        for(int i=0; i<17; i++)
54
        {
55
                if(used[i])
56
                {
57
                        send2(CIRCLE_ACTION_MAP,i);
58
                        delay_ms(1000);
59
                        
60
                        do
61
                        {        
62
                                bom_refresh(BOM_ALL);
63
                                bom_max = bom_get_max();
64
                        }
65
                        while(bom_max == -1);
66
                                
67
                        map[i] = bom_max;
68
                        send2(CIRCLE_ACTION_DONE,i);
69
                }
70
        }
71
        
72
        usb_puts("Map: \r\n");
73
        for(int i=0; i<17; i++)
74
        {
75
                usb_puti(map[i]);
76
                usb_puts("\r\n");
77
        }
78
}
79

    
80
void plan()
81
{
82
        static int k = 0;
83
        
84
        target_slave++;
85
        
86
        if(target_slave>16) 
87
        {
88
                next_state = FINISH;
89
                orb1_set_color(YELLOW);
90
        }
91
        else if(used[target_slave]) 
92
        {
93
                k++;
94
                usb_puts("K: ");
95
                                                                usb_puti(k);
96
                                                                usb_puts("\r\n");
97
                set_desired_max_bom(360/robotsRecieved*k);
98
                send2(CIRCLE_ACTION_MOVE,target_slave);
99
                delay_ms(500);
100
                next_state = SENDING;
101
        }
102
        
103
        
104
}
105

    
106
void plan2()
107
{
108
        int order[robotsRecieved];
109
        int check[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
110
        
111
        
112
        
113
        for(int i=0; i<robotsRecieved; i++)
114
        {
115
                int current;
116
                int min = 20;
117
                for(int j=0; j<17; j++)
118
                {
119
                        if(map[j]<min && !check[j])
120
                        {
121
                                current = j;
122
                                min = map[j];
123
                                usb_puts("Test \r\n");
124
                        }
125
                        
126
                }
127
                
128
                order[i]=current;
129
                check[current]=1;
130
                        
131
                        usb_puti(i);
132
                        usb_puts("  Current: ");
133
                        usb_puti(current);
134
                        usb_puts("\r\n");
135
        }
136
        usb_puts("Order: \r\n");
137
        for(int i=0; i<robotsRecieved; i++)
138
        {        usb_puti(i);
139
                usb_puts("   ");
140
                usb_puti(order[i]);
141
                usb_puts("\r\n");
142
        }
143
        
144
        for(int i=0; i<robotsRecieved; i++)
145
        {
146
                if(i==robotsRecieved-1) gap[order[i]]= map[order[0]] - map[order[i]] +16; // closes the loop
147
                else gap[order[i]]= map[order[i+1]] - map[order[i]];
148
        }
149
        
150
        usb_puts("Gap: \r\n");
151
        for(int i=0; i<17; i++)
152
        {
153
                usb_puti(gap[i]);
154
                usb_puts("\r\n");
155
        }
156
        
157
        for(int i=0; i<robotsRecieved; i++)
158
        {
159
                if(i==0) neighbour[order[i]]=order[robotsRecieved-1];
160
                else neighbour[order[i]]=order[i-1];
161
                
162
        }
163
        
164
        usb_puts("Neighbour: \r\n");
165
        for(int i=0; i<17; i++)
166
        {
167
                usb_puti(neighbour[i]);
168
                usb_puts("\r\n");
169
        }
170
}
171

    
172
void plan3()
173
{
174
        static int move_counter =0;
175
        int max = 0;
176
        int move_gap = 0;
177
        
178
        for(int j=0; j<17; j++)
179
        {
180
                if(gap[j]>max && gap[j]!=20)
181
                {
182
                        target_slave = j;
183
                        max = gap[j];
184
                }
185
                        
186
        }
187
        
188
        move_counter++;
189
        if(move_counter==robotsRecieved) next_state = FINISH;
190
        else
191
        {
192
                move_gap = gap[target_slave]-16/robotsRecieved;
193
                desired_max_bom = map[target_slave]+move_gap;
194
                if(desired_max_bom>15) desired_max_bom-=16;
195
                gap[target_slave]-=move_gap;
196
                gap[neighbour[target_slave]] += move_gap;
197
                usb_puts("Target:");
198
                usb_puti(target_slave);
199
                usb_puts("  Destination:");
200
                usb_puti(desired_max_bom);
201
                usb_puts("\n\r");
202
                send2(CIRCLE_ACTION_MOVE,target_slave);
203
                delay_ms(500);
204
                next_state = SENDING;
205
        }
206
}
207

    
208

    
209
void switch_state ()
210
{
211
        switch(role)
212
        {
213
                case MASTER:
214
                        switch(current_state)
215
                        {
216
                                case PLANNING:
217
                                        orb1_set_color(RED);
218
                                        break;
219
                                case SENDING:
220
                                        bom_off();
221
                                        break;
222
                        }
223
                        
224
                        
225
                        
226
                        switch(next_state)
227
                        {
228
                                case ID:
229
                                        send2(CIRCLE_ACTION_EXIST,robotid);
230
                                        break;
231
                                        
232
                                case MAPPING:
233
                                        map_slaves();
234
                                        plan2();
235
                                        break;
236
                                        
237
                                case PLANNING:
238
                                
239
                                        orb1_set_color(PINK);
240
                                
241
                                        break;
242
                                        
243
                                case SENDING:
244
                                        bom_on();
245
                                        break;
246
                                
247
                                case RECIEVING:
248
                                        break;
249
                        }
250
                        break;
251
                        
252
                case SLAVE:
253
                        switch(current_state)
254
                        {
255
                                case SENDING:
256
                                        bom_off();
257
                                        break;
258
                                        
259
                        }
260
                        
261
                        
262
                        
263
                        switch(next_state)
264
                        {
265
                                case ID:
266
                                        
267
                                        break;
268
                                        
269
                                case MAPPING:
270
                                        orb1_set_color(PINK);
271
                                        break;
272
                                        
273
                                case SENDING:
274
                                        bom_on();
275
                                        break;
276
                                
277
                                case RECIEVING:
278
                                        bom_off();
279
                                        break;
280
                                case FINISH:
281
                                        motor_l_set(FORWARD,0);
282
                                        motor_r_set(FORWARD,0);
283
                                        orb1_set_color(YELLOW);
284
                                        break;
285
                        }
286
                        break;
287
        }
288
        
289
        
290
        current_state = next_state;
291
}
292

    
293

    
294
void send2(char arg0, char arg1)
295
{
296
        char send_buffer[2];
297
        send_buffer[0]=arg0;
298
        send_buffer[1]=arg1;
299
        wl_basic_send_global_packet(42,send_buffer,2);
300
}
301

    
302

    
303
int main(void)
304
{
305

    
306

    
307
        int sending_counter = 0;
308
        int waitingCounter=0;
309
        int max_bom;
310
        
311
    /* Initialize dragonfly board */
312
        
313
    dragonfly_init(ALL_ON);
314
        xbee_init();
315
        wl_basic_init_default();
316
        wl_set_channel(12);
317
    int data_length;
318
        unsigned char *packet_data;
319
        char send_buffer[2];
320
        
321

    
322
        robotid = get_robotid();
323
        
324
        if(wheel()>100)
325
        {
326
                role = MASTER;
327
        }
328
        
329
        
330
        if(role == MASTER) {orb2_set_color(RED); set_desired_max_bom(30);}
331
        else orb2_set_color(BLUE);
332
        
333
        
334
        while(1)
335
        {
336
        
337
        
338
                bom_refresh(BOM_ALL);
339
                
340
                
341
                if(current_state != next_state) switch_state();
342
                
343
                
344
                switch(role)
345
                
346
                {
347
                        case MASTER:
348
                
349

    
350
                                switch(current_state)
351
                                {        
352
                                        case INIT:
353
                                                next_state = ID;
354
                                                break;
355
                                        case ID:
356
                                                
357
                                                waitingCounter++;
358
        
359
                                        
360
                                                if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
361
                                                {
362

    
363
                                                        //only add to robots seen if you haven't gotten an ACK from this robot
364
                                                        if(used[packet_data[1]]==0)
365
                                                        {
366
                                                                robotsRecieved++;
367
                                                                used[packet_data[1]] = 1;
368

    
369
                                                                usb_puts("Added: ");
370
                                                                usb_puti(packet_data[1]);
371
                                                                usb_puts("\r\n");
372
                                                        }
373

    
374
                                                        // NEW: sends a packet to each robot it receives telling them to be done.
375
                                                        send2(CIRCLE_ACTION_GOTYOU,packet_data[1]);
376
                                                }
377
                                                if(waitingCounter >= 300){
378
                                                        next_state = MAPPING;
379
                                                }
380
                                                break;
381
                                                
382
                                        case MAPPING:
383
                                        
384
                                                next_state = PLANNING;
385
                                                break;
386
                                                
387
                                        case PLANNING:
388
                                                plan3();
389
                                                break;
390
                                                
391
                                        case SENDING:
392
                                        
393
                                                if(sending_counter++>4)        // clock for switching the BOMs between the master and slave
394
                                                {
395
                                                        next_state = RECIEVING;
396
                                                        sending_counter = 0;
397
                                                        send2(CIRCLE_ACTION_CHANGE,target_slave);
398
                                                }
399
                                                break;
400
                                                
401
                                        case RECIEVING:
402
                                        
403
                                                if(sending_counter++>4)        // clock for switching the BOMs between the master and slave
404
                                                {
405
                                                        next_state = SENDING;
406
                                                        sending_counter = 0;
407
                                                        send2(CIRCLE_ACTION_CHANGE,target_slave);
408
                                                }
409
                                                
410
                                                max_bom = bom_get_max();
411
                                                //usb_puts("bom_get_max : ");
412
                                                //usb_puti(max_bom);
413
                                                //usb_puts("\n\r");
414
                                        
415
                                                if(max_bom == desired_max_bom)
416
                                                {
417
                                                        bom_max_counter ++;
418
                                                        if(bom_max_counter>2)                 // only stops the slave if two consecutive boms reading give the desired bom as the max one. Filters the noise.
419
                                                        {
420
                                                        send2(CIRCLE_ACTION_STOP,target_slave);
421
                                                        next_state = PLANNING;
422
                                                        bom_max_counter = 0;
423
                                                        }
424
                                                
425
                                                }
426
                                                else bom_max_counter = 0;
427
                                                break;
428
                                        
429
                                }
430
                                
431
                                break;
432
                        
433
                
434
                
435
                        case SLAVE:
436
                        
437
                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_STOP && packet_data[1] == robotid) next_state = FINISH;
438
                                
439
        
440
                        
441
                                switch(current_state)
442
                                {
443
                                        case INIT:
444
                                                next_state = ID;
445
                                                break;
446
                                                
447
                                        case ID:
448
                                                
449
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_EXIST)
450
                                                {
451
                                                        centerid = packet_data[1];
452

    
453
                                                        send2(CIRCLE_ACTION_ACK,robotid);
454

    
455
                                                        next_state = MAPPING;
456
                                                
457
                                                }
458
                                                break;
459
                                                
460
                                        case MAPPING:
461
                                                
462
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_MAP && packet_data[1] == robotid)
463
                                                {
464
                                                        bom_on();
465
                                                }
466
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE && packet_data[1] == robotid)
467
                                                {
468
                                                        bom_off();
469
                                                        next_state = PLANNING;
470
                                                }
471
                                        
472
                                        case PLANNING:
473
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_MOVE && packet_data[1] == robotid)
474
                                                {
475
                                                        next_state = RECIEVING;
476
                                                }
477
                                                break;
478
                                                        
479
                                        case SENDING:
480
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_CHANGE && packet_data[1] == robotid)
481
                                                        next_state = RECIEVING;        
482
                                                break;
483
                                                
484
                                        case RECIEVING:
485
                                        
486
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_CHANGE && packet_data[1] == robotid)
487
                                                        next_state = SENDING;
488
                                                
489
                                                if(stop)
490
                                                {
491
                                                motor_l_set(FORWARD,0);
492
                                                motor_r_set(FORWARD,0);
493
                                                orb1_set_color(GREEN);
494
                                                }
495
                                                
496
                                                else
497
                                                {
498
                                                        max_bom = bom_get_max();
499
                                                        /*usb_puts("bom_get_max : ");
500
                                                        usb_puti(max_bom);
501
                                                        usb_puts("/n/r");*/
502
                                                
503
                                                
504
                                                   if(max_bom == 8)
505
                                                   {        
506
                                                        orb2_set_color(BLUE);
507
                                                        motor_r_set(FORWARD,180);
508
                                                        motor_l_set(FORWARD,180);
509
                                                        
510
                                                   }
511
                                                   else if(max_bom == 7 || max_bom == 6 || max_bom == 5)
512
                                                   {
513
                                                        motor_l_set(FORWARD,180);
514
                                                        motor_r_set(FORWARD,0);
515
                                                        }
516
                                                        else if(max_bom == -1);
517
                                                   else 
518
                                                   {
519
                                                        orb2_set_color(GREEN);
520
                                                        motor_l_set(FORWARD,0);
521
                                                        motor_r_set(FORWARD,180);
522
                                                        }
523
                                                }
524
                                                break;
525
                
526
                                }
527
                        
528
                                break;
529
                }
530
                
531
                packet_data = wl_basic_do_default(&data_length);
532
                delay_ms(10);
533
        }
534
        
535
  
536
  return 0;
537
  
538
  
539
        
540
        
541
}
542

    
543

    
544

    
545

    
546

    
547

    
548

    
549

    
550

    
551

    
552

    
553

    
554

    
555

    
556

    
557

    
558

    
559

    
560

    
561

    
562

    
563

    
564

    
565

    
566

    
567

    
568

    
569

    
570

    
571

    
572

    
573

    
574

    
575

    
576
/*
577

578

579
//   Code working for a single slave orbiting around the master, with only one direction  (tested on 07.04.2010)
580

581

582
#include <dragonfly_lib.h>
583
#include <wl_basic.h>
584
#include<encoders.h>
585

586

587
int master = 0;
588
int sending = 0;
589
int stop = 0;
590
struct vector slave_position;
591
int desired_max_bom;
592
int bom_max_counter;
593

594

595
void set_desired_max_bom(int desired_angle)
596
{
597
        if (desired_angle >= 348 || desired_angle < 11) desired_max_bom = 0;
598
        if (desired_angle >= 11 && desired_angle < 33) desired_max_bom = 1;
599
        if (desired_angle >= 33 && desired_angle < 56) desired_max_bom = 2;
600
        if (desired_angle >= 56 && desired_angle < 78) desired_max_bom = 3;
601
        if (desired_angle >= 78 && desired_angle < 101) desired_max_bom = 4;
602
        if (desired_angle >= 101 && desired_angle < 123) desired_max_bom = 5;
603
        if (desired_angle >= 123 && desired_angle < 145) desired_max_bom = 6;
604
        if (desired_angle >= 145 && desired_angle < 167) desired_max_bom = 7;
605
        if (desired_angle >= 167 && desired_angle < 190) desired_max_bom = 8;
606
        if (desired_angle >= 190 && desired_angle < 212) desired_max_bom = 9;
607
        if (desired_angle >= 212 && desired_angle < 235) desired_max_bom = 10;
608
        if (desired_angle >= 235 && desired_angle < 257) desired_max_bom = 11;
609
        if (desired_angle >= 257 && desired_angle < 280) desired_max_bom = 12;
610
        if (desired_angle >= 280 && desired_angle < 302) desired_max_bom = 13;
611
        if (desired_angle >= 302 && desired_angle < 325) desired_max_bom = 14;
612
        if (desired_angle >= 325 && desired_angle < 348) desired_max_bom = 15;
613
}
614

615

616

617

618

619

620
void switch_sending ()
621
{
622
        if(sending)
623
        {
624
                sending = 0;
625
                bom_off();
626
        }
627
        else
628
        {
629
                sending = 1;
630
                bom_on();
631
        }
632
}
633

634

635

636
int main(void)
637
{
638

639
        
640
        
641
        int sending_counter = 0;
642
        
643
   // Initialize dragonfly board 
644
        
645
    dragonfly_init(ALL_ON);
646
        xbee_init();
647
        wl_basic_init_default();
648
        wl_set_channel(12);
649
    int data_length;
650
        unsigned char *packet_data;
651
        char send_buffer[2];
652
        
653
        
654
        if(wheel()>100)
655
        {
656
                master = 1;
657
        }
658
        
659
        
660
        if(master) {orb1_set_color(RED); set_desired_max_bom(30);}
661
        else orb1_set_color(BLUE);
662
        
663
        
664
        while(1)
665
        {
666
        
667
        
668
                
669
        
670
                bom_refresh(BOM_ALL);
671
                
672
                
673
                
674
                if(master)
675
                {
676
                
677
                        if(sending_counter++>4)        // clock for switching the BOMs between the master and slave
678
                        {
679
                                switch_sending();
680
                                sending_counter = 0;
681
                                send_buffer[0] = 'a';
682
                                wl_basic_send_global_packet(42, send_buffer, 1);
683
                        }
684
                
685
                        
686
                        if(sending)
687
                        {
688
                
689
                                
690
                        
691
                        
692

693
                        }
694
                        
695
                        else // recieving
696
                        {
697
                                int max_bom = bom_get_max();
698
                                        usb_puts("bom_get_max : ");
699
                                        usb_puti(max_bom);
700
                                        usb_puts("\n\r");
701
                        
702
                                if(max_bom == desired_max_bom)
703
                                {
704
                                        if(bom_max_counter)                 // only stops the slave if two consecutive boms reading give the desired bom as the max one. Filters the noise.
705
                                        {
706
                                        send_buffer[0] = 's';
707
                                        wl_basic_send_global_packet(42, send_buffer, 2);
708
                                        }
709
                                bom_max_counter =1;
710
                                }
711
                                else bom_max_counter = 0;
712
                                
713
                        }
714
                }
715
                
716
                
717
                
718
                else // slave
719
                {
720
                        if(packet_data[0]=='s') stop=1;
721
                        if(packet_data[0]=='a') switch_sending();
722
                
723
                        if(sending)
724
                        {
725
                        
726
                        }
727
                        
728
                        else // recieving
729
                        {
730
                        
731
                                if(stop)
732
                                {
733
                                motor_l_set(FORWARD,0);
734
                                motor_r_set(FORWARD,0);
735
                                orb1_set_color(GREEN);
736
                                }
737
                                
738
                                else
739
                                {
740
                                        int max_bom = bom_get_max();
741
                                        
742
                                
743
                                
744
                                   if(max_bom == 8)
745
                                   {        
746
                                        orb2_set_color(BLUE);
747
                                        motor_r_set(FORWARD,180);
748
                                        motor_l_set(FORWARD,180);
749
                                        
750
                                   }
751
                                   else if(max_bom == 7 || max_bom == 6 || max_bom == 5)
752
                                   {
753
                                        motor_l_set(FORWARD,180);
754
                                        motor_r_set(FORWARD,0);
755
                                        }
756
                                        else if(max_bom == -1);
757
                                   else 
758
                                   {
759
                                        orb2_set_color(GREEN);
760
                                        motor_l_set(FORWARD,0);
761
                                        motor_r_set(FORWARD,180);
762
                                        }
763
                                }
764
                        
765
                        
766
                        }
767
                
768
                
769
                }
770
                
771
                packet_data = wl_basic_do_default(&data_length);
772
                delay_ms(10);
773
        }
774
        
775
  
776
  return 0;
777
  
778
  
779
        
780
        
781
}
782

783

784

785
*/
786