Project

General

Profile

Statistics
| Revision:

root / trunk / code / behaviors / formation_control / circle / circle.c @ 1749

History | View | Annotate | Download (19.9 KB)

1

    
2
/*** PROGRAM INFORMATION ***
3

4
          This program assembles a group of robots into a circle and allows them movement
5
        within that formation.  Robots should be able to break formation and travel as a
6
        line, readjust in the face of obstacles, and reform if conditions are necessary.
7

8
          The program begins waiting for a button press.  When pressed, a robot assumes the
9
        BEACON position, which means that it is the robot in the center of the circle and
10
        therefore in charge.  It then gathers robots around it by sending them commands.
11
        This code is executed using two finite state machines, nested inside one another.
12
        One controls the overall state of the robot (whether it is a BEACON, an EDGE, or
13
        WAITING, for example).
14

15
          This code should be implemented so that most useful functions are built in to the
16
        machine.  For example, the BEACON robot should be able to call methods such as
17
        CircleUp() to gather robots around it, and Move(distance) to move the circle group
18
        all at once.
19

20
          This Code is the property of the Carnegie Mellon Robotics Club and is being used
21
        to test formation control in a low-cost robot colony.  Thanks to all members of
22
        RoboClub, especially Colony president John Sexton and the ever-present Chris Mar.
23
        
24
        AUTHORS: James Carroll, Steve DeVincentis, Hanzhang (Echo) Hu, Nico Paris, Joel Rey,
25
         Reva Street, Alex Zirbel                                                         */
26

    
27

    
28
#include <dragonfly_lib.h>
29
#include <wl_basic.h>
30
#include <encoders.h>
31
#include "circle.h"
32

    
33
/*** TODO: ***
34

35
        - Transform the code into a method-based state machine that uses the procedural state
36
                machines, which are hardcoded and hard to edit, as a backup.
37
        - Implement a drive straight method for use in keeping the robots more accurate as a
38
                group.
39
        - Fix the approach method: good robots usually work well, but bad robots often have
40
                errors which might be avoidable with the use of error checking.
41
        - Make robots more robust: packages are often lost, which throws the entire procedural
42
                nature of the program off.
43
        - Consider using the center bot to check distances
44
        - More testing is always good and necessary.                                        */
45

    
46
/*** BOT LOG ***
47

48
        4-1-2010: BOT 7 as BEACON and BOT 1 as EDGE worked extremely well.
49
        4-2-2010: BOT 7 and BOT 14 worked extremely well, no matter states.  BOT 1 started
50
                well, but malfunctioned later.                                                */
51

    
52
/*** TERMINOLOGY ***
53

54
        WAITINGSTATE:
55
                The robot waits to be given a signal to do something.  Wireless is on, in
56
                case the robot is called on to turn into an EDGE.  The color should be LIME
57
                or YELLOW-GREEN.
58

59
        BEACON_CONTROL:
60
                The code that executes commands when a robot is turned to BEACON mode.  This
61
                code may run predefined methods for simplicity.  One goal is to make these
62
                methods change the robot turn to to BEACON_MACHINE mode for a while, and then
63
                return to the CONTROL code where they left off.
64

65
        EDGE_CONTROL:
66
                Like BEACON_CONTROL, executes whatever orders are required of the robot as an
67
                EDGE.
68

69
        BEACON_MACHINE:
70
                A hardcoded list of functions which the robot is capable of running through.
71
                Consists of a finite state machine, where the robot executes a set of commands
72
                in a procedural manner and then returns to wherever it was in the control code.
73

74
        EDGE_MACHINE:
75
                Like the BEACON_MACHINE, but contains the same sort of procedural information
76
                for EDGE robots.
77

78
        END:
79
                A terminal state of the machine, where the robot just sits and waits.  The
80
                color should be GREEN and WHITE.
81

82

83
        TYPES OF WIRELESS PACKETS:
84
                CIRCLE_ACTION_EXIST 'E'
85
                CIRCLE_ACTION_POSITION 'P'
86
                CIRCLE_ACTION_ACK 'A'
87
                        A general acknowledgement package.
88
                CIRCLE_ACTION_DONE 'D'
89
                        Used by robots to tell when they have finished their action.
90
                CIRCLE_ACTION_GOTYOU 'G'
91
                        Used by the BEACON to tell a robot when it has been checked off.
92
                        At this point, the EDGE has been recognized.  Used for times when
93
                        all EDGE robots have to communicate to the center via the spam method.
94
                CIRCLE_ACTION_FORWARD 'F'
95
                        The BEACON tells the rest of the robots to move forward.
96
                CIRCLE_CLAIM_CENTER 'C'
97
                        Sent out by a robot when it takes over as BEACON.                */
