Statistics
| Revision:

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

History | View | Annotate | Download (21.2 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 1806 azirbel
Joel Rey, Reva Street, Alex Zirbel                                                         */
29 1749 azirbel
30 1749 azirbel
31 1594 azirbel
#include <dragonfly_lib.h>
32 1594 azirbel
#include <wl_basic.h>
33 1594 azirbel
#include <encoders.h>
34 1594 azirbel
#include "circle.h"
35 1594 azirbel
36 1749 azirbel
/*** TODO: ***
37 1626 gnagaraj
38 1806 azirbel
   -Transform the code into a method-based state machine that uses the
39 1806 azirbel
procedural state machines, which are hardcoded and hard to edit, as a backup.
40 1691 azirbel
41 1806 azirbel
   -Implement a drive straight method for use in keeping the robots more
42 1806 azirbel
accurate as a group.
43 1806 azirbel
44 1806 azirbel
   -Fix the approach method: good robots usually work well, but bad robots often
45 1806 azirbel
have errors which might be avoidable with the use of error checking.
46 1806 azirbel
47 1806 azirbel
   -Make robots more robust: packages are often lost, which throws the entire
48 1806 azirbel
procedural nature of the program off.
49 1806 azirbel
50 1806 azirbel
   -Consider using the center bot to check distances
51 1806 azirbel
52 1806 azirbel
   -More testing is always good and necessary.                                        */
53 1806 azirbel
54 1749 azirbel
/*** BOT LOG ***
55 1691 azirbel
56 1806 azirbel
   4-1-2010: BOT 7 as BEACON and BOT 1 as EDGE worked extremely well.
57 1806 azirbel
   4-2-2010: BOT 7 and BOT 14 worked extremely well, no matter states.  BOT 1
58 1806 azirbel
               started well, but malfunctioned later.                                                */
59 1691 azirbel
60 1749 azirbel
/*** TERMINOLOGY ***
61 1691 azirbel
62 1749 azirbel
        WAITINGSTATE:
63 1806 azirbel
        The robot waits to be given a signal to do something.  Wireless is on, in
64 1749 azirbel
                case the robot is called on to turn into an EDGE.  The color should be LIME
65 1749 azirbel
                or YELLOW-GREEN.
66 1594 azirbel
67 1749 azirbel
        BEACON_CONTROL:
68 1749 azirbel
                The code that executes commands when a robot is turned to BEACON mode.  This
69 1749 azirbel
                code may run predefined methods for simplicity.  One goal is to make these
70 1749 azirbel
                methods change the robot turn to to BEACON_MACHINE mode for a while, and then
71 1749 azirbel
                return to the CONTROL code where they left off.
72 1594 azirbel
73 1749 azirbel
        EDGE_CONTROL:
74 1749 azirbel
                Like BEACON_CONTROL, executes whatever orders are required of the robot as an
75 1749 azirbel
                EDGE.
76 1594 azirbel
77 1749 azirbel
        BEACON_MACHINE:
78 1749 azirbel
                A hardcoded list of functions which the robot is capable of running through.
79 1749 azirbel
                Consists of a finite state machine, where the robot executes a set of commands
80 1749 azirbel
                in a procedural manner and then returns to wherever it was in the control code.
81 1594 azirbel
82 1749 azirbel
        EDGE_MACHINE:
83 1749 azirbel
                Like the BEACON_MACHINE, but contains the same sort of procedural information
84 1749 azirbel
                for EDGE robots.
85 1749 azirbel
86 1749 azirbel
        END:
87 1749 azirbel
                A terminal state of the machine, where the robot just sits and waits.  The
88 1749 azirbel
                color should be GREEN and WHITE.
89 1749 azirbel
90 1749 azirbel
91 1749 azirbel
        TYPES OF WIRELESS PACKETS:
92 1749 azirbel
                CIRCLE_ACTION_EXIST 'E'
93 1749 azirbel
                CIRCLE_ACTION_POSITION 'P'
94 1749 azirbel
                CIRCLE_ACTION_ACK 'A'
95 1749 azirbel
                        A general acknowledgement package.
96 1749 azirbel
                CIRCLE_ACTION_DONE 'D'
97 1749 azirbel
                        Used by robots to tell when they have finished their action.
98 1749 azirbel
                CIRCLE_ACTION_GOTYOU 'G'
99 1749 azirbel
                        Used by the BEACON to tell a robot when it has been checked off.
100 1749 azirbel
                        At this point, the EDGE has been recognized.  Used for times when
101 1749 azirbel
                        all EDGE robots have to communicate to the center via the spam method.
102 1749 azirbel
                CIRCLE_ACTION_FORWARD 'F'
103 1749 azirbel
                        The BEACON tells the rest of the robots to move forward.
104 1749 azirbel
                CIRCLE_CLAIM_CENTER 'C'
105 1749 azirbel
                        Sent out by a robot when it takes over as BEACON.                */
106 1749 azirbel
107 1749 azirbel
108 1749 azirbel
109 1749 azirbel
int END = 100;
110 1749 azirbel
int WAITINGSTATE = 0;                /* Define some variables to keep track of the state machine.*/
111 1749 azirbel
int EDGE_CONTROL = 1;
112 1749 azirbel
int BEACON_CONTROL = 2;
113 1749 azirbel
int EDGE_MACHINE = 3;
114 1749 azirbel
int BEACON_MACHINE = 4;
115 1749 azirbel
116 1774 azirbel
int COUNT = 0;
117 1774 azirbel
int CIRCLEUP = 1;
118 1774 azirbel
int ORIENT = 2;
119 1774 azirbel
int DRIVE = 3;
120 1749 azirbel
121 1774 azirbel
int currentPos = 0;
122 1774 azirbel
int state = 0;
123 1774 azirbel
124 1774 azirbel
125 1720 azirbel
int timeout = 0;
126 1720 azirbel
int sending = 0;
127 1720 azirbel
int stop2 = 0;
128 1720 azirbel
struct vector slave_position;
129 1720 azirbel
int desired_max_bom;
130 1720 azirbel
int bom_max_counter;
131 1618 jmcarrol
132 1618 jmcarrol
133 1720 azirbel
void switch_sending(void)
134 1720 azirbel
{
135 1720 azirbel
        if(sending)
136 1720 azirbel
        {
137 1720 azirbel
                sending = 0;
138 1720 azirbel
                bom_off();
139 1720 azirbel
        }
140 1720 azirbel
        else
141 1720 azirbel
        {
142 1720 azirbel
                sending = 1;
143 1720 azirbel
                bom_on();
144 1720 azirbel
        }
145 1720 azirbel
}
146 1720 azirbel
147 1594 azirbel
void forward(int speed){                        // set the motors to this forward speed.
148 1594 azirbel
        motor_l_set(FORWARD,speed);
149 1594 azirbel
        motor_r_set(FORWARD,speed);
150 1594 azirbel
}
151 1594 azirbel
void left(int speed){                                // turn left at this speed.
152 1806 azirbel
        motor_l_set(BACKWARD,speed);
153 1806 azirbel
        motor_r_set(FORWARD,speed);
154 1806 azirbel
}
155 1806 azirbel
void right(int speed){
156 1594 azirbel
        motor_l_set(FORWARD,speed);
157 1594 azirbel
        motor_r_set(BACKWARD,speed);
158 1594 azirbel
}
159 1749 azirbel
void stop(void){                        // could be set to motors_off(), or just use this as an alternative.
160 1749 azirbel
        motor_l_set(BACKWARD,0);        // stop() is better - motors_off() creates a slight delay to turn them back on.
161 1594 azirbel
        motor_r_set(FORWARD,0);
162 1594 azirbel
}
163 1594 azirbel
void setforward(int spd1, int spd2){
164 1594 azirbel
        motor_l_set(FORWARD,spd1);
165 1594 azirbel
        motor_r_set(FORWARD,spd2);
166 1594 azirbel
}
167 1594 azirbel
void backward(int speed){
168 1594 azirbel
        motor_l_set(BACKWARD, speed);
169 1594 azirbel
        motor_r_set(BACKWARD, speed);
170 1594 azirbel
}
171 1594 azirbel
int get_distance(void){                                // takes an averaged reading of the front rangefinder
172 1594 azirbel
        int temp,distance,kk=5;                        // kk sets this to 5 readings.
173 1594 azirbel
        distance =0;
174 1594 azirbel
        for (int i=0; i<kk; i++){
175 1594 azirbel
                temp = range_read_distance(IR2);
176 1594 azirbel
                if (temp == -1)
177 1594 azirbel
                {
178 1594 azirbel
                        //temp=0;
179 1594 azirbel
                        i--;
180 1594 azirbel
                }
181 1594 azirbel
                else
182 1594 azirbel
                        distance+= temp;
183 1594 azirbel
                delay_ms(3);
184 1594 azirbel
        }
185 1594 azirbel
        if (kk>0)
186 1594 azirbel
                return (int)(distance/kk);
187 1594 azirbel
        else
188 1594 azirbel
                return 0;
189 1594 azirbel
}
190 1618 jmcarrol
191 1724 azirbel
/* Sends a global packet with two arguments */
192 1724 azirbel
void send2(char arg0, char arg1)
193 1720 azirbel
{
194 1722 azirbel
        char send_buffer[2];
195 1724 azirbel
        send_buffer[0]=arg0;
196 1724 azirbel
        send_buffer[1]=arg1;
197 1720 azirbel
        wl_basic_send_global_packet(42,send_buffer,2);
198 1720 azirbel
}
199 1618 jmcarrol
200 1724 azirbel
/* Sends a global packet with three arguments */
201 1724 azirbel
void send3(char arg0, char arg1, char arg2)
202 1724 azirbel
{
203 1725 azirbel
        char send_buffer[3];
204 1724 azirbel
        send_buffer[0]=arg0;
205 1724 azirbel
        send_buffer[1]=arg1;
206 1724 azirbel
        send_buffer[2]=arg2;
207 1749 azirbel
        wl_basic_send_global_packet(42,send_buffer,3);
208 1724 azirbel
}
209 1724 azirbel
210 1639 azirbel
/*
211 1639 azirbel
        Orients the robot so that it is facing the beacon (or the broadcasting BOM).
212 1639 azirbel
213 1626 gnagaraj
*/
214 1805 azirbel
void faceFront(void)
215 1618 jmcarrol
{
216 1799 alevkoy
        int bomNum = -1;
217 1805 azirbel
        orb1_set_color(BLUE);
218 1805 azirbel
        while(bomNum != 4)
219 1618 jmcarrol
        {
220 1627 gnagaraj
                bom_refresh(BOM_ALL);
221 1799 alevkoy
                bomNum = bom_get_max();
222 1805 azirbel
                if(bomNum == -1)
223 1618 jmcarrol
                {
224 1805 azirbel
                        //ignore
225 1799 alevkoy
                }
226 1805 azirbel
                else if((bomNum < 4) || (bomNum >= 12))
227 1799 alevkoy
                {
228 1805 azirbel
                        right(200);
229 1618 jmcarrol
                }
230 1805 azirbel
                else
231 1618 jmcarrol
                {
232 1805 azirbel
                        left(200);
233 1618 jmcarrol
                }
234 1618 jmcarrol
        }
235 1805 azirbel
        stop();
236 1627 gnagaraj
        return;
237 1618 jmcarrol
}
238 1618 jmcarrol
239 1805 azirbel
void aboutFace(int goal)
240 1805 azirbel
{
241 1805 azirbel
        int bomNum = -1;
242 1805 azirbel
        int speed = 170;        // speed with which to turn
243 1626 gnagaraj
244 1805 azirbel
        orb1_set_color(BLUE);                        // BLUE and PURPLE
245 1805 azirbel
246 1805 azirbel
        while(bomNum != goal)
247 1805 azirbel
        {
248 1805 azirbel
                // bomNum is the current maximum reading
249 1805 azirbel
                bom_refresh(BOM_ALL);
250 1805 azirbel
                bomNum = bom_get_max();
251 1805 azirbel
                right(speed);
252 1805 azirbel
        }
253 1805 azirbel
        stop();
254 1805 azirbel
        return;
255 1805 azirbel
}
256 1805 azirbel
257 1805 azirbel
258 1639 azirbel
/*
259 1626 gnagaraj
    BLINK the given number times
260 1626 gnagaraj
*/
261 1717 azirbel
void blink(int num)
262 1717 azirbel
{
263 1594 azirbel
        for(int i = 0; i<num; i++)
264 1594 azirbel
        {
265 1594 azirbel
                orb_set_color(ORB_OFF);
266 1724 azirbel
                delay_ms(150);
267 1594 azirbel
                orb_set_color(RED);
268 1724 azirbel
                delay_ms(50);
269 1594 azirbel
        }
270 1594 azirbel
        orb_set_color(ORB_OFF);
271 1594 azirbel
}
272 1594 azirbel
273 1725 azirbel
/*
274 1725 azirbel
    BLINK slowly the given number times
275 1725 azirbel
*/
276 1725 azirbel
void slowblink(int num)
277 1725 azirbel
{
278 1725 azirbel
        for(int i = 0; i<num; i++)
279 1725 azirbel
        {
280 1725 azirbel
                orb_set_color(ORB_OFF);
281 1725 azirbel
                delay_ms(300);
282 1725 azirbel
                orb_set_color(RED);
283 1725 azirbel
                delay_ms(200);
284 1725 azirbel
        }
285 1725 azirbel
        orb_set_color(ORB_OFF);
286 1725 azirbel
}
287 1594 azirbel
288 1774 azirbel
void order(int action)
289 1774 azirbel
{
290 1774 azirbel
        currentPos++;
291 1774 azirbel
        send2(CIRCLE_EXECUTE, action);
292 1774 azirbel
        state = 20 + action;
293 1774 azirbel
}
294 1594 azirbel
295 1774 azirbel
void terminate(void)
296 1774 azirbel
{
297 1774 azirbel
        send2(CIRCLE_EXECUTE, 100);
298 1774 azirbel
        orb_set_color(GREEN);
299 1774 azirbel
        orb2_set_color(WHITE);
300 1774 azirbel
        while(1) ;
301 1774 azirbel
}
302 1626 gnagaraj
303 1626 gnagaraj
304 1639 azirbel
305 1774 azirbel
306 1639 azirbel
//*****************************************************************************************************************************************************************************************
307 1749 azirbel
//*****************************************************************************************************************************************************************************************
308 1749 azirbel
//*****************************************************************************************************************************************************************************************
309 1639 azirbel
310 1639 azirbel
311 1639 azirbel
/*
312 1749 azirbel
        A state machine with five states.  The robot starts out in WAITINGSTATE mode, from which
313 1749 azirbel
        it recieves a signal of some sort and moves to a different state.
314 1639 azirbel
*/
315 1594 azirbel
int main(void)
316 1594 azirbel
{
317 1594 azirbel
        /* Initialize dragonfly board */
318 1618 jmcarrol
            dragonfly_init(ALL_ON);
319 1618 jmcarrol
            /* Initialize the basic wireless library */
320 1618 jmcarrol
            wl_basic_init_default();
321 1749 azirbel
            /* Set the XBee channel to 24 - must be standard among robots */
322 1594 azirbel
        wl_set_channel(24);
323 1594 azirbel
324 1594 azirbel
        int robotid = get_robotid();
325 1749 azirbel
        int centerid = 0;                // once the EDGE gets the first signal from a center, it stores who the center is.
326 1749 azirbel
        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.
327 1749 azirbel
        for (int i=0; i<17; i++) used[i] = 0;                // initially, no robots in the group.
328 1749 azirbel
329 1749 azirbel
        int data_length;                // keeps track of the length of wireless packets received.
330 1594 azirbel
        unsigned char *packet_data=wl_basic_do_default(&data_length);
331 1594 azirbel
332 1749 azirbel
        int beacon_State=0;                // these variables keep track of the inner state machines in the procedural MACHINE states.
333 1635 sdevince
        int edge_State=0;
334 1749 azirbel
335 1610 azirbel
        int waitingCounter=0;
336 1749 azirbel
        int robotsReceived=0;                // an important variable that stores the size of the group.
337 1749 azirbel
        int offset = 20;                // offset for the approaching: how far off the rangefinders can be
338 1724 azirbel
        int time=0;
339 1749 azirbel
        int direction = 4;                // keeps track of which way robots are facing relative to the center
340 1749 azirbel
        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
341 1749 azirbel
                                                // right distance away.
342 1749 azirbel
        int onefoot = 250;                // how far away to stop.
343 1627 gnagaraj
344 1596 azirbel
        while(1)
345 1596 azirbel
        {
346 1626 gnagaraj
                bom_refresh(BOM_ALL);
347 1749 azirbel
348 1749 azirbel
                                /*
349 1749 azirbel
                                *******EXPECTED MOVES **********   (OUT OF DATE.  Will be updated once changes have been made.)
350 1749 azirbel
                                The designed movement:
351 1749 azirbel
                                 1. one center robot, several edge robots are on;
352 1749 azirbel
                                 2. center robots: button 1 is pressed;
353 1749 azirbel
                                 3. center robots: send global package telling edges that he exists;
354 1749 azirbel
                                 4. EDGE robots response with ACK.
355 1749 azirbel
                                 5. EDGE robots wait for center robots to finish counting (DONE package)
356 1749 azirbel
                                 6. EDGE robtos approach the center robtot and stop at the "onefoot" distance, send message to the center
357 1749 azirbel
                                */
358 1626 gnagaraj
359 1626 gnagaraj
360 1749 azirbel
                /* This is the MAIN SWITCH LOOP, which governs the overall status of the robot. */
361 1596 azirbel
                switch(state)
362 1596 azirbel
                {
363 1749 azirbel
364 1749 azirbel
365 1749 azirbel
                        /*
366 1749 azirbel
                                The WAITINGSTATE.  This state constantly checks for wireless packets,
367 1749 azirbel
                                and updates its state as soon as it receives a signal.
368 1626 gnagaraj
                        */
369 1749 azirbel
                        case 0:
370 1717 azirbel
371 1774 azirbel
                                orb_set_color(YELLOW);
372 1749 azirbel
                                packet_data=wl_basic_do_default(&data_length);
373 1749 azirbel
                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_CLAIM_CENTER)
374 1749 azirbel
                                {
375 1749 azirbel
                                        centerid = packet_data[1];
376 1749 azirbel
377 1775 azirbel
                                        state = 1;
378 1749 azirbel
                                }
379 1749 azirbel
380 1749 azirbel
                                if(button1_read())
381 1749 azirbel
                                {
382 1749 azirbel
                                        send2(CIRCLE_CLAIM_CENTER, robotid);         // becomes the center if button1 is clicked.
383 1775 azirbel
                                        state = 2;
384 1749 azirbel
                                }
385 1749 azirbel
386 1749 azirbel
                        break;
387 1749 azirbel
388 1749 azirbel
389 1749 azirbel
390 1749 azirbel
//***********************************************************************************************************************************************************************************
391 1749 azirbel
392 1749 azirbel
393 1749 azirbel
394 1749 azirbel
                        /*
395 1749 azirbel
                                The CONTROL for the EDGE state.  This sets a certain procedure to follow, in the form of simple
396 1749 azirbel
                                commands, for a robot to follow if it is set to an EDGE.
397 1749 azirbel
                        */
398 1749 azirbel
399 1749 azirbel
                        case 1:
400 1774 azirbel
                                orb_set_color(CYAN);
401 1774 azirbel
                                orb1_set_color(YELLOW);
402 1749 azirbel
403 1774 azirbel
                                int command = -1;
404 1774 azirbel
405 1774 azirbel
                                packet_data=wl_basic_do_default(&data_length);
406 1774 azirbel
                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_EXECUTE)
407 1774 azirbel
                                {
408 1774 azirbel
                                        command = packet_data[1];
409 1774 azirbel
                                }
410 1774 azirbel
411 1774 azirbel
                                if(command != -1)
412 1774 azirbel
                                {
413 1775 azirbel
                                        edge_State = 0;
414 1774 azirbel
                                        switch(command)
415 1774 azirbel
                                        {
416 1774 azirbel
                                                case 0:
417 1774 azirbel
                                                        state = 10; break;
418 1774 azirbel
419 1774 azirbel
                                                case 1:
420 1774 azirbel
                                                        state = 11; break;
421 1774 azirbel
422 1774 azirbel
                                                case 2:
423 1774 azirbel
                                                        state = 12; break;
424 1774 azirbel
425 1774 azirbel
                                                case 3:
426 1774 azirbel
                                                        state = 13; break;
427 1774 azirbel
428 1774 azirbel
                                                case 100:
429 1774 azirbel
                                                        terminate(); break;
430 1774 azirbel
                                        }
431 1774 azirbel
                                }
432 1774 azirbel
433 1749 azirbel
                        break;
434 1749 azirbel
435 1749 azirbel
436 1749 azirbel
437 1749 azirbel
//***********************************************************************************************************************************************************************************
438 1749 azirbel
439 1749 azirbel
440 1749 azirbel
441 1749 azirbel
                        /*
442 1749 azirbel
                                The CONTROL for the BEACON state.  This sets a certain procedure to follow, in the form of simple
443 1749 azirbel
                                commands, for a robot to follow if it is set to a BEACON.
444 1749 azirbel
                        */
445 1749 azirbel
                        case 2:
446 1774 azirbel
                                orb_set_color(PURPLE);
447 1775 azirbel
                                beacon_State = 0;
448 1774 azirbel
449 1774 azirbel
                                switch(currentPos)
450 1774 azirbel
                                {
451 1774 azirbel
                                        case 0:
452 1774 azirbel
                                                order(COUNT);        break;
453 1774 azirbel
454 1774 azirbel
                                        case 1:
455 1774 azirbel
                                                order(CIRCLEUP); break;
456 1774 azirbel
457 1774 azirbel
                                        case 2:
458 1774 azirbel
                                                order(ORIENT); break;
459 1774 azirbel
460 1774 azirbel
                                        case 3:
461 1774 azirbel
                                                order(DRIVE); break;
462 1774 azirbel
463 1774 azirbel
                                        case 4:
464 1774 azirbel
                                                terminate(); break;
465 1774 azirbel
                                }
466 1774 azirbel
467 1749 azirbel
                        break;
468 1749 azirbel
469 1749 azirbel
470 1749 azirbel
471 1749 azirbel
//***********************************************************************************************************************************************************************************
472 1749 azirbel
473 1749 azirbel
474 1774 azirbel
                        /* The following states are MACHINE states for the EDGE robot. */
475 1774 azirbel
476 1749 azirbel
                        /*
477 1774 azirbel
                                EDGE on COUNT
478 1749 azirbel
                        */
479 1774 azirbel
                        case 10:
480 1749 azirbel
481 1774 azirbel
482 1635 sdevince
                                switch(edge_State)
483 1594 azirbel
                                {
484 1635 sdevince
                                        /*
485 1635 sdevince
                                                0. EDGE robots are on.
486 1720 azirbel
                                                1. They are waiting for EXIST pacakage from the Center robots
487 1635 sdevince
                                                2. After they receive the package, they send ACK package to center.
488 1717 azirbel
                                                3. Done for now: display green.
489 1635 sdevince
                                        */
490 1774 azirbel
                                        case 0:
491 1635 sdevince
                                                bom_off();
492 1721 azirbel
                                                orb1_set_color(YELLOW);
493 1775 azirbel
                                                orb2_set_color(BLUE);
494 1635 sdevince
                                                packet_data=wl_basic_do_default(&data_length);
495 1635 sdevince
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_EXIST)
496 1635 sdevince
                                                {
497 1721 azirbel
                                                        centerid = packet_data[1];
498 1723 azirbel
499 1724 azirbel
                                                        send2(CIRCLE_ACTION_ACK,robotid);
500 1723 azirbel
501 1635 sdevince
                                                        edge_State=1;
502 1635 sdevince
                                                }
503 1635 sdevince
                                        break;
504 1635 sdevince
                                        /*
505 1635 sdevince
                                                1. Wait for DONE package
506 1635 sdevince
                                                2. The counting process is DONE
507 1635 sdevince
                                        */
508 1635 sdevince
                                        case 1:
509 1635 sdevince
510 1721 azirbel
                                                orb_set_color(YELLOW);
511 1721 azirbel
                                                orb2_set_color(PURPLE);
512 1723 azirbel
513 1724 azirbel
                                                send2(CIRCLE_ACTION_ACK,robotid);                // keep sending the packet until we get a response
514 1723 azirbel
515 1635 sdevince
                                                packet_data=wl_basic_do_default(&data_length);
516 1723 azirbel
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_GOTYOU && packet_data[1] == robotid)
517 1635 sdevince
                                                {
518 1635 sdevince
                                                        edge_State=2;
519 1635 sdevince
                                                }
520 1635 sdevince
                                        break;
521 1721 azirbel
522 1721 azirbel
                                        case 2:        // wait for the second, general, done packet.
523 1721 azirbel
524 1721 azirbel
                                                orb_set_color(YELLOW);
525 1721 azirbel
                                                packet_data=wl_basic_do_default(&data_length);
526 1722 azirbel
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE && packet_data[1] == centerid)
527 1721 azirbel
                                                {
528 1774 azirbel
                                                        state = 1;
529 1721 azirbel
                                                }
