Statistics
| Revision:

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

History | View | Annotate | Download (23.4 KB)

1 1749 azirbel
2 1749 azirbel
/*** PROGRAM INFORMATION ***
3 1749 azirbel
4 1806 azirbel
   This program assembles a group of robots into a circle and allows the
5 1806 azirbel
movement within that formation.  Robots should be able to break formation and
6 1806 azirbel
travel as a line, readjust in the face of obstacles, and reform if conditions
7 1806 azirbel
are necessary.
8 1749 azirbel
9 1806 azirbel
   The program begins waiting for a button press.  When pressed, a robot assumes
10 1806 azirbel
the BEACON position, which means that it is the robot in the center of the
11 1806 azirbel
circle and therefore in charge.  It then gathers robots around it by sending
12 1806 azirbel
them commands.  This code is executed using two finite state machines, nested
13 1806 azirbel
inside one another.
14 1806 azirbel
   One controls the overall state of the robot (whether it is a BEACON, an EDGE,
15 1806 azirbel
or WAITING, for example).
16 1749 azirbel
17 1806 azirbel
   This code should be implemented so that most useful functions are built in
18 1806 azirbel
to the machine.  For example, the BEACON robot should be able to call methods
19 1806 azirbel
such as CircleUp() to gather robots around it, and Move(distance) to move the
20 1806 azirbel
circle group all at once.
21 1749 azirbel
22 1806 azirbel
   This Code is the property of the Carnegie Mellon Robotics Club and is being
23 1806 azirbel
used to test formation control in a low-cost robot colony.  Thanks to all
24 1806 azirbel
members of RoboClub, especially Colony president John Sexton and graduade
25 1806 azirbel
student representative Chris Mar.
26 1749 azirbel
27 1806 azirbel
   AUTHORS: James Carroll, Steve DeVincentis, Hanzhang (Echo) Hu, Nico Paris,
28 1807 azirbel
Joel Rey, Reva Street, Alex Zirbel
29 1807 azirbel
         */
30 1749 azirbel
31 1749 azirbel
32 1594 azirbel
#include <dragonfly_lib.h>
33 1594 azirbel
#include <wl_basic.h>
34 1594 azirbel
#include <encoders.h>
35 1594 azirbel
#include "circle.h"
36 1594 azirbel
37 1749 azirbel
/*** TODO: ***
38 1626 gnagaraj
39 1806 azirbel
   -Transform the code into a method-based state machine that uses the
40 1806 azirbel
procedural state machines, which are hardcoded and hard to edit, as a backup.
41 1691 azirbel
42 1806 azirbel
   -Implement a drive straight method for use in keeping the robots more
43 1806 azirbel
accurate as a group.
44 1806 azirbel
45 1806 azirbel
   -Fix the approach method: good robots usually work well, but bad robots often
46 1806 azirbel
have errors which might be avoidable with the use of error checking.
47 1806 azirbel
48 1806 azirbel
   -Make robots more robust: packages are often lost, which throws the entire
49 1806 azirbel
procedural nature of the program off.
50 1806 azirbel
51 1806 azirbel
   -Consider using the center bot to check distances
52 1806 azirbel
53 1807 azirbel
   -More testing is always good and necessary.
54 1807 azirbel
*/
55 1806 azirbel
56 1749 azirbel
/*** BOT LOG ***
57 1691 azirbel
58 1806 azirbel
   4-1-2010: BOT 7 as BEACON and BOT 1 as EDGE worked extremely well.
59 1806 azirbel
   4-2-2010: BOT 7 and BOT 14 worked extremely well, no matter states.  BOT 1
60 1807 azirbel
               started well, but malfunctioned later.
61 1807 azirbel
        */
62 1691 azirbel
63 1749 azirbel
/*** TERMINOLOGY ***
64 1691 azirbel
65 1807 azirbel
  WAITINGSTATE:
66 1807 azirbel
   The robot waits to be given a signal to do something.  Wireless is on,
67 1807 azirbel
in case the robot is called on to turn into an EDGE.  The color should be LIME
68 1807 azirbel
or YELLOW-GREEN.
69 1594 azirbel
70 1807 azirbel
  BEACON_CONTROL:
71 1807 azirbel
   The code that executes commands when a robot is turned to BEACON mode.  This
72 1807 azirbel
code may run predefined methods for simplicity.  One goal is to make these
73 1807 azirbel
methods change the robot turn to to BEACON_MACHINE mode for a while, and then
74 1807 azirbel
return to the CONTROL code where they left off.
75 1594 azirbel
76 1807 azirbel
  EDGE_CONTROL:
77 1807 azirbel
   Like BEACON_CONTROL, executes whatever orders are required of the robot as an
78 1807 azirbel
EDGE.
79 1594 azirbel
80 1807 azirbel
  BEACON_MACHINE:
81 1807 azirbel
   A hardcoded list of functions which the robot is capable of running through.
82 1807 azirbel
Consists of a finite state machine, where the robot executes a set of commands
83 1807 azirbel
in a procedural manner and then returns to wherever it was in the control code.
84 1594 azirbel
85 1807 azirbel
  EDGE_MACHINE:
86 1807 azirbel
   Like the BEACON_MACHINE, but contains the same sort of procedural information
87 1807 azirbel
for EDGE robots.
88 1749 azirbel
89 1807 azirbel
  END:
90 1807 azirbel
   A terminal state of the machine, where the robot just sits and waits.  The
91 1807 azirbel
color should be GREEN and WHITE.
92 1749 azirbel
93 1749 azirbel
94 1807 azirbel
  TYPES OF WIRELESS PACKETS:
95 1749 azirbel
96 1807 azirbel
   CIRCLE_ACTION_EXIST 'E'
97 1807 azirbel
   CIRCLE_ACTION_POSITION 'P'
98 1807 azirbel
   CIRCLE_ACTION_ACK 'A'
99 1807 azirbel
         A general acknowledgement package.
100 1807 azirbel
   CIRCLE_ACTION_DONE 'D'
101 1807 azirbel
         Used by robots to tell when they have finished their action.
102 1807 azirbel
   CIRCLE_ACTION_GOTYOU 'G'
103 1807 azirbel
         Used by the BEACON to tell a robot when it has been checked off.
104 1807 azirbel
         At this point, the EDGE has been recognized.  Used for times when
105 1807 azirbel
         all EDGE robots have to communicate to the center via the spam method.
106 1807 azirbel
   CIRCLE_ACTION_FORWARD 'F'
107 1807 azirbel
         The BEACON tells the rest of the robots to move forward.
108 1807 azirbel
   CIRCLE_CLAIM_CENTER 'C'
109 1807 azirbel
         Sent out by a robot when it takes over as BEACON.
110 1807 azirbel
         */