98

    
99

    
100

    
101
int END = 100;        
102
int WAITINGSTATE = 0;                /* Define some variables to keep track of the state machine.*/
103
int EDGE_CONTROL = 1;
104
int BEACON_CONTROL = 2;
105
int EDGE_MACHINE = 3;
106
int BEACON_MACHINE = 4;
107

    
108

    
109
int timeout = 0;
110
int sending = 0;
111
int stop2 = 0;
112
struct vector slave_position;
113
int desired_max_bom;
114
int bom_max_counter;
115

    
116

    
117
void switch_sending(void)
118
{
119
        if(sending)
120
        {
121
                sending = 0;
122
                bom_off();
123
        }
124
        else
125
        {
126
                sending = 1;
127
                bom_on();
128
        }
129
}
130

    
131
void forward(int speed){                        // set the motors to this forward speed.
132
        motor_l_set(FORWARD,speed);
133
        motor_r_set(FORWARD,speed);
134
}
135
void left(int speed){                                // turn left at this speed.
136
        motor_l_set(FORWARD,speed);
137
        motor_r_set(BACKWARD,speed);
138
}
139
void right(int speed){
140
        motor_l_set(BACKWARD,speed);
141
        motor_r_set(FORWARD,speed);
142
}
143
void stop(void){                        // could be set to motors_off(), or just use this as an alternative.
144
        motor_l_set(BACKWARD,0);        // stop() is better - motors_off() creates a slight delay to turn them back on.
145
        motor_r_set(FORWARD,0);
146
}
147
void setforward(int spd1, int spd2){
148
        motor_l_set(FORWARD,spd1);
149
        motor_r_set(FORWARD,spd2);
150
}
151
void backward(int speed){
152
        motor_l_set(BACKWARD, speed);
153
        motor_r_set(BACKWARD, speed);
154
}
155
int get_distance(void){                                // takes an averaged reading of the front rangefinder
156
        int temp,distance,kk=5;                        // kk sets this to 5 readings.
157
        distance =0;
158
        for (int i=0; i<kk; i++){
159
                temp = range_read_distance(IR2);
160
                if (temp == -1)
161
                {
162
                        //temp=0;
163
                        i--;
164
                }
165
                else
166
                        distance+= temp;
167
                delay_ms(3);
168
        }
169
        if (kk>0)
170
                return (int)(distance/kk);
171
        else 
172
                return 0;
173
}
174

    
175
/* Sends a global packet with two arguments */
176
void send2(char arg0, char arg1)
177
{
178
        char send_buffer[2];
179
        send_buffer[0]=arg0;
180
        send_buffer[1]=arg1;
181
        wl_basic_send_global_packet(42,send_buffer,2);
182
}
183

    
184
/* Sends a global packet with three arguments */
185
void send3(char arg0, char arg1, char arg2)
186
{
187
        char send_buffer[3];
188
        send_buffer[0]=arg0;
189
        send_buffer[1]=arg1;
190
        send_buffer[2]=arg2;
191
        wl_basic_send_global_packet(42,send_buffer,3);
192
}
193

    
194
/*
195
        Orients the robot so that it is facing the beacon (or the broadcasting BOM).
196
        
197
*/
198
void correctTurn(void)
199
{
200
        orb1_set_color(BLUE);                        // BLUE and PURPLE
201
        left(220);
202
        while(1)
203
        {
204
                int bomNum = 0;                                // bomNum is the current maximum reading
205
                bom_refresh(BOM_ALL);
206
                bomNum = bom_get_max();
207
                usb_puti(bomNum);
208
                if(bomNum == 4)                                // when it's turned the right way, stop
209
                {
210
                        timeout = 0;
211
                        //motor_l_set(1, 200);
212
                        //motor_r_set(1, 200);
213
                        break;                                // exits the while() loop to stop the method
214
                }
215
                else                                        // facing the wrong way
216
                {
217
                        if(bomNum == -1)
218
                        {
219
                                timeout++;
220
                                
221
                                if(timeout > 5000)        // if it's been looking too long, move a little bit as it turns
222
                                {
223
                                        motor_r_set(FORWARD, 210);
224
                                        motor_l_set(BACKWARD, 190);
225
                                }
226
                        }
227
                        else if((bomNum >= 12) || (bomNum < 4))
228
                        {
229
                                motor_l_set(FORWARD, 200);
230
                                motor_r_set(BACKWARD, 200);
231
                                timeout = 0;
232
                        }
233
                        else
234
                        {
235
                                motor_l_set(BACKWARD, 200);
236
                                motor_r_set(FORWARD, 200);
237
                                timeout = 0;
238
                        }
239
                }
240
        }
241
        return;
242
}
243

    
244

    
245
/* 
246
    BLINK the given number times
247
*/
248
void blink(int num)
249
{
250
        for(int i = 0; i<num; i++)
251
        {
252
                orb_set_color(ORB_OFF);
253
                delay_ms(150);
254
                orb_set_color(RED);
255
                delay_ms(50);
256
        }
257
        orb_set_color(ORB_OFF);
258
}
259

    
260
/* 
261
    BLINK slowly the given number times
262
*/
263
void slowblink(int num)
264
{
265
        for(int i = 0; i<num; i++)
266
        {
267
                orb_set_color(ORB_OFF);
268
                delay_ms(300);
269
                orb_set_color(RED);
270
                delay_ms(200);
271
        }
272
        orb_set_color(ORB_OFF);
273
}
274

    
275

    
276

    
277

    
278

    
279
//*****************************************************************************************************************************************************************************************
280
//*****************************************************************************************************************************************************************************************
281
//*****************************************************************************************************************************************************************************************
282

    
283

    
284
/*
285
        A state machine with five states.  The robot starts out in WAITINGSTATE mode, from which
286
        it recieves a signal of some sort and moves to a different state.
287
*/
288
int main(void)
289
{
290
        /* Initialize dragonfly board */
291
            dragonfly_init(ALL_ON);
292
            /* Initialize the basic wireless library */
293
            wl_basic_init_default();
294
            /* Set the XBee channel to 24 - must be standard among robots */
295
        wl_set_channel(24);
296

    
297
        int robotid = get_robotid();
298
        int centerid = 0;                // once the EDGE gets the first signal from a center, it stores who the center is.
299
        int used[17];                        // stores a list of bots which are in the group by storing a "1" in the array if the robot of that index is in the group.
300
        for (int i=0; i<17; i++) used[i] = 0;                // initially, no robots in the group.
301

    
302
        int data_length;                // keeps track of the length of wireless packets received.
303
        unsigned char *packet_data=wl_basic_do_default(&data_length);
304
        
305
        int state = WAITINGSTATE;
306
        int beacon_State=0;                // these variables keep track of the inner state machines in the procedural MACHINE states.
307
        int edge_State=0;
308

    
309
        int waitingCounter=0;
310
        int robotsReceived=0;                // an important variable that stores the size of the group.
311
        int offset = 20;                // offset for the approaching: how far off the rangefinders can be
312
        int time=0;
313
        int direction = 4;                // keeps track of which way robots are facing relative to the center
314
        int distance=1000;                // how far away the robot is.  Initialized to a large value to ensure that the robot doesn't think it is already the
315
                                                // right distance away.
316
        int onefoot = 250;                // how far away to stop.
317
        
318
        while(1)
319
        {
320
                bom_refresh(BOM_ALL);
321

    
322
                                /*                
323
                                *******EXPECTED MOVES **********   (OUT OF DATE.  Will be updated once changes have been made.)
324
                                The designed movement:
325
                                 1. one center robot, several edge robots are on;
326
                                 2. center robots: button 1 is pressed;
327
                                 3. center robots: send global package telling edges that he exists;
328
                                 4. EDGE robots response with ACK. 
329
                                 5. EDGE robots wait for center robots to finish counting (DONE package)
330
                                 6. EDGE robtos approach the center robtot and stop at the "onefoot" distance, send message to the center
331
                                */
332
                
333
                
334
                /* This is the MAIN SWITCH LOOP, which governs the overall status of the robot. */
335
                switch(state)
336
                {
337

    
338

    
339
                        /*
340
                                The WAITINGSTATE.  This state constantly checks for wireless packets,
341
                                and updates its state as soon as it receives a signal.
342
                        */
343
                        case 0:
344

    
345
                                packet_data=wl_basic_do_default(&data_length);
346
                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_CLAIM_CENTER)
347
                                {
348
                                        centerid = packet_data[1];
349

    
350
                                        send2(CIRCLE_ACTION_ACK,robotid);
351

    
352
                                        state = EDGE_CONTROL;
353
                                }
354

    
355
                                if(button1_read())
356
                                {
357
                                        send2(CIRCLE_CLAIM_CENTER, robotid);         // becomes the center if button1 is clicked.
358
                                }
359

    
360
                        break;
361

    
362

    
363

    
364
//***********************************************************************************************************************************************************************************
365

    
366

    
367

    
368
                        /*
369
                                The CONTROL for the EDGE state.  This sets a certain procedure to follow, in the form of simple
370
                                commands, for a robot to follow if it is set to an EDGE.
371
                        */
372

    
373
                        case 1:
374

    
375
                        break;
376

    
377

    
378

    
379
//***********************************************************************************************************************************************************************************
380

    
381

    
382

    
383
                        /*
384
                                The CONTROL for the BEACON state.  This sets a certain procedure to follow, in the form of simple
385
                                commands, for a robot to follow if it is set to a BEACON.
386
                        */
387
                        case 2:
388

    
389
                        break;
390

    
391

    
392

    
393
//***********************************************************************************************************************************************************************************
394

    
395

    
396
                        /*
397
                                The MACHINE for the EDGE state.
398
                        */
399
                        case 3:        
400

    
401
                                switch(edge_State)
402
                                {
403
                                        /*
404
                                                0. EDGE robots are on. 
405
                                                1. They are waiting for EXIST pacakage from the Center robots
406
                                                2. After they receive the package, they send ACK package to center.
407
                                                3. Done for now: display green.
408
                                        */
409
                                        case 0:   
410
                                                bom_off();
411
                                                orb1_set_color(YELLOW);
412
                                                orb2_set_color(CYAN);
413
                                                packet_data=wl_basic_do_default(&data_length);
414
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_EXIST)
415
                                                {
416
                                                        centerid = packet_data[1];
417

    
418
                                                        send2(CIRCLE_ACTION_ACK,robotid);
419

    
420
                                                        edge_State=1;
421
                                                }
422
                                        break;
423
                                        /*
424
                                                1. Wait for DONE package 
425
                                                2. The counting process is DONE
426
                                        */
427
                                        case 1:                
428
                                        
429
                                                orb_set_color(YELLOW);
430
                                                orb2_set_color(PURPLE);
431

    
432
                                                send2(CIRCLE_ACTION_ACK,robotid);                // keep sending the packet until we get a response
433
                                                
434
                                                packet_data=wl_basic_do_default(&data_length);
435
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_GOTYOU && packet_data[1] == robotid)
436
                                                {
437
                                                        edge_State=2;
438
                                                }
439
                                        break;
440

    
441
                                        case 2:        // wait for the second, general, done packet.
442

    
443
                                                orb_set_color(YELLOW);
444
                                                packet_data=wl_basic_do_default(&data_length);
445
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE && packet_data[1] == centerid)
446
                                                {
447
                                                        edge_State=3;
448
                                                }