530 1723 azirbel
                                        break;
531 1774 azirbel
                                }
532 1774 azirbel
533 1774 azirbel
                        break;
534 1774 azirbel
535 1774 azirbel
                        /* The CIRCLEUP command for EDGE */
536 1774 azirbel
537 1774 azirbel
                        case 11:
538 1774 azirbel
539 1774 azirbel
                                switch(edge_State)
540 1774 azirbel
                                {
541 1596 azirbel
542 1774 azirbel
                                        case 0:
543 1635 sdevince
                                                // COLOR afer DONE ---> MAGENTA
544 1635 sdevince
                                                orb_set_color(MAGENTA);
545 1805 azirbel
                                                faceFront();                        // turn to face the beacon
546 1635 sdevince
                                                forward(175);
547 1635 sdevince
                                                //range_init();
548 1635 sdevince
549 1635 sdevince
550 1635 sdevince
                                                distance = get_distance();
551 1635 sdevince
                                                time=0;
552 1635 sdevince
                                                while ((distance-offset)>=onefoot || distance==0 || (distance+offset)<onefoot)
553 1635 sdevince
                                                {
554 1635 sdevince
                                                        if(distance==0)
555 1635 sdevince
                                                                orb_set_color(WHITE);
556 1635 sdevince
                                                        else if(distance-offset>=onefoot)
557 1635 sdevince
                                                                forward(175);
558 1635 sdevince
                                                        else
559 1635 sdevince
                                                                backward(175);
560 1635 sdevince
                                                        distance = get_distance();
561 1635 sdevince
                                                        delay_ms(14);
562 1635 sdevince
                                                        time+=14;
563 1749 azirbel
                                                        if(time>50)
564 1717 azirbel
                                                        {
565 1805 azirbel
                                                                faceFront;
566 1635 sdevince
                                                                time=0;
567 1635 sdevince
                                                        }
568 1635 sdevince
                                                }
569 1635 sdevince
570 1635 sdevince
                                                stop();
571 1724 azirbel
                                                orb_set_color(GREEN);
572 1639 azirbel
573 1724 azirbel
                                                send2(CIRCLE_ACTION_ACK, robotid);
574 1639 azirbel
575 1724 azirbel
                                                stop();
576 1774 azirbel
                                                state = 1;
577 1635 sdevince
                                        break;
578 1717 azirbel
579 1774 azirbel
                                }
