Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (16 KB)

1 1594 azirbel
#include <dragonfly_lib.h>
2
#include <wl_basic.h>
3
#include <encoders.h>
4
#include "circle.h"
5
6
int EDGE = 0;
7
int BEACON = 1;
8 1618 jmcarrol
int timeout = 0;
9 1626 gnagaraj
int sending = 0;
10
int stop2 = 0;
11
struct vector slave_position;
12
int desired_max_bom;
13
int bom_max_counter;
14 1594 azirbel
15 1635 sdevince
//Last used 12,13,7(BOM)
16 1626 gnagaraj
void set_desired_max_bom(int desired_angle)
17
{
18
        if (desired_angle >= 348 || desired_angle < 11) desired_max_bom = 0;
19
        if (desired_angle >= 11 && desired_angle < 33) desired_max_bom = 1;
20
        if (desired_angle >= 33 && desired_angle < 56) desired_max_bom = 2;
21
        if (desired_angle >= 56 && desired_angle < 78) desired_max_bom = 3;
22
        if (desired_angle >= 78 && desired_angle < 101) desired_max_bom = 4;
23
        if (desired_angle >= 101 && desired_angle < 123) desired_max_bom = 5;
24
        if (desired_angle >= 123 && desired_angle < 145) desired_max_bom = 6;
25
        if (desired_angle >= 145 && desired_angle < 167) desired_max_bom = 7;
26
        if (desired_angle >= 167 && desired_angle < 190) desired_max_bom = 8;
27
        if (desired_angle >= 190 && desired_angle < 212) desired_max_bom = 9;
28
        if (desired_angle >= 212 && desired_angle < 235) desired_max_bom = 10;
29
        if (desired_angle >= 235 && desired_angle < 257) desired_max_bom = 11;
30
        if (desired_angle >= 257 && desired_angle < 280) desired_max_bom = 12;
31
        if (desired_angle >= 280 && desired_angle < 302) desired_max_bom = 13;
32
        if (desired_angle >= 302 && desired_angle < 325) desired_max_bom = 14;
33
        if (desired_angle >= 325 && desired_angle < 348) desired_max_bom = 15;
34
}
35
36 1627 gnagaraj
void switch_sending(void)
37 1626 gnagaraj
{
38
        if(sending)
39
        {
40
                sending = 0;
41
                bom_off();
42
        }
43
        else
44
        {
45
                sending = 1;
46
                bom_on();
47
        }
48
}
49
50 1691 azirbel
/*
51
Current situation:
52
        go to the center. ends when each edge robto send "I am here" message
53 1626 gnagaraj

54 1691 azirbel
I think compasses are in the club, but not on the robots?
55

56
Assume we have the compasses, and write pseudocode, maybe?
57

58
TODO:
59
  Center:
60
    1. Make a move forward method/state to make the circle begin moving as a group.
61

62
  Edge:
63
    2. Find a way to follow the middle robot and preserve circle structure, or follow a directional command given by the center robot.
64
    3. Fix the error case with wireless - if the center robot does not receive the first exist packet, the robot keeps sending it and will cause error later.
65

66
  In general:
67
    More testing.  Especially with robots that are actually working.
68
*/
69
70
71 1594 azirbel
/*
72
        This program is used to make robots target a center (leader) robot using the BOM,
73
        then drive toward it and stop at a certain distance away.
74

75
        The distance will eventually be adjustable.
76

77
        With adjustment, the leader robot will be able to turn and use its standardized
78
        rangefinder to reposition or space the robots evenly.
79

80
        AuTHORS: Nico, Alex, Reva, Echo, Steve
81
*/
82
83
84
/*
85
TODO:
86 1610 azirbel
        Used: Bots 1, 7
87
        16 Performed Badly
88
        12 worked ok as beacon, not well as edge
89

90
                Fix orient code so the bot does not toggle back and forth when it tries to turn
91

92 1594 azirbel
                Use the center bot to check distances
93 1610 azirbel
Done-->        Count them ("spam" method)
94 1594 azirbel
                Use beacon to find relative positions
95
                Beacon tells them how to move to be at the right distance
96
                *done*Wireless communication, initialization
97
*/
98
99 1618 jmcarrol
100
101 1594 azirbel
void forward(int speed){                        // set the motors to this forward speed.
102
        motor_l_set(FORWARD,speed);
103
        motor_r_set(FORWARD,speed);
104
}
105
void left(int speed){                                // turn left at this speed.
106
        motor_l_set(FORWARD,speed);
107
        motor_r_set(BACKWARD,speed);
108
}
109
void right(int speed){
110
        motor_l_set(BACKWARD,speed);
111
        motor_r_set(FORWARD,speed);
112
}
113
void stop(void){                                        // could be set to motors_off(), or just use this as an alternative.
114 1639 azirbel
        motor_l_set(BACKWARD,0);                        // stop() is better - motors_off() creates a slight delay to turn them back on.
115 1594 azirbel
        motor_r_set(FORWARD,0);
116
}
117
void setforward(int spd1, int spd2){
118
        motor_l_set(FORWARD,spd1);
119
        motor_r_set(FORWARD,spd2);
120
}
121
void backward(int speed){
122
        motor_l_set(BACKWARD, speed);
123
        motor_r_set(BACKWARD, speed);
124
}
125
int get_distance(void){                                // takes an averaged reading of the front rangefinder
126
        int temp,distance,kk=5;                        // kk sets this to 5 readings.
127
        distance =0;
128
        for (int i=0; i<kk; i++){
129
                temp = range_read_distance(IR2);
130
                if (temp == -1)
131
                {
132
                        //temp=0;
133
                        i--;
134
                }
135
                else
136
                        distance+= temp;
137
                delay_ms(3);
138
        }
139
        if (kk>0)
140
                return (int)(distance/kk);
141
        else
142
                return 0;
143
}
144 1618 jmcarrol
145
146 1626 gnagaraj
147 1639 azirbel
/*
148
        Orients the robot so that it is facing the beacon (or the broadcasting BOM).
149

150 1626 gnagaraj
*/
151 1627 gnagaraj
void correctTurn(void)
152 1618 jmcarrol
{
153 1627 gnagaraj
        orb1_set_color(BLUE);                        // BLUE and PURPLE
154
        left(220);
155
        while(1)
156 1618 jmcarrol
        {
157 1627 gnagaraj
                int bomNum = 0;                                // bomNum is the current maximum reading
158
                bom_refresh(BOM_ALL);
159
                bomNum = bom_get_max();
160
                usb_puti(bomNum);
161
                if(bomNum == 4)                                // when it's turned the right way, stop
162 1618 jmcarrol
                {
163 1627 gnagaraj
                        timeout = 0;
164
                        //motor_l_set(1, 200);
165
                        //motor_r_set(1, 200);
166 1639 azirbel
                        break;                                // exits the while() loop to stop the method
167 1618 jmcarrol
                }
168 1639 azirbel
                else                                        // facing the wrong way
169 1618 jmcarrol
                {
170 1639 azirbel
                        if(bomNum == -1)
171
                        {
172 1627 gnagaraj
                                timeout++;
173
174 1639 azirbel
                                if(timeout > 5000)        // if it's been looking too long, move a little bit as it turns
175 1627 gnagaraj
                                {
176
                                        motor_r_set(FORWARD, 210);
177
                                        motor_l_set(BACKWARD, 190);
178
                                }
179
                        }
180
                        else if((bomNum >= 12) || (bomNum < 4))
181
                        {
182
                                motor_l_set(FORWARD, 200);
183
                                motor_r_set(BACKWARD, 200);
184
                                timeout = 0;
185
                        }
186
                        else
187
                        {
188
                                motor_l_set(BACKWARD, 200);
189
                                motor_r_set(FORWARD, 200);
190
                                timeout = 0;
191
                        }
192 1618 jmcarrol
                }
193
        }
194 1627 gnagaraj
        return;
195 1618 jmcarrol
}
196
197 1626 gnagaraj
198 1639 azirbel
/*
199
        This is supposed to (essentially) do a correct turn, then move forward or something.
200 1627 gnagaraj
        Actually, we should just get rid of this.
201 1626 gnagaraj
*/
202 1618 jmcarrol
void correctApproach(void)
203
{
204
        int bomNum = 0;
205
        bom_refresh(BOM_ALL);
206
        bomNum = bom_get_max();
207
        usb_puti(bomNum);
208
        if(bomNum == 4)
209
        {
210
                motor_l_set(1, 200);
211
                motor_r_set(1, 200);
212
        }
213
        else
214
        {
215
                if(bomNum == -1){}
216
                else if((bomNum >= 12) || (bomNum < 4))
217
                {
218
                        motor_l_set(FORWARD, 200);
219
                        motor_r_set(BACKWARD, 200);
220
                }
221
                else
222
                {
223
                        motor_l_set(BACKWARD, 200);
224
                        motor_r_set(FORWARD, 200);
225
                }
226
                delay_ms(100);
227
        }
228
}
229
230 1639 azirbel
/*
231
        drives forward a hardcoded distance. May not be useful.
232
*/
233
void go_straight(void){
234 1594 azirbel
        forward(200);
235
        encoder_rst_dx(LEFT);
236
        encoder_rst_dx(RIGHT);
237
        delay_ms(100);
238
        int x_left = encoder_get_x(LEFT), x_right = encoder_get_x(RIGHT);
239
        int count = 0;
240
        int d;
241
        while (count<25){                                                //count = 25 when bot6; count <12
242
                x_left = encoder_get_x(LEFT);
243
                x_right = encoder_get_x(RIGHT);
244
                d = x_right-x_left;
245
                if (d>13 || d<-13){
246
                        if(d<50 && d>-50){
247
                                d = round(1.0*d/4);
248
                                setforward(200+d, 200-d);
249
                        }
250
                }
251
                delay_ms(32);
252
                count++;
253
        }
254
}
255
256 1626 gnagaraj
257
/*
258
    BLINK the given number times
259
*/
260 1594 azirbel
void blink(int num) {
261
        for(int i = 0; i<num; i++)
262
        {
263
                orb_set_color(ORB_OFF);
264 1639 azirbel
                delay_ms(350);
265 1594 azirbel
                orb_set_color(RED);
266 1610 azirbel
                delay_ms(200);
267 1594 azirbel
        }
268
        orb_set_color(ORB_OFF);
269
}
270
271
272
273 1626 gnagaraj
274
275 1639 azirbel
276
277
//*****************************************************************************************************************************************************************************************
278
279
280
281
282
283
284
/*
285
        A double state machine.  The robot is either an "edge" or a "beacon" depending on the initial potentiometer reading.
286
*/
287 1594 azirbel
int main(void)
288
{
289
        /* Initialize dragonfly board */
290 1618 jmcarrol
            dragonfly_init(ALL_ON);
291
            /* Initialize the basic wireless library */
292
            wl_basic_init_default();
293
            /* Set the XBee channel to your assigned channel */        /* Set the XBee channel to your assigned channel */
294 1594 azirbel
        wl_set_channel(24);
295
296 1626 gnagaraj
        int sending_counter = 0;
297 1594 azirbel
        int robotid = get_robotid();
298
        int used[16];
299 1639 azirbel
        int usedPointer=0;
300 1597 azirbel
        for (int i=0; i<16; i++) used[i] = 0;
301 1594 azirbel
        char send_buffer[2];
302
        int data_length;
303
        unsigned char *packet_data=wl_basic_do_default(&data_length);
304
305
306
        int state = EDGE;
307
        int beacon_State=0;
308 1635 sdevince
        int edge_State=0;
309 1610 azirbel
        int waitingCounter=0;
310
        int robotsReceived=0;
311 1635 sdevince
        int offset = 20, time=0;
312 1627 gnagaraj
313 1594 azirbel
        if(wheel()<100)
314
        {
315
                state=EDGE;
316
        }
317
        else
318
        {
319
                state=BEACON;
320
        }
321
322 1690 azirbel
        int distance=1000;                                        // how far away to stop.
323 1635 sdevince
        int onefoot=250, speed=250;                                // one foot is 490 for bot 1; one foot is 200 for bot6
324 1594 azirbel
325 1596 azirbel
        while(1)
326
        {
327 1626 gnagaraj
                bom_refresh(BOM_ALL);
328
329
                /*
330
                *******TERMinology**************
331
                EDGE=0 other names: slave. Definition: robots on the edge of  the circle;
332
                BEACON=1 other name: master. Definition: robots in the center of the circle;
333

334

335
                *******EXPECTED MOVES **********
336
                The designed movement:
337
                 1. one center robot, several edge robots are on;
338
                 2. center robots: button 1 is pressed;
339
                 3. center robots: send global package telling edges that he exists;
340
                 4. EDGE robots response with ACK.
341
                 5. EDGE robots wait for center robots to finish counting (DONE package)
342 1690 azirbel
                 6. EDGE robtos approach the center robtot and stop at the "onefoot" distance, send message to the center
343 1626 gnagaraj
                */
344
345
346
                // decide if its is center or not.
347 1596 azirbel
                switch(state)
348
                {
349 1626 gnagaraj
                        /**********
350
                                if  EDGE /slave robots
351
                        */
352
                        case 0:
353 1635 sdevince
                                switch(edge_State)
354 1594 azirbel
                                {
355 1635 sdevince
                                        /*
356
                                                0. EDGE robots are on.
357
                                                1. They are waiting for ExiST pacakage from the Center robots
358
                                                2. After they receive the package, they send ACK package to center.
359
                                                3. Wait the center robot to finish counting all EDGE robots
360
                                        */
361
                                        case 0:
362
                                                bom_off();
363
                                                orb1_set_color(YELLOW);orb2_set_color(CYAN);
364
                                                packet_data=wl_basic_do_default(&data_length);
365
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_EXIST)
366
                                                {
367
                                                        send_buffer[0]=CIRCLE_ACTION_ACK;
368
                                                        send_buffer[1]=robotid;
369
370
                                                        wl_basic_send_global_packet(42,send_buffer,2);
371
                                                        edge_State=1;
372
                                                }
373
                                        break;
374
                                        /*
375
                                                1. Wait for DONE package
376
                                                2. The counting process is DONE
377
                                        */
378
                                        case 1:
379
380
                                                orb_set_color(YELLOW);orb2_set_color(PURPLE);
381
                                                packet_data=wl_basic_do_default(&data_length);
382
                                                //wl_basic_send_global_packet(42,send_buffer,2);
383 1594 azirbel
384 1635 sdevince
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE)
385
                                                {
386
                                                        edge_State=2;
387
                                                }
388
                                        break;
389 1596 azirbel
390 1635 sdevince
                                        case 2:
391
                                                // COLOR afer DONE ---> MAGENTA
392
                                                orb_set_color(MAGENTA);
393
                                                correctTurn();                        // turn to face the beacon
394
                                                forward(175);
395
                                                //range_init();
396
397
398
                                                distance = get_distance();
399
                                                time=0;
400
                                                while ((distance-offset)>=onefoot || distance==0 || (distance+offset)<onefoot)
401
                                                {
402
                                                        if(distance==0)
403
                                                                orb_set_color(WHITE);
404
                                                        else if(distance-offset>=onefoot)
405
                                                                forward(175);
406
                                                        else
407
                                                                backward(175);
408
                                                        //correctApproach();
409
                                                        distance = get_distance();
410
                                                        delay_ms(14);
411
                                                        time+=14;
412
                                                        if(time>500){
413
                                                                correctTurn();
414
                                                                time=0;
415
                                                        }
416
                                                }
417
418
                                                stop();
419
                                                orb_set_color(LIME);
420 1639 azirbel
421
                                                send_buffer[0]=CIRCLE_ACTION_ACK;
422
                                                send_buffer[1]=robotid;
423
                                                wl_basic_send_global_packet(42,send_buffer,2);
424
425 1635 sdevince
                                                edge_State=3;
426
                                        break;
427
428 1639 azirbel
                                        // wait until the beacon sends out its robot ID
429 1690 azirbel
/*
430
        // as we don't check distance to center one by one now,
431
        no more private communication at this point.
432 1635 sdevince
                                        case 3:
433 1639 azirbel
                                                orb_set_color(YELLOW);
434
                                                orb2_set_color(GREEN);
435

436
                                                packet_data=wl_basic_do_default(&data_length);
437
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK && packet_data[1]==robotid)
438
                                                {
439
                                                        bom_on();
440
                                                        orb_set_color(ORANGE);
441
                                                }
442
                                                if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE && packet_data[1]==robotid)
443
                                                {