449
                                        break;
450
                                        
451
                                        case 3:
452
                                                // COLOR afer DONE ---> MAGENTA
453
                                                orb_set_color(MAGENTA);
454
                                                correctTurn();                        // turn to face the beacon
455
                                                forward(175);
456
                                                //range_init();
457
                                                
458
                                                
459
                                                distance = get_distance();
460
                                                time=0;
461
                                                while ((distance-offset)>=onefoot || distance==0 || (distance+offset)<onefoot)
462
                                                {
463
                                                        if(distance==0)
464
                                                                orb_set_color(WHITE);
465
                                                        else if(distance-offset>=onefoot)
466
                                                                forward(175);
467
                                                        else
468
                                                                backward(175);
469
                                                        //correctApproach();
470
                                                        distance = get_distance();
471
                                                        delay_ms(14);
472
                                                        time+=14;
473
                                                        if(time>50)
474
                                                        {
475
                                                                correctTurn();
476
                                                                time=0;
477
                                                        }
478
                                                }
479
                                                        
480
                                                stop();
481
                                                orb_set_color(GREEN);
482

    
483
                                                send2(CIRCLE_ACTION_ACK, robotid);
484

    
485
                                                stop();
486
                                                edge_State=4;
487
                                        break;
488

    
489
                                        // waits for a packet to tell it to turn on the bom.