580 1774 azirbel
581 1774 azirbel
582 1774 azirbel
                        break;
583 1774 azirbel
584 1774 azirbel
                        /* An ORIENT series of steps for the EDGE robot. */
585 1774 azirbel
586 1774 azirbel
                        case 12:
587 1774 azirbel
588 1774 azirbel
589 1774 azirbel
                                switch(edge_State)
590 1774 azirbel
                                {
591 1774 azirbel
592 1724 azirbel
                                        // waits for a packet to tell it to turn on the bom.
593 1774 azirbel
                                        case 0:
594 1724 azirbel
                                                packet_data=wl_basic_do_default(&data_length);
595 1724 azirbel
                                                if(packet_data != 0 && data_length==2 && packet_data[0]==CIRCLE_ACTION_GOTYOU && packet_data[1] == robotid)
596 1724 azirbel
                                                {
597 1724 azirbel
                                                        bom_on();
598 1724 azirbel
                                                        orb_set_color(ORANGE);
599 1724 azirbel
                                                        send2(CIRCLE_ACTION_ACK,centerid);
600 1774 azirbel
                                                        edge_State = 1;
601 1724 azirbel
                                                }
602 1724 azirbel
                                        break;
603 1724 azirbel
604 1724 azirbel
                                        // waits for a packet to tell it that it has been received.
605 1774 azirbel
                                        case 1:
606 1724 azirbel
                                                orb2_set_color(YELLOW);
607 1724 azirbel
                                                packet_data=wl_basic_do_default(&data_length);
608 1749 azirbel
                                                if(packet_data != 0 && data_length==3 && packet_data[0]==CIRCLE_ACTION_GOTYOU && packet_data[1] == robotid)
609 1724 azirbel
                                                {
610 1724 azirbel
                                                        bom_off();
611 1724 azirbel
                                                        direction = packet_data[2];
612 1724 azirbel
                                                        orb_set_color(YELLOW);
613 1774 azirbel
                                                        edge_State = 2;
614 1724 azirbel
                                                }
615 1724 azirbel
                                        break;
616 1724 azirbel
617 1749 azirbel
                                        /* Wait for the center bot to send a DONE packet; then turn to face the right direction. */
618 1774 azirbel
                                        case 2:
619 1749 azirbel
                                                orb_set_color(GREEN);
620 1749 azirbel
                                                packet_data=wl_basic_do_default(&data_length);
621 1749 azirbel
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE)
622 1749 azirbel
                                                {
623 1749 azirbel
                                                        orb_set_color(WHITE);
624 1749 azirbel
                                                        orb2_set_color(CYAN);
625 1774 azirbel
                                                        edge_State = 3;
626 1749 azirbel
                                                }