111 1749 azirbel
112 1749 azirbel
113 1807 azirbel
/* Define some variables to keep track of the state machine.*/
114 1749 azirbel
int END = 100;
115 1807 azirbel
int WAITINGSTATE = 0;
116 1749 azirbel
int EDGE_CONTROL = 1;
117 1749 azirbel
int BEACON_CONTROL = 2;
118 1749 azirbel
int EDGE_MACHINE = 3;
119 1749 azirbel
int BEACON_MACHINE = 4;
120 1749 azirbel
121 1774 azirbel
int COUNT = 0;
122 1774 azirbel
int CIRCLEUP = 1;
123 1774 azirbel
int ORIENT = 2;
124 1774 azirbel
int DRIVE = 3;
125 1807 azirbel
int TURNL = 4;
126 1807 azirbel
int TURNR = 5;
127 1749 azirbel
128 1774 azirbel
int currentPos = 0;
129 1774 azirbel
int state = 0;
130 1774 azirbel
131 1807 azirbel
// keep track of the speed and duration of group movements.
132 1807 azirbel
int speed = 20;
133 1807 azirbel
int duration = 2;
134 1774 azirbel
135 1720 azirbel
int timeout = 0;
136 1720 azirbel
int sending = 0;
137 1720 azirbel
int stop2 = 0;
138 1720 azirbel
struct vector slave_position;
139 1720 azirbel
int desired_max_bom;
140 1720 azirbel
int bom_max_counter;
141 1618 jmcarrol
142 1618 jmcarrol
143 1720 azirbel
void switch_sending(void)
144 1720 azirbel
{
145 1720 azirbel
        if(sending)
146 1720 azirbel
        {
147 1720 azirbel
                sending = 0;
148 1720 azirbel
                bom_off();
149 1720 azirbel
        }
150 1720 azirbel
        else
151 1720 azirbel
        {
152 1720 azirbel
                sending = 1;
153 1720 azirbel
                bom_on();
154 1720 azirbel
        }
155 1720 azirbel
}
156 1720 azirbel
157 1807 azirbel
// set the motors to this forward speed.
158 1807 azirbel
void forward(int speed)
159 1807 azirbel
{
160 1594 azirbel
        motor_l_set(FORWARD,speed);
161 1594 azirbel
        motor_r_set(FORWARD,speed);
162 1594 azirbel
}
163 1807 azirbel
// turn left at this speed.
164 1807 azirbel
void left(int speed)
165 1807 azirbel
{
166 1806 azirbel
        motor_l_set(BACKWARD,speed);
167 1806 azirbel
        motor_r_set(FORWARD,speed);
168 1806 azirbel
}
169 1807 azirbel
void right(int speed)
170 1807 azirbel
{
171 1594 azirbel
        motor_l_set(FORWARD,speed);
172 1594 azirbel
        motor_r_set(BACKWARD,speed);
173 1594 azirbel
}
174 1807 azirbel
// stop() is better than motors_off(), which creates a slight delay when
175 1807 azirbel
// reactivating the motors.  Stop() is faster.
176 1807 azirbel
void stop(void)
177 1807 azirbel
{
178 1807 azirbel
        motor_l_set(BACKWARD,0);
179 1594 azirbel
        motor_r_set(FORWARD,0);
180 1594 azirbel
}
181 1807 azirbel
void setforward(int spd1, int spd2)
182 1807 azirbel
{
183 1594 azirbel
        motor_l_set(FORWARD,spd1);
184 1594 azirbel
        motor_r_set(FORWARD,spd2);
185 1594 azirbel
}
186 1807 azirbel
void backward(int speed)
187 1807 azirbel
{
188 1594 azirbel
        motor_l_set(BACKWARD, speed);
189 1594 azirbel
        motor_r_set(BACKWARD, speed);
190 1594 azirbel
}
191 1807 azirbel
// takes an averaged reading of the front rangefinder
192 1807 azirbel
int get_distance(void)
193 1807 azirbel
{
194 1807 azirbel
        // kk sets this to 5 readings.
195 1807 azirbel
        int temp,distance,kk=5;
196 1594 azirbel
        distance =0;
197 1807 azirbel
        for (int i=0; i<kk; i++)
198 1807 azirbel
        {
199 1594 azirbel
                temp = range_read_distance(IR2);
200 1594 azirbel
                if (temp == -1)
201 1594 azirbel
                {
202 1594 azirbel
                        //temp=0;
203 1594 azirbel
                        i--;
204 1594 azirbel
                }
205 1594 azirbel
                else
206 1594 azirbel
                        distance+= temp;
207 1594 azirbel
                delay_ms(3);
208 1594 azirbel
        }
209 1594 azirbel
        if (kk>0)
210 1594 azirbel
                return (int)(distance/kk);
211 1594 azirbel
        else
212 1594 azirbel
                return 0;
213 1594 azirbel
}
214 1618 jmcarrol
215 1724 azirbel
/* Sends a global packet with two arguments */
216 1724 azirbel
void send2(char arg0, char arg1)
217 1720 azirbel
{
218 1722 azirbel
        char send_buffer[2];
219 1724 azirbel
        send_buffer[0]=arg0;
220 1724 azirbel
        send_buffer[1]=arg1;
221 1720 azirbel
        wl_basic_send_global_packet(42,send_buffer,2);
222 1720 azirbel
}
223 1618 jmcarrol
224 1724 azirbel
/* Sends a global packet with three arguments */
225 1724 azirbel
void send3(char arg0, char arg1, char arg2)
226 1724 azirbel
{
227 1725 azirbel
        char send_buffer[3];
228 1724 azirbel
        send_buffer[0]=arg0;
229 1724 azirbel
        send_buffer[1]=arg1;
230 1724 azirbel
        send_buffer[2]=arg2;
231 1749 azirbel
        wl_basic_send_global_packet(42,send_buffer,3);
232 1724 azirbel
}
233 1724 azirbel
234 1639 azirbel
/*
235 1807 azirbel
   Orients the robot so that it is facing the beacon (or the broadcasting BOM).
236 1626 gnagaraj
*/
237 1805 azirbel
void faceFront(void)
238 1618 jmcarrol
{
239 1808 azirbel
        int counter = 0;
240 1808 azirbel
        int currentDir = 0;
241 1808 azirbel
        left(200);
242 1799 alevkoy
        int bomNum = -1;
243 1805 azirbel
        orb1_set_color(BLUE);
244 1805 azirbel
        while(bomNum != 4)
245 1618 jmcarrol
        {
246 1808 azirbel
                if(counter >= 5)
247 1808 azirbel
                {
248 1808 azirbel
                        forward(200);
249 1808 azirbel
                        delay_ms(750);
250 1808 azirbel
                        counter = 0;
251 1808 azirbel
                }
252 1627 gnagaraj
                bom_refresh(BOM_ALL);
253 1799 alevkoy
                bomNum = bom_get_max();
254 1805 azirbel
                if(bomNum == -1)
255 1618 jmcarrol
                {
256 1805 azirbel
                        //ignore
257 1799 alevkoy
                }
258 1805 azirbel
                else if((bomNum < 4) || (bomNum >= 12))
259 1799 alevkoy
                {
260 1805 azirbel
                        right(200);
261 1808 azirbel
                        if(currentDir == 0)
262 1808 azirbel
                                counter++;
263 1808 azirbel
                        currentDir = 1;
264 1618 jmcarrol
                }
265 1805 azirbel
                else
266 1618 jmcarrol
                {
267 1805 azirbel
                        left(200);
268 1808 azirbel
                        if(currentDir == 1)
269 1808 azirbel
                                counter++;
270 1808 azirbel
                        currentDir = 0;
271 1618 jmcarrol
                }
272 1618 jmcarrol
        }
273 1805 azirbel
        stop();
274 1627 gnagaraj
        return;
275 1618 jmcarrol
}
276 1618 jmcarrol
277 1807 azirbel
/*
278 1807 azirbel
   Turns the robot slowly to the right until it reaches the BOM reading goal.
279 1807 azirbel
   More stable code than what was implemented ealier, with smart turning,
280 1807 azirbel
   but slower.
281 1807 azirbel
*/
282 1805 azirbel
void aboutFace(int goal)
283 1805 azirbel
{
284 1805 azirbel
        int bomNum = -1;
285 1805 azirbel
        int speed = 170;        // speed with which to turn
286 1626 gnagaraj
287 1807 azirbel
        orb1_set_color(BLUE);        // BLUE and PURPLE
288 1805 azirbel
289 1805 azirbel
        while(bomNum != goal)
290 1805 azirbel
        {
291 1805 azirbel
                // bomNum is the current maximum reading
292 1805 azirbel
                bom_refresh(BOM_ALL);
293 1805 azirbel
                bomNum = bom_get_max();
294 1805 azirbel
                right(speed);
295 1805 azirbel
        }
296 1805 azirbel
        stop();
297 1805 azirbel
        return;
298 1805 azirbel
}
299 1805 azirbel
300 1805 azirbel
301 1639 azirbel
/*
302 1807 azirbel
   BLINK the given number times
303 1626 gnagaraj
*/
304 1717 azirbel
void blink(int num)
305 1717 azirbel
{
306 1594 azirbel
        for(int i = 0; i<num; i++)
307 1594 azirbel
        {
308 1594 azirbel
                orb_set_color(ORB_OFF);
309 1724 azirbel
                delay_ms(150);
310 1594 azirbel
                orb_set_color(RED);
311 1724 azirbel
                delay_ms(50);
312 1594 azirbel
        }
313 1594 azirbel
        orb_set_color(ORB_OFF);
314 1594 azirbel
}
315 1594 azirbel
316 1725 azirbel
/*
317 1807 azirbel
   BLINK slowly the given number times
318 1725 azirbel
*/
319 1725 azirbel
void slowblink(int num)
320 1725 azirbel
{
321 1725 azirbel
        for(int i = 0; i<num; i++)
322 1725 azirbel
        {
323 1725 azirbel
                orb_set_color(ORB_OFF);
324 1725 azirbel
                delay_ms(300);
325 1725 azirbel
                orb_set_color(RED);
326 1725 azirbel
                delay_ms(200);
327 1725 azirbel
        }
328 1725 azirbel
        orb_set_color(ORB_OFF);
329 1725 azirbel
}
330 1594 azirbel
331 1807 azirbel
/*
332 1807 azirbel
   A method for the higher-level code for the BEACON.  The beacon can make
333 1807 azirbel
   any of the preprogrammed commands, and this code sends the packet and
334 1807 azirbel
   transitions the robots correctly.
335 1807 azirbel
*/
336 1774 azirbel
void order(int action)
337 1774 azirbel
{
338 1774 azirbel
        currentPos++;
339 1774 azirbel
        send2(CIRCLE_EXECUTE, action);
340 1774 azirbel
        state = 20 + action;
341 1774 azirbel
}
342 1594 azirbel
343 1807 azirbel
/*
344 1807 azirbel
   A method for the higher-level code for the BEACON.  The beacond sends
345 1807 azirbel
   not only the command, but also the speed and duration for which the
346 1807 azirbel
   (movement) command is to be executed.
347 1807 azirbel
*/
348 1807 azirbel
void orderMove(int action, int newSpeed, int newDuration)
349 1807 azirbel
{
350 1807 azirbel
        currentPos++;
351 1807 azirbel
        speed = newSpeed;
352 1807 azirbel
        duration = newDuration;
353 1807 azirbel
        send2(CIRCLE_EXECUTE, action);
354 1807 azirbel
        state = 20 + action;
355 1807 azirbel
}
356 1807 azirbel
357 1807 azirbel
/*
358 1807 azirbel
   Turns off the motors, sends an EXECUTE packet, and blinks green and white
359 1807 azirbel
   forever.
360 1807 azirbel
*/
361 1774 azirbel
void terminate(void)
362 1774 azirbel
{
363 1807 azirbel
        motors_off();
364 1774 azirbel
        send2(CIRCLE_EXECUTE, 100);
365 1774 azirbel
        orb_set_color(GREEN);
366 1774 azirbel
        orb2_set_color(WHITE);
367 1774 azirbel
        while(1) ;
368 1774 azirbel
}
369 1626 gnagaraj
370 1626 gnagaraj
371 1807 azirbel
//******************************************************************************
372 1807 azirbel
//******************************************************************************
373 1807 azirbel
//******************************************************************************
374 1639 azirbel
375 1774 azirbel
376 1639 azirbel
377 1639 azirbel
/*
378 1807 azirbel
   A state machine with five states.  The robot starts out in WAITINGSTATE mode,
379 1807 azirbel
from which it recieves a signal of some sort and moves to a different state.
380 1639 azirbel
*/
381 1594 azirbel
int main(void)
382 1594 azirbel
{
383 1594 azirbel
        /* Initialize dragonfly board */
384 1618 jmcarrol
            dragonfly_init(ALL_ON);
385 1618 jmcarrol
            /* Initialize the basic wireless library */
386 1618 jmcarrol
            wl_basic_init_default();
387 1749 azirbel
            /* Set the XBee channel to 24 - must be standard among robots */
388 1594 azirbel
        wl_set_channel(24);
389 1594 azirbel
390 1594 azirbel
        int robotid = get_robotid();
391 1749 azirbel
392 1807 azirbel
        // once the EDGE gets the first signal from a center, it stores who the         // center is.
393 1807 azirbel
        int centerid = 0;
394 1807 azirbel
395 1807 azirbel
        // stores a list of bots which are in the group by storing a "1" in the
396 1807 azirbel
        // array if the robot of that index is in the group.
397 1807 azirbel
        int used[17];
398 1807 azirbel
        int numOk;
399 1807 azirbel
400 1807 azirbel
        // initially, no robots in the group.
401 1807 azirbel
        for (int i=0; i<17; i++)
402 1807 azirbel
                used[i] = 0;
403 1807 azirbel
404 1807 azirbel
        // keeps track of the length of wireless packets received.
405 1807 azirbel
        int data_length;
406 1594 azirbel
        unsigned char *packet_data=wl_basic_do_default(&data_length);
407 1807 azirbel
408 1807 azirbel
        // these variables keep track of the inner state machines in the
409 1807 azirbel
        //  procedural MACHINE states.
410 1807 azirbel
        int beacon_State=0;
411 1635 sdevince
        int edge_State=0;
412 1749 azirbel
413 1610 azirbel
        int waitingCounter=0;
414 1807 azirbel
415 1807 azirbel
        // an important variable that stores the size of the group.
416 1807 azirbel
        int robotsReceived=0;
417 1807 azirbel
418 1807 azirbel
        // offset for the approaching: how far off the rangefinders can be
419 1807 azirbel
        int offset = 20;
420 1724 azirbel
        int time=0;
421 1807 azirbel
422 1807 azirbel
        // keeps track of which way robots are facing relative to the center
423 1807 azirbel
        int direction = 4;
424 1807 azirbel
425 1807 azirbel
        // how far away the robot is.  Initialized to a large value to ensure
426 1807 azirbel
        // that the robot doesn't think it is already the right distance away.
427 1807 azirbel
        int distance=1000;
428 1807 azirbel
        int onefoot = 250;        // how far away to stop.
429 1627 gnagaraj
430 1596 azirbel
        while(1)
431 1596 azirbel
        {
432 1626 gnagaraj
                bom_refresh(BOM_ALL);
433 1749 azirbel
434 1807 azirbel
        /***EXPECTED MOVES***
435 1807 azirbel
           (OUT OF DATE.  Will be updated once changes have been made.)
436 1807 azirbel
        The designed movement:
437 1807 azirbel
         1. one center robot, several edge robots are on;
438 1807 azirbel
         2. center robots: button 1 is pressed;
439 1807 azirbel
         3. center robots: send global package telling edges that he exists;
440 1807 azirbel
         4. EDGE robots response with ACK.
441 1807 azirbel
         5. EDGE robots wait for center robots to finish counting (DONE package)
442 1807 azirbel
         6. EDGE robtos approach the center robtot and stop at the "onefoot"
443 1807 azirbel
                 distance, send message to the center
444 1807 azirbel
                */
445 1626 gnagaraj
446 1626 gnagaraj
447 1807 azirbel
                /*
448 1807 azirbel
                  This is the MAIN SWITCH LOOP, which governs the overall
449 1807 azirbel
                  status of the robot.
450 1807 azirbel
                 */
451 1596 azirbel
                switch(state)
452 1596 azirbel
                {
453 1749 azirbel
454 1749 azirbel
455 1807 azirbel
                /*
456 1807 azirbel
                The WAITINGSTATE.  This state constantly checks for wireless
457 1807 azirbel
                packets,
458 1807 azirbel
                and updates its state as soon as it receives a signal.
459 1807 azirbel
                */
460 1807 azirbel
                case 0:
461 1717 azirbel
462 1807 azirbel
                        orb_set_color(YELLOW);
463 1807 azirbel
                        packet_data=wl_basic_do_default(&data_length);
464 1807 azirbel
                        if(packet_data != 0 && data_length>=2
465 1807 azirbel
                                && packet_data[0]==CIRCLE_CLAIM_CENTER)
466 1807 azirbel
                        {
467 1807 azirbel
                                centerid = packet_data[1];
468 1807 azirbel
                                state = 1;
469 1807 azirbel
                        }
470 1749 azirbel
471 1807 azirbel
                        if(button1_read())
472 1807 azirbel
                        {
473 1807 azirbel
                                // becomes the center if button1 is clicked.
474 1807 azirbel
                                send2(CIRCLE_CLAIM_CENTER, robotid);
475 1807 azirbel
                                state = 2;
476 1807 azirbel
                        }
477 1807 azirbel
                break;
478 1749 azirbel
479 1749 azirbel
480 1749 azirbel
481 1807 azirbel
//******************************************************************************
482 1807 azirbel
//******************************************************************************
483 1749 azirbel
484 1749 azirbel
485 1807 azirbel
                /*
486 1807 azirbel
                The CONTROL for the EDGE state.  This sets a certain procedure
487 1807 azirbel
                to follow, in the form of simple
488 1807 azirbel
                commands, for a robot to follow if it is set to an EDGE.
489 1807 azirbel
                */
490 1749 azirbel
491 1807 azirbel
                case 1:
492 1807 azirbel
                        orb_set_color(CYAN);
493 1807 azirbel
                        orb1_set_color(YELLOW);
494 1749 azirbel
495 1807 azirbel
                        int command = -1;
496 1807 azirbel
497 1807 azirbel
                        packet_data=wl_basic_do_default(&data_length);
498 1749 azirbel
499 1807 azirbel
                        if(packet_data != 0 && data_length>=2 &&
500 1807 azirbel
                           packet_data[0]==CIRCLE_EXECUTE)
501 1807 azirbel
                        {
502 1807 azirbel
                                command = packet_data[1];
503 1807 azirbel
                        }
504 1749 azirbel
505 1807 azirbel
                        if(command != -1)
506 1807 azirbel
                        {
507 1807 azirbel
                                edge_State = 0;
508 1807 azirbel
                                switch(command)
509 1774 azirbel
                                {
510 1807 azirbel
                                case 0:
511 1807 azirbel
                                        state = 10; break;
512 1774 azirbel
513 1807 azirbel
                                case 1:
514 1807 azirbel
                                        state = 11; break;
515 1774 azirbel
516 1807 azirbel
                                case 2:
517 1807 azirbel
                                        state = 12; break;
518 1774 azirbel
519 1807 azirbel
                                case 3:
520 1807 azirbel
                                        state = 13; break;
521 1774 azirbel
522 1807 azirbel
                                case 4:
523 1807 azirbel
                                        state = 14; break;
524 1774 azirbel
525 1807 azirbel
                                case 5:
526 1807 azirbel
                                        state = 15; break;
527 1807 azirbel
528 1807 azirbel
                                case 100:
529 1807 azirbel
                                        terminate(); break;
530 1774 azirbel
                                }
531 1807 azirbel
                        }
532 1774 azirbel
533 1807 azirbel
                break;
534 1749 azirbel
535 1749 azirbel
536 1749 azirbel
537 1807 azirbel
//******************************************************************************
538 1807 azirbel
//******************************************************************************
539 1749 azirbel
540 1749 azirbel
541 1807 azirbel
                /*
542 1807 azirbel
                The CONTROL for the BEACON state.  This sets a certain procedure
543 1807 azirbel
                to follow, in the form of simple commands, for a robot to follow
544 1807 azirbel
                if it is set to a BEACON.
545 1807 azirbel
                */
546 1807 azirbel
                case 2:
547 1807 azirbel
                        orb_set_color(PURPLE);
548 1807 azirbel
                        beacon_State = 0;
549 1749 azirbel
550 1807 azirbel
                        switch(currentPos)
551 1807 azirbel
                        {
552 1807 azirbel
                        case 0:
553 1807 azirbel
                                order(COUNT);        break;
554 1774 azirbel
555 1807 azirbel
                        case 1:
556 1807 azirbel
                                order(CIRCLEUP); break;
557 1774 azirbel
558 1807 azirbel
                        case 2:
559 1807 azirbel
                                order(ORIENT); break;
560 1774 azirbel
561 1807 azirbel
                        case 3:
562 1808 azirbel
                                orderMove(DRIVE,20,2); break;
563 1774 azirbel
564 1807 azirbel
                        case 4:
565 1808 azirbel
                                order(CIRCLEUP); break;
566 1808 azirbel
567 1808 azirbel
                        case 5:
568 1808 azirbel
                                order(ORIENT); break;
569 1808 azirbel
570 1808 azirbel
                        case 6:
571 1808 azirbel
                                orderMove(TURNR,18,1); break;
572 1808 azirbel
573 1808 azirbel
                        case 7:
574 1808 azirbel
                                orderMove(DRIVE,20,2); break;
575 1808 azirbel
576 1808 azirbel
                        case 8:
577 1808 azirbel
                                order(CIRCLEUP); break;
578 1808 azirbel
579 1808 azirbel
                        case 9:
580 1808 azirbel
                                order(ORIENT); break;
581 1808 azirbel
582 1808 azirbel
                        case 10:
583 1807 azirbel
                                terminate(); break;
584 1808 azirbel
585 1807 azirbel
                        }
586 1774 azirbel
587 1807 azirbel
                break;
588 1749 azirbel
589 1749 azirbel
590 1807 azirbel
//******************************************************************************
591 1807 azirbel
//******************************************************************************
592 1749 azirbel
593 1749 azirbel
594 1807 azirbel
        /* The following states are MACHINE states for the EDGE robot. */
595 1749 azirbel
596 1807 azirbel
                /*
597 1807 azirbel
                        EDGE on COUNT
598 1807 azirbel
                */
599 1807 azirbel
                case 10:
600 1774 azirbel
601 1807 azirbel
                        switch(edge_State)
602 1807 azirbel
                        {
603 1807 azirbel
                                /*
604 1807 azirbel
                                0. EDGE robots are on.
605 1807 azirbel
                                1. They are waiting for EXIST pacakage from the
606 1807 azirbel
                                        Center robots
607 1807 azirbel
                                2. After they receive the package, they send ACK
608 1807 azirbel
                                        package to center.
609 1807 azirbel
                                3. Done for now: display green.
610 1807 azirbel
                                */
611 1807 azirbel
                        case 0:
612 1807 azirbel
                                bom_off();
613 1807 azirbel
                                orb1_set_color(YELLOW);
614 1807 azirbel
                                orb2_set_color(BLUE);
615 1807 azirbel
                                packet_data=wl_basic_do_default(&data_length);
616 1749 azirbel
617 1807 azirbel
                                if(packet_data != 0 && data_length>=2 &&
618 1807 azirbel
                                   packet_data[0]==CIRCLE_ACTION_EXIST)
619 1594 azirbel
                                {
620 1807 azirbel
                                        centerid = packet_data[1];
621 1723 azirbel
622 1807 azirbel
                                        send2(CIRCLE_ACTION_ACK,robotid);
623 1723 azirbel
624 1807 azirbel
                                        edge_State=1;
625 1807 azirbel
                                }
626 1807 azirbel
                        break;
627 1807 azirbel
628 1807 azirbel
                        /*
629 1807 azirbel
                                1. Wait for DONE package
630 1807 azirbel
                                2. The counting process is DONE
631 1807 azirbel
                        */
632 1807 azirbel
                        case 1:
633 1635 sdevince
634 1807 azirbel
                                orb_set_color(YELLOW);
635 1807 azirbel
                                orb2_set_color(PURPLE);
636 1723 azirbel
637 1807 azirbel
                                // keep sending the packet until we get a
638 1807 azirbel
                                // response
639 1807 azirbel
                                send2(CIRCLE_ACTION_ACK,robotid);
640 1723 azirbel
641 1807 azirbel
                                packet_data=wl_basic_do_default(&data_length);
642 1807 azirbel
                                if(packet_data != 0 && data_length>=2 &&
643 1807 azirbel
                                   packet_data[0]==CIRCLE_ACTION_GOTYOU &&
644 1807 azirbel
                                   packet_data[1] == robotid)
645 1807 azirbel
                                {
646 1807 azirbel
                                        edge_State=2;
647 1807 azirbel
                                }
648 1807 azirbel
                        break;
649 1721 azirbel
650 1807 azirbel
                        // wait for the second, general, done packet.
651 1807 azirbel
                        case 2:
652 1721 azirbel
653 1807 azirbel
                                orb_set_color(YELLOW);
654 1807 azirbel
                                packet_data=wl_basic_do_default(&data_length);
655 1807 azirbel
                                if(packet_data != 0 && data_length>=2 &&
656 1807 azirbel
                                   packet_data[0]==CIRCLE_ACTION_DONE &&
657 1807 azirbel
                                   packet_data[1] == centerid)
658 1807 azirbel
                                {
659 1807 azirbel
                                        state = 1;
660 1774 azirbel
                                }
661 1774 azirbel
                        break;
662 1807 azirbel
                        }
663 1774 azirbel
664 1807 azirbel
                break;
665 1774 azirbel
666 1807 azirbel
                /* The CIRCLEUP command for EDGE */
667 1774 azirbel
668 1807 azirbel
                case 11:
669 1807 azirbel
670 1807 azirbel
                        switch(edge_State)
671 1807 azirbel
                        {
672 1596 azirbel
673 1807 azirbel
                        case 0:
674 1807 azirbel
                                // COLOR afer DONE ---> MAGENTA
675 1807 azirbel
                                orb_set_color(MAGENTA);
676 1807 azirbel
                                // turn to face the beacon
677 1807 azirbel
                                faceFront();
678 1807 azirbel
                                forward(175);
679 1807 azirbel
                                //range_init();
680 1635 sdevince
681 1635 sdevince
682 1807 azirbel
                                distance = get_distance();
683 1807 azirbel
                                time=0;
684 1807 azirbel
                                while ((distance-offset)>=onefoot ||
685 1807 azirbel
                                   distance==0 || (distance+offset)<onefoot)
686 1807 azirbel
                                {
687 1807 azirbel
                                        if(distance==0)
688 1807 azirbel
                                                orb_set_color(WHITE);
689 1807 azirbel
                                        else if(distance-offset>=onefoot)
690 1807 azirbel
                                                forward(175);
691 1807 azirbel
                                        else
692 1807 azirbel
                                                backward(175);
693 1807 azirbel
                                        distance = get_distance();
694 1807 azirbel
                                        delay_ms(14);
695 1807 azirbel
                                        time+=14;
696 1808 azirbel
                                        if(time>30)
697 1807 azirbel
                                        {
698 1807 azirbel
                                                faceFront();
699 1635 sdevince
                                                time=0;
700 1807 azirbel
                                        }
701 1807 azirbel
                                }
702 1635 sdevince
703 1807 azirbel
                                stop();
704 1807 azirbel
                                orb_set_color(GREEN);
705 1639 azirbel
706 1807 azirbel
                                send2(CIRCLE_ACTION_ACK, robotid);
707 1639 azirbel
708 1807 azirbel
                                stop();
709 1807 azirbel
                                state = 1;
710 1807 azirbel
                        break;
711 1807 azirbel
                        }
712 1717 azirbel
713 1774 azirbel
714 1807 azirbel
                break;
715 1774 azirbel
716 1807 azirbel
                /* An ORIENT series of steps for the EDGE robot. */
717 1774 azirbel
718 1807 azirbel
                case 12:
719 1774 azirbel
720 1807 azirbel
                        switch(edge_State)
721 1807 azirbel
                        {
722 1774 azirbel
723 1807 azirbel
                        // waits for a packet to tell it to turn on the bom.
724 1807 azirbel
                        case 0:
725 1807 azirbel
                                packet_data=wl_basic_do_default(&data_length);
726 1807 azirbel
                                if(packet_data != 0 && data_length==2 &&
727 1807 azirbel
                                   packet_data[0]==CIRCLE_ACTION_GOTYOU &&
728 1807 azirbel
                                   packet_data[1] == robotid)
729 1774 azirbel
                                {
730 1807 azirbel
                                        bom_on();
731 1807 azirbel
                                        orb_set_color(ORANGE);
732 1807 azirbel
                                        send2(CIRCLE_ACTION_ACK,centerid);
733 1807 azirbel
                                        edge_State = 1;
734 1807 azirbel
                                }
735 1807 azirbel
                        break;
736 1774 azirbel
737 1807 azirbel
                        // waits for a packet to tell it that it has been
738 1807 azirbel
                        // received.
739 1807 azirbel
                        case 1:
740 1807 azirbel
                                orb2_set_color(YELLOW);
741 1807 azirbel
                                packet_data=wl_basic_do_default(&data_length);
742 1807 azirbel
                                if(packet_data != 0 && data_length==3 &&
743 1807 azirbel
                                   packet_data[0]==CIRCLE_ACTION_GOTYOU &&
744 1807 azirbel
                                   packet_data[1] == robotid)
745 1807 azirbel
                                {
746 1807 azirbel
                                        bom_off();
747 1807 azirbel
                                        direction = packet_data[2];
748 1807 azirbel
                                        orb_set_color(YELLOW);
749 1807 azirbel
                                        edge_State = 2;
750 1807 azirbel
                                }
751 1807 azirbel
                        break;
752 1724 azirbel
753 1807 azirbel
                        /*
754 1807 azirbel
                         Wait for the center bot to send a DONE packet; then
755 1807 azirbel
                         turn to face the right direction.
756 1807 azirbel
                        */
757 1807 azirbel
                        case 2:
758 1807 azirbel
                                orb_set_color(GREEN);
759 1807 azirbel
                                packet_data=wl_basic_do_default(&data_length);
760 1807 azirbel
                                if(packet_data != 0 && data_length>=2 &&
761 1807 azirbel
                                   packet_data[0]==CIRCLE_ACTION_DONE)
762 1807 azirbel
                                {
763 1807 azirbel
                                        orb_set_color(WHITE);
764 1807 azirbel
                                        orb2_set_color(CYAN);
765 1807 azirbel
                                        edge_State = 3;
766 1807 azirbel
                                }
767 1807 azirbel
                        break;
768 1724 azirbel
769 1807 azirbel
                        /* Turn until we reach the right direction */
770 1807 azirbel
                        case 3:
771 1807 azirbel
                                aboutFace(direction);
772 1807 azirbel
                                stop();
773 1807 azirbel
                                orb_set_color(YELLOW);
774 1807 azirbel
                                send2(CIRCLE_ACTION_DONE,robotid);
775 1807 azirbel
                                state = 1;
776 1807 azirbel
                        break;
777 1725 azirbel
778 1807 azirbel
                        }
779 1749 azirbel
780 1807 azirbel
                break;
781 1774 azirbel
782 1774 azirbel
783 1807 azirbel
                /* The DRIVE steps for the EDGE robot */
784 1807 azirbel
                case 13:
785 1808 azirbel
786 1808 azirbel
                        /* Wait for specifications to drive */
787 1808 azirbel
                        packet_data=wl_basic_do_default(&data_length);
788 1808 azirbel
                        if(packet_data != 0 && data_length>=3 &&
789 1808 azirbel
                           packet_data[0]==CIRCLE_ACTION_FORWARD)
790 1807 azirbel
                        {
791 1808 azirbel
                                orb_set_color(BLUE);
792 1774 azirbel
793 1808 azirbel
                                forward(packet_data[1]*10);
794 1808 azirbel
                                delay_ms(packet_data[2]*1000);
795 1808 azirbel
                                stop();
796 1808 azirbel
                                state = 1;
797 1807 azirbel
                        }
798 1749 azirbel
799 1807 azirbel
                break;
800 1639 azirbel
801 1807 azirbel
                /* The TURNL steps for the EDGE robot */
802 1807 azirbel
                case 14:
803 1717 azirbel
804 1807 azirbel
                        /* Wait for specifications for the turn. */
805 1807 azirbel
                        packet_data=wl_basic_do_default(&data_length);
806 1807 azirbel
                        if(packet_data != 0 && data_length>=3 &&
807 1807 azirbel
                           packet_data[0]==CIRCLE_ACTION_TURN)
808 1807 azirbel
                        {
809 1807 azirbel
                                orb_set_color(BLUE);
810 1626 gnagaraj
811 1807 azirbel
                                left(packet_data[1]*10);
812 1807 azirbel
                                delay_ms(packet_data[2]*1000);
813 1807 azirbel
                                stop();
814 1807 azirbel
                                state = 1;
815 1807 azirbel
                        }
816 1807 azirbel
                break;
817 1626 gnagaraj
818 1807 azirbel
                /* The TURNR steps for the EDGE robot */
819 1807 azirbel
                case 15:
820 1626 gnagaraj
821 1807 azirbel
                        /* Wait for specifications for the turn. */
822 1807 azirbel
                        packet_data=wl_basic_do_default(&data_length);
823 1807 azirbel
                        if(packet_data != 0 && data_length>=3 &&
824 1807 azirbel
                           packet_data[0]==CIRCLE_ACTION_TURN)
825 1807 azirbel
                        {
826 1807 azirbel
                                orb_set_color(BLUE);
827 1639 azirbel
828 1807 azirbel
                                right(packet_data[1]*10);
829 1807 azirbel
                                delay_ms(packet_data[2]*1000);
830 1807 azirbel
                                stop();
831 1807 azirbel
                                state = 1;
832 1807 azirbel
                        }
833 1807 azirbel
                break;
834 1807 azirbel
835 1807 azirbel
        // END for EDGE robots
836 1807 azirbel
837 1639 azirbel
838 1639 azirbel
839 1807 azirbel
//******************************************************************************
840 1807 azirbel
//******************************************************************************
841 1639 azirbel
842 1639 azirbel
843 1807 azirbel
                /*
844 1807 azirbel
                   The MACHINE for the BEACON state
845 1807 azirbel
                */
846 1774 azirbel
847 1807 azirbel
                /* the COUNT code for the BEACON */
848 1807 azirbel
                case 20:
849 1807 azirbel
                        switch(beacon_State)
850 1807 azirbel
                        {
851 1717 azirbel
852 1807 azirbel
                        /* 0. center  robots on wait for pressing button 1 */
853 1807 azirbel
                        case 0:
854 1807 azirbel
                                bom_on();
855 1807 azirbel
                                orb_set_color(BLUE);
856 1807 azirbel
                                robotsReceived = 0;
857 1807 azirbel
                                beacon_State=1;
858 1807 azirbel
                        break;
859 1717 azirbel
860 1807 azirbel
                        /* 1. Send EXIST package to EDGE robots */
861 1807 azirbel
                        case 1:
862 1807 azirbel
                                orb_set_color(RED);
863 1807 azirbel
                                send2(CIRCLE_ACTION_EXIST,robotid);
864 1807 azirbel
                                beacon_State=2;
865 1807 azirbel
                        break;
866 1721 azirbel
867 1807 azirbel
                        /* 2. Count the number of the EDGE robots
868 1807 azirbel
                         *******NOTE: at most  1000  times of loop ******  */
869 1807 azirbel
                        case 2:
870 1807 azirbel
                                waitingCounter++;
871 1807 azirbel
                                orb1_set_color(YELLOW);
872 1807 azirbel
                                orb2_set_color(BLUE);
873 1807 azirbel
                                packet_data=wl_basic_do_default(&data_length);
874 1639 azirbel
875 1807 azirbel
                                if(packet_data!=0 && data_length>=2 &&
876 1807 azirbel
                                   packet_data[0]==CIRCLE_ACTION_ACK)
877 1807 azirbel
                                {
878 1807 azirbel
                                        orb_set_color(RED);
879 1807 azirbel
                                        orb2_set_color(BLUE);
880 1807 azirbel
                                        // only add to list seen if you haven't
881 1807 azirbel
                                        // gotten an ACK from this robot
882 1807 azirbel
                                        if(used[packet_data[1]]==0)
883 1807 azirbel
                                        {
884 1807 azirbel
                                                robotsReceived++;
885 1807 azirbel
                                                used[packet_data[1]] = 1;
886 1639 azirbel
887 1807 azirbel
                                                usb_puts("Added: ");
888 1807 azirbel
                                                usb_puti(packet_data[1]);
889 1807 azirbel
                                                usb_puts("\r\n");
890 1807 azirbel
                                        }
891 1721 azirbel
892 1807 azirbel
                                        // NEW: sends a packet to each robot it
893 1807 azirbel
                                        // receives telling them to be done.
894 1807 azirbel
                                        send2(CIRCLE_ACTION_GOTYOU,
895 1807 azirbel
                                                packet_data[1]);
896 1774 azirbel
                                }
897 1807 azirbel
                                if(waitingCounter >= 300)
898 1807 azirbel
                                {
899 1807 azirbel
                                        beacon_State=3;
900 1807 azirbel
                                }
901 1807 azirbel
                        break;
902 1717 azirbel
903 1807 azirbel
                        /* COUNTing is DONE.  Sending DONE package. */
904 1807 azirbel
                        case 3:
905 1807 azirbel
                                blink(robotsReceived);
906 1807 azirbel
                                orb_set_color(GREEN);
907 1807 azirbel
                                send2(CIRCLE_ACTION_DONE, robotid);
908 1807 azirbel
                                state = 2;
909 1774 azirbel
                        break;
910 1807 azirbel
                        }
911 1774 azirbel
912 1807 azirbel
                break;
913 1774 azirbel
914 1807 azirbel
                /* The CIRCLEUP method for BEACON */
915 1807 azirbel
                case 21:
916 1807 azirbel
917 1807 azirbel
                        switch(beacon_State)
918 1807 azirbel
                        {
919 1807 azirbel
920 1807 azirbel
                        /* Wait for all the robots to get to right distance */
921 1807 azirbel
                        case 0:
922 1808 azirbel
                //                left(170);
923 1807 azirbel
                                orb1_set_color(YELLOW);
924 1807 azirbel
                                orb2_set_color(WHITE);
925 1807 azirbel
926 1807 azirbel
                                numOk = 0;
927 1807 azirbel
928 1807 azirbel
                                while(numOk<robotsReceived)
929 1774 azirbel
                                {
930 1807 azirbel
                                        packet_data=
931 1807 azirbel
                                           wl_basic_do_default(&data_length);
932 1807 azirbel
                                        if(packet_data!=0 && data_length>=2 &&
933 1807 azirbel
                                           packet_data[0]==CIRCLE_ACTION_ACK)
934 1807 azirbel
                                        {
935 1807 azirbel
                                                numOk++;
936 1807 azirbel
                                        }
937 1807 azirbel
                                }
938 1626 gnagaraj
939 1807 azirbel
                                state = 2;
940 1774 azirbel
                        break;
941 1807 azirbel
                        }
942 1774 azirbel
943 1807 azirbel
                break;
944 1774 azirbel
945 1774 azirbel
946 1807 azirbel
                /* The ORIENT code for the beacon */
947 1807 azirbel
                case 22:
948 1807 azirbel
949 1807 azirbel
                        switch(beacon_State)
950 1807 azirbel
                        {
951 1807 azirbel
                        /* Turns all the robots in the same direction */
952 1807 azirbel
                        case 0:
953 1807 azirbel
                                stop();
954 1807 azirbel
                                bom_off();
955 1807 azirbel
                                orb_set_color(ORANGE);
956 1807 azirbel
957 1807 azirbel
                                // for each robot, tells them to turn their bom
958 1807 azirbel
                                // on, then tells them which way to face.
959 1807 azirbel
                                for(int i=0; i < 17; i++)
960 1774 azirbel
                                {
961 1807 azirbel
                                    if(used[i] == 1)
962 1807 azirbel
                                    {
963 1807 azirbel
                                        send2(CIRCLE_ACTION_GOTYOU, i);
964 1807 azirbel
                                        // waits for a response so it knows the
965 1807 azirbel
                                        // BOM is on.
966 1807 azirbel
                                        while(1)
967 1807 azirbel
                                        {
968 1807 azirbel
                                            orb_set_color(RED);
969 1807 azirbel
                                            orb2_set_color(WHITE);
970 1807 azirbel
                                            packet_data=wl_basic_do_default(
971 1807 azirbel
                                                &data_length);
972 1807 azirbel
                                            if(packet_data!=0 && data_length>=2
973 1807 azirbel
                                                && packet_data[0]==
974 1807 azirbel
                                                CIRCLE_ACTION_ACK)
975 1807 azirbel
                                            {
976 1724 azirbel
                                                orb_set_color(ORANGE);
977 1807 azirbel
                                                break;
978 1807 azirbel
                                            }
979 1807 azirbel
                                        }
980 1807 azirbel
                                        delay_ms(20);
981 1807 azirbel
                                        bom_refresh(BOM_ALL);
982 1807 azirbel
                                        direction = bom_get_max();
983 1807 azirbel
984 1807 azirbel
                                        direction += 8;
985 1807 azirbel
                                        if(direction > 15) direction -= 16;
986 1724 azirbel
987 1807 azirbel
                                        delay_ms(20);
988 1724 azirbel
989 1807 azirbel
                                        send3(CIRCLE_ACTION_GOTYOU, i,
990 1807 azirbel
                                             direction);
991 1807 azirbel
992 1807 azirbel
                                        delay_ms(20);
993 1807 azirbel
                                    }
994 1774 azirbel
                                }
995 1807 azirbel
                                beacon_State = 1;
996 1807 azirbel
                        break;
997 1807 azirbel
998 1807 azirbel
                        /*
999 1807 azirbel
                        Sends a DONE packet to signify that it has read in all
1000 1807 azirbel
                        the robots' directions and sent packets.
1001 1807 azirbel
                        Edge robots should now turn to face the right direction.
1002 1807 azirbel
                        */
1003 1807 azirbel
                        case 1:
1004 1807 azirbel
                                send2(CIRCLE_ACTION_DONE,robotid);
1005 1807 azirbel
                                bom_on();
1006 1807 azirbel
                                beacon_State = 2;
1007 1807 azirbel
                        break;
1008 1807 azirbel
1009 1807 azirbel
                        case 2:
1010 1807 azirbel
                                numOk = 0;
1011 1749 azirbel
1012 1807 azirbel
                                while(numOk < robotsReceived)
1013 1807 azirbel
                                {
1014 1807 azirbel
                                        orb_set_color(ORANGE);
1015 1807 azirbel
                                        packet_data=wl_basic_do_default(
1016 1807 azirbel
                                           &data_length);
1017 1807 azirbel
1018 1807 azirbel
                                        if(packet_data!=0 && data_length>=2 &&
1019 1807 azirbel
                                           packet_data[0]==CIRCLE_ACTION_DONE)
1020 1807 azirbel
                                        {
1021 1807 azirbel
                                                numOk++;
1022 1807 azirbel
                                        }
1023 1807 azirbel
                                }
1024 1807 azirbel
                                state = 2;
1025 1774 azirbel
                        break;
1026 1807 azirbel
                        }
1027 1774 azirbel
1028 1807 azirbel
                break;
1029 1774 azirbel
1030 1774 azirbel
1031 1807 azirbel
                /* The DRIVE code for the beacon */
1032 1807 azirbel
                case 23:
1033 1774 azirbel
1034 1808 azirbel
                        orb_set_color(YELLOW);
1035 1808 azirbel
                        delay_ms(100);
1036 1749 azirbel
1037 1808 azirbel
                        // format: type of ack, speed divided by 10,
1038 1808 azirbel
                        // time in seconds.
1039 1808 azirbel
                        for(int i = 0 ; i < 13; i++)
1040 1807 azirbel
                                send3(CIRCLE_ACTION_FORWARD,speed,duration);
1041 1808 azirbel
                        orb_set_color(BLUE);
1042 1808 azirbel
                        forward(speed*10);
1043 1808 azirbel
                        delay_ms(duration*1000);
1044 1808 azirbel
                        stop();
1045 1808 azirbel
                        state = 2;
1046 1807 azirbel
                break;
1047 1807 azirbel
1048 1807 azirbel
                /* The TURNL code for the beacon */
1049 1807 azirbel
                case 24:
1050 1807 azirbel
1051 1807 azirbel
                        orb_set_color(YELLOW);
1052 1808 azirbel
                        delay_ms(100);
1053 1807 azirbel
1054 1807 azirbel
                        // format: type of ack, speed divided by 10,
1055 1807 azirbel
                        // time in seconds.
1056 1808 azirbel
                        for(int i = 0 ; i < 13; i++)
1057 1807 azirbel
                                send3(CIRCLE_ACTION_TURN,speed,duration);
1058 1807 azirbel
                        orb_set_color(BLUE);
1059 1807 azirbel
                        left(speed*10);
1060 1807 azirbel
                        delay_ms(duration*1000);
1061 1807 azirbel
                        stop();
1062 1807 azirbel
                        state = 2;
1063 1807 azirbel
1064 1807 azirbel
                break;
1065 1807 azirbel
1066 1807 azirbel
                /* The TURNR code for the beacon */
1067 1807 azirbel
                case 25:
1068 1807 azirbel
1069 1807 azirbel
                        orb_set_color(YELLOW);
1070 1808 azirbel
                        delay_ms(100);
1071 1807 azirbel
1072 1807 azirbel
                        // format: type of ack, speed divided by 10,
1073 1807 azirbel
                        // time in seconds.
1074 1808 azirbel
                        for(int i = 0 ; i < 13; i++)
1075 1807 azirbel
                                send3(CIRCLE_ACTION_TURN,speed,duration);
1076 1807 azirbel
                        orb_set_color(BLUE);
1077 1807 azirbel
                        right(speed*10);
1078 1807 azirbel
                        delay_ms(duration*1000);
1079 1807 azirbel
                        stop();
1080 1807 azirbel
                        state = 2;
1081 1807 azirbel
1082 1807 azirbel
                break;
1083 1807 azirbel
1084 1807 azirbel
1085 1807 azirbel
//******************************************************************************
1086 1807 azirbel
//******************************************************************************
1087 1807 azirbel
1088 1749 azirbel
                }        // ends the main switch
1089 1749 azirbel
        }                // ends the main while loop
1090 1594 azirbel
1091 1807 azirbel
        // error, we should never break from the while loop!
1092 1807 azirbel
        orb_set_color(RED);
1093 1594 azirbel
1094 1807 azirbel
        /*
1095 1807 azirbel
         END HERE, just in case something happened.
1096 1807 azirbel
         This way we can see the red orb.
1097 1807 azirbel
        */
1098 1807 azirbel
        while(1);
1099 1594 azirbel
}