490
                                        case 4:
491
                                                packet_data=wl_basic_do_default(&data_length);
492
                                                if(packet_data != 0 && data_length==2 && packet_data[0]==CIRCLE_ACTION_GOTYOU && packet_data[1] == robotid)
493
                                                {
494
                                                        bom_on();
495
                                                        orb_set_color(ORANGE);
496
                                                        send2(CIRCLE_ACTION_ACK,centerid);
497
                                                        edge_State = 5;
498
                                                }
499
                                        break;
500

    
501
                                        // waits for a packet to tell it that it has been received.
502
                                        case 5:
503
                                                orb2_set_color(YELLOW);
504
                                                packet_data=wl_basic_do_default(&data_length);
505
                                                if(packet_data != 0 && data_length==3 && packet_data[0]==CIRCLE_ACTION_GOTYOU && packet_data[1] == robotid)
506
                                                {
507
                                                        bom_off();
508
                                                        direction = packet_data[2];
509
                                                        orb_set_color(YELLOW);
510
                                                        edge_State = 6;
511
                                                }
512
                                        break;
513

    
514
                                        /* Wait for the center bot to send a DONE packet; then turn to face the right direction. */
515
                                        case 6:
516
                                                orb_set_color(GREEN);
517
                                                packet_data=wl_basic_do_default(&data_length);