627 1725 azirbel
                                        break;
628 1725 azirbel
629 1749 azirbel
                                        /* Turn until we reach the right direction (DIRECTION) */
630 1774 azirbel
                                        case 3:
631 1776 azirbel
                                                aboutFace(direction);
632 1749 azirbel
                                        break;
633 1749 azirbel
634 1774 azirbel
                                }
635 1774 azirbel
636 1774 azirbel
637 1774 azirbel
                        break;
638 1774 azirbel
639 1774 azirbel
640 1774 azirbel
                        /* The MOVE steps for the EDGE robot */
641 1774 azirbel
642 1774 azirbel
                        case 13:
643 1774 azirbel
644 1774 azirbel
                                switch(edge_State)
645 1774 azirbel
                                {
646 1774 azirbel
647 1749 azirbel
                                        /* Wait for the command to move forward. */
648 1774 azirbel
                                        case 0:
649 1749 azirbel
                                                packet_data=wl_basic_do_default(&data_length);
650 1749 azirbel
                                                if(packet_data != 0 && data_length>=3 && packet_data[0]==CIRCLE_ACTION_FORWARD)
651 1749 azirbel
                                                {
652 1749 azirbel
                                                        orb_set_color(BLUE);
653 1775 azirbel
                                                        forward(packet_data[1]*10);
654 1775 azirbel
                                                        delay_ms(packet_data[2]*1000);
655 1774 azirbel
                                                        edge_State = 1;
656 1749 azirbel
                                                }
657 1749 azirbel
                                        break;
658 1749 azirbel
659 1749 azirbel
                                        /* Terminal. */
660 1774 azirbel
                                        case 1:
661 1749 azirbel
                                                stop();
662 1774 azirbel
                                                state = 1;
663 1717 azirbel
                                        break;
664 1639 azirbel
665 1717 azirbel
666 1717 azirbel
                                }        // end the EdgeState switch
667 1717 azirbel
668 1717 azirbel
                        break;                // break the Edge state in the main switch loop
669 1626 gnagaraj
670 1717 azirbel
                        // END for EDGE robots
671 1626 gnagaraj
672 1626 gnagaraj
673 1626 gnagaraj
674 1626 gnagaraj
675 1626 gnagaraj
676 1639 azirbel
677 1749 azirbel
//***********************************************************************************************************************************************************************************
678 1639 azirbel
679 1639 azirbel
680 1639 azirbel
681 1639 azirbel
682 1639 azirbel
                        /*
683 1749 azirbel
                           The MACHINE for the BEACON state
684 1774 azirbel
                        */
685 1774 azirbel
686 1774 azirbel
                        /* the COUNT code for the BEACON */
687 1774 azirbel
                        case 20:
688 1717 azirbel
                                switch(beacon_State)
689 1717 azirbel
                                {
690 1717 azirbel
691 1717 azirbel
                                        /* 0. center  robots on wait for pressing button 1 */
692 1720 azirbel
                                        case 0:
693 1717 azirbel
                                                bom_on();
694 1775 azirbel
                                                orb_set_color(BLUE);
695 1774 azirbel
                                                robotsReceived = 0;
696 1775 azirbel
                                                beacon_State=1;
697 1626 gnagaraj
                                        break;
698 1717 azirbel
699 1717 azirbel
                                        /* 1. Send EXIST package to EDGE robots */
700 1717 azirbel
                                        case 1:
701 1717 azirbel
                                                orb_set_color(RED);
702 1724 azirbel
                                                send2(CIRCLE_ACTION_EXIST,robotid);
703 1717 azirbel
                                                beacon_State=2;
704 1626 gnagaraj
                                        break;
705 1721 azirbel
706 1717 azirbel
                                        /* 2. Count the number of the EDGE robots *******NOTE: at most  1000  times of loop ******  */
707 1720 azirbel
                                        case 2:
708 1717 azirbel
                                                waitingCounter++;
709 1717 azirbel
                                                orb1_set_color(YELLOW);
710 1717 azirbel
                                                orb2_set_color(BLUE);
711 1717 azirbel
                                                packet_data=wl_basic_do_default(&data_length);
712 1639 azirbel
713 1717 azirbel
                                                if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
714 1717 azirbel
                                                {
715 1717 azirbel
                                                        orb_set_color(RED);
716 1717 azirbel
                                                        orb2_set_color(BLUE);
717 1717 azirbel
                                                        //only add to robots seen if you haven't gotten an ACK from this robot
718 1723 azirbel
                                                        if(used[packet_data[1]]==0)
719 1723 azirbel
                                                        {
720 1717 azirbel
                                                                robotsReceived++;
721 1724 azirbel
                                                                used[packet_data[1]] = 1;
722 1639 azirbel
723 1717 azirbel
                                                                usb_puts("Added: ");
724 1717 azirbel
                                                                usb_puti(packet_data[1]);
725 1717 azirbel
                                                                usb_puts("\r\n");
726 1717 azirbel
                                                        }
727 1721 azirbel
728 1723 azirbel
                                                        // NEW: sends a packet to each robot it receives telling them to be done.
729 1724 azirbel
                                                        send2(CIRCLE_ACTION_GOTYOU,packet_data[1]);
730 1626 gnagaraj
                                                }
731 1724 azirbel
                                                if(waitingCounter >= 300){
732 1717 azirbel
                                                        beacon_State=3;
733 1717 azirbel
                                                }
734 1626 gnagaraj
                                        break;
735 1717 azirbel
736 1717 azirbel
                                        /* COUNTing is DONE.  Sending DONE package. */
737 1717 azirbel
                                        case 3:
738 1717 azirbel
                                                blink(robotsReceived);
739 1717 azirbel
                                                orb_set_color(GREEN);
740 1724 azirbel
                                                send2(CIRCLE_ACTION_DONE, robotid);
741 1774 azirbel
                                                state = 2;
742 1626 gnagaraj
                                        break;
743 1774 azirbel
                                }