518
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE)
519
                                                {
520
                                                        orb_set_color(WHITE);
521
                                                        orb2_set_color(CYAN);
522
                                                        edge_State = 7;
523
                                                }
524
                                        break;
525

    
526
                                        /* Turn until we reach the right direction (DIRECTION) */
527
                                        case 7:
528
                                                left(170);
529
                                                bom_refresh(BOM_ALL);
530
                                                if(bom_get_max() == direction)
531
                                                {
532
                                                        stop();
533
                                                        orb_set_color(YELLOW);
534
                                                        edge_State = 8;
535
                                                }
536
                                        break;
537

    
538
                                        /* Wait for the command to move forward. */
539
                                        case 8:
540
                                                packet_data=wl_basic_do_default(&data_length);
541
                                                if(packet_data != 0 && data_length>=3 && packet_data[0]==CIRCLE_ACTION_FORWARD)
542
                                                {
543
                                                        orb_set_color(BLUE);
544
                                                        forward(200);
545
                                                        delay_ms(2000);
546
                                                        edge_State = END;
547
                                                }
548
                                        break;
549

    
550
                                        /* Terminal. */
551
                                        case 100:
552
                                                stop();
553
                                                orb_set_color(GREEN);
554
                                                orb2_set_color(WHITE);
555
                                                while(1);
556
                                        break;
557

    
558

    
559
                                }        // end the EdgeState switch
560

    
561
                        break;                // break the Edge state in the main switch loop
562
                                
563
                        // END for EDGE robots
564
                        
565

    
566

    
567

    
568

    
569

    
570
//***********************************************************************************************************************************************************************************
571

    
572

    
573

    
574

    
575
                        /*
576
                           The MACHINE for the BEACON state
577
                        */        
578
                        case 4:
579
                                switch(beacon_State) 