744 1717 azirbel
745 1774 azirbel
                        break;
746 1774 azirbel
747 1774 azirbel
                        /* The CIRCLEUP method for BEACON */
748 1774 azirbel
                        case 21:
749 1774 azirbel
750 1774 azirbel
                                switch(beacon_State)
751 1774 azirbel
                                {
752 1774 azirbel
753 1717 azirbel
                                        /* Wait for all the robots to get to right distance/position */
754 1774 azirbel
                                        case 0:
755 1720 azirbel
                                                left(170);
756 1717 azirbel
                                                orb1_set_color(YELLOW);
757 1717 azirbel
                                                orb2_set_color(WHITE);
758 1626 gnagaraj
759 1717 azirbel
                                                int numOk = 0;
760 1626 gnagaraj
761 1717 azirbel
                                                while(numOk<robotsReceived)
762 1626 gnagaraj
                                                {
763 1717 azirbel
                                                        packet_data=wl_basic_do_default(&data_length);
764 1717 azirbel
                                                        if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
765 1717 azirbel
                                                        {
766 1717 azirbel
                                                                numOk++;
767 1717 azirbel
                                                        }
768 1626 gnagaraj
                                                }
769 1626 gnagaraj
770 1774 azirbel
                                                state = 2;
771 1774 azirbel
                                        break;
772 1774 azirbel
                                }
773 1774 azirbel
774 1774 azirbel
                        break;
775 1774 azirbel
776 1774 azirbel
777 1774 azirbel
                        /* The ORIENT code for the beacon */
778 1774 azirbel
                        case 22:
779 1774 azirbel
780 1774 azirbel
                                switch(beacon_State)
781 1774 azirbel
                                {
782 1724 azirbel
                                        /* Turns all the robots in the same direction */
783 1774 azirbel
                                        case 0:
784 1717 azirbel
                                                stop();
785 1724 azirbel
                                                bom_off();
786 1724 azirbel
                                                orb_set_color(ORANGE);
787 1724 azirbel
788 1724 azirbel
                                                // for each robot, tells them to turn their bom on, then tells them which way they should face.
789 1724 azirbel
                                                for(int i=0; i < 17; i++)
790 1724 azirbel
                                                {
791 1724 azirbel
                                                        if(used[i] == 1)
792 1724 azirbel
                                                        {
793 1724 azirbel
                                                                send2(CIRCLE_ACTION_GOTYOU, i);
794 1724 azirbel
                                                                while(1)        // waits for a response so it knows the BOM is on.
795 1724 azirbel
                                                                {
796 1724 azirbel
                                                                        orb_set_color(RED);
797 1724 azirbel
                                                                        orb2_set_color(WHITE);
798 1724 azirbel
                                                                        packet_data=wl_basic_do_default(&data_length);
799 1724 azirbel
                                                                        if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
800 1724 azirbel
                                                                        {
801 1724 azirbel
                                                                                orb_set_color(ORANGE);
802 1724 azirbel
                                                                                break;
803 1724 azirbel
                                                                        }
804 1724 azirbel
                                                                }
805 1724 azirbel
806 1749 azirbel
                                                                bom_refresh(BOM_ALL);
807 1724 azirbel
                                                                direction = bom_get_max();
808 1749 azirbel
                                                                direction += 8;
809 1749 azirbel
                                                                if(direction > 15) direction -= 16;
810 1724 azirbel
                                                                send3(CIRCLE_ACTION_GOTYOU, i, direction);
811 1749 azirbel
                                                                delay_ms(20);
812 1724 azirbel
                                                        }
813 1724 azirbel
                                                }
814 1774 azirbel
                                                beacon_State = 1;
815 1724 azirbel
                                        break;
816 1724 azirbel
817 1749 azirbel
                                        /* Sends a DONE packet to signify that it has read in all the robots' directions and sent packets.
818 1749 azirbel
                                                Edge robots should now turn to face the right direction. */
819 1774 azirbel
                                        case 1:
820 1749 azirbel
                                                send2(CIRCLE_ACTION_DONE,robotid);
821 1749 azirbel
                                                bom_on();
822 1774 azirbel
                                                state = 2;
823 1749 azirbel
                                        break;
824 1774 azirbel
                                }