580
                                {
581

    
582
                                        /* 0. center  robots on wait for pressing button 1 */
583
                                        case 0:
584
                                                bom_on();
585
                                                orb_set_color(PURPLE);
586
                                                if(button1_click()) beacon_State=1;
587
                                        break;        
588

    
589
                                        /* 1. Send EXIST package to EDGE robots */
590
                                        case 1:
591
                                                orb_set_color(RED);
592
                                                send2(CIRCLE_ACTION_EXIST,robotid);
593
                                                beacon_State=2;
594
                                        break;
595

    
596
                                        /* 2. Count the number of the EDGE robots *******NOTE: at most  1000  times of loop ******  */
597
                                        case 2:
598
                                                waitingCounter++;
599
                                                orb1_set_color(YELLOW);
600
                                                orb2_set_color(BLUE);
601
                                                packet_data=wl_basic_do_default(&data_length);
602
                                        
603
                                                if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
604
                                                {
605
                                                        orb_set_color(RED);
606
                                                        orb2_set_color(BLUE);
607
                                                        //only add to robots seen if you haven't gotten an ACK from this robot
608
                                                        if(used[packet_data[1]]==0)
609
                                                        {
610
                                                                robotsReceived++;
611
                                                                used[packet_data[1]] = 1;
612

    
613
                                                                usb_puts("Added: ");
614
                                                                usb_puti(packet_data[1]);
615
                                                                usb_puts("\r\n");
616
                                                        }
617

    
618
                                                        // NEW: sends a packet to each robot it receives telling them to be done.
619
                                                        send2(CIRCLE_ACTION_GOTYOU,packet_data[1]);
620
                                                }
621
                                                if(waitingCounter >= 300){
622
                                                        beacon_State=3;
623
                                                }
624
                                        break;
625

    
626
                                        /* COUNTing is DONE.  Sending DONE package. */        
627
                                        case 3:
628
                                                blink(robotsReceived);
629
                                                orb_set_color(GREEN);
630
                                                send2(CIRCLE_ACTION_DONE, robotid);
631
                                                beacon_State=4;
632
                                        break;
633

    
634
                                        /* Wait for all the robots to get to right distance/position */
635
                                        case 4: 
636
                                                left(170);
637
                                                orb1_set_color(YELLOW);
638
                                                orb2_set_color(WHITE);
639
                                        
640
                                                int numOk = 0;
641
                                        
642
                                                while(numOk<robotsReceived)
643
                                                {
644
                                                        packet_data=wl_basic_do_default(&data_length);
645
                                                        if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
646
                                                        {
647
                                                                numOk++;
648
                                                        }
649
                                                }
650
                                        
651
                                                beacon_State = 5;
652
                                        break; 
653
                                
654
                                        /* Turns all the robots in the same direction */
655
                                        case 5:
656
                                                stop();
657
                                                bom_off();
658
                                                orb_set_color(ORANGE);
659
                                                
660
                                                // for each robot, tells them to turn their bom on, then tells them which way they should face.
661
                                                for(int i=0; i < 17; i++)
662
                                                {
663
                                                        if(used[i] == 1)
664
                                                        {
665
                                                                send2(CIRCLE_ACTION_GOTYOU, i);
666
                                                                while(1)        // waits for a response so it knows the BOM is on.
667
                                                                {
668
                                                                        orb_set_color(RED);
669
                                                                        orb2_set_color(WHITE);
670
                                                                        packet_data=wl_basic_do_default(&data_length);
671
                                                                        if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
672
                                                                        {
673
                                                                                orb_set_color(ORANGE);
674
                                                                                break;
675
                                                                        }
676
                                                                }
677

    
678
                                                                bom_refresh(BOM_ALL);
679
                                                                direction = bom_get_max();
680
                                                                direction += 8;
681
                                                                if(direction > 15) direction -= 16;
682
                                                                send3(CIRCLE_ACTION_GOTYOU, i, direction);
683
                                                                delay_ms(20);
684
                                                        }
685
                                                }
686
                                                beacon_State = 6;
687
                                        break;
688
                        
689
                                        /* Sends a DONE packet to signify that it has read in all the robots' directions and sent packets.
690
                                                Edge robots should now turn to face the right direction. */
691
                                        case 6:
692
                                                send2(CIRCLE_ACTION_DONE,robotid);
693
                                                bom_on();
694
                                                beacon_State = 7;
695
                                        break;
696

    
697
                                        /* Tells the robots to move forward and moves itself. */
698
                                        case 7:
699
                                                orb_set_color(YELLOW);
700
                                                delay_ms(5000);
701

    
702
                                                // format: type of ack, speed, time.
703
                                                send3(CIRCLE_ACTION_FORWARD,200,2000);
704
                                                orb_set_color(BLUE);
705
                                                forward(200);
706
                                                delay_ms(2000);
707
                                                stop();
708
                                                beacon_State = END;
709
                                        break;
710

    
711
                                        /* Terminal. */
712
                                        case 100:
713
                                                stop();
714
                                                orb_set_color(GREEN);
715
                                                orb2_set_color(WHITE);
716
                                                while(1);
717
                                        break;
718
                                }
719
                        break;
720

    
721
//***********************************************************************************************************************************************************************************
722
                        
723
                }        // ends the main switch
724
        }                // ends the main while loop
725

    
726
        orb_set_color(RED);        // error, we should never break from the while loop!
727

    
728
        while(1); /* END HERE, just in case something happened.  This way we can see the red orb. */
729
}
730

    
731