825 1749 azirbel
826 1774 azirbel
                        break;
827 1774 azirbel
828 1774 azirbel
829 1774 azirbel
                        /* The DRIVE code for the beacon */
830 1774 azirbel
                        case 23:
831 1774 azirbel
832 1774 azirbel
                                switch(beacon_State)
833 1774 azirbel
                                {
834 1774 azirbel
835 1749 azirbel
                                        /* Tells the robots to move forward and moves itself. */
836 1775 azirbel
                                        case 0:
837 1749 azirbel
                                                orb_set_color(YELLOW);
838 1749 azirbel
                                                delay_ms(5000);
839 1749 azirbel
840 1775 azirbel
                                                // format: type of ack, speed divided by 10, time in seconds.
841 1775 azirbel
                                                send3(CIRCLE_ACTION_FORWARD,20,2);
842 1749 azirbel
                                                orb_set_color(BLUE);
843 1749 azirbel
                                                forward(200);
844 1749 azirbel
                                                delay_ms(2000);
845 1749 azirbel
                                                stop();
846 1775 azirbel
                                                beacon_State = 1;
847 1749 azirbel
                                        break;
848 1749 azirbel
849 1724 azirbel
                                        /* Terminal. */
850 1775 azirbel
                                        case 1:
851 1749 azirbel
                                                stop();
852 1774 azirbel
                                                state = 2;
853 1717 azirbel
                                        break;
854 1717 azirbel
                                }
855 1717 azirbel
                        break;
856 1749 azirbel
857 1749 azirbel
//***********************************************************************************************************************************************************************************
858 1717 azirbel
859 1749 azirbel
                }        // ends the main switch
860 1749 azirbel
        }                // ends the main while loop
861 1594 azirbel
862 1749 azirbel
        orb_set_color(RED);        // error, we should never break from the while loop!
863 1594 azirbel
864 1749 azirbel
        while(1); /* END HERE, just in case something happened.  This way we can see the red orb. */
865 1594 azirbel
}
866 1749 azirbel