Project

General

Profile

Statistics
| Revision:

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

History | View | Annotate | Download (6.47 KB)

1
#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

    
9
/*
10
        This program is used to make robots target a center (leader) robot using the BOM,
11
        then drive toward it and stop at a certain distance away.
12
        
13
        The distance will eventually be adjustable.
14

15
        With adjustment, the leader robot will be able to turn and use its standardized
16
        rangefinder to reposition or space the robots evenly.
17
        
18
        AuTHORS: Nico, Alex, Reva, Echo, Steve
19
*/
20

    
21

    
22
/* 
23
TODO:
24
                Check BOM more often and before final stop
25
                Make BOM check more comprehensively
26
                Use the center bot to check distances
27
                Count them ("spam" method)
28
                Use beacon to find relative positions
29
                Beacon tells them how to move to be at the right distance
30
                *done*Wireless communication, initialization
31
*/
32

    
33
void forward(int speed){                        // set the motors to this forward speed.
34
        motor_l_set(FORWARD,speed);
35
        motor_r_set(FORWARD,speed);
36
}
37
void left(int speed){                                // turn left at this speed.
38
        motor_l_set(FORWARD,speed);
39
        motor_r_set(BACKWARD,speed);
40
}
41
void right(int speed){
42
        motor_l_set(BACKWARD,speed);
43
        motor_r_set(FORWARD,speed);
44
}
45
void stop(void){                                        // could be set to motors_off(), or just use this as an alternative.
46
        motor_l_set(BACKWARD,0);
47
        motor_r_set(FORWARD,0);
48
}
49
void setforward(int spd1, int spd2){
50
        motor_l_set(FORWARD,spd1);
51
        motor_r_set(FORWARD,spd2);
52
}
53
void backward(int speed){
54
        motor_l_set(BACKWARD, speed);
55
        motor_r_set(BACKWARD, speed);
56
}
57
int get_distance(void){                                // takes an averaged reading of the front rangefinder
58
        int temp,distance,kk=5;                        // kk sets this to 5 readings.
59
        distance =0;
60
        for (int i=0; i<kk; i++){
61
                temp = range_read_distance(IR2);
62
                if (temp == -1)
63
                {
64
                        //temp=0;
65
                        i--;
66
                }
67
                else
68
                        distance+= temp;
69
                delay_ms(3);
70
        }
71
        if (kk>0)
72
                return (int)(distance/kk);
73
        else 
74
                return 0;
75
}
76
void turn_to_beacon(int max){
77
        if (max>-1 && max<16){
78
                int index = (max+12)%16;
79
                if (index==0) { 
80
                        stop(); 
81
                }
82
                else if (index<8) right(170);
83
                else left(170);
84
        }
85
}
86

    
87
void turn_to_beacon2(int max){                                // like the previous but no stop() call'
88

    
89

    
90

    
91

    
92
        if (max>-1 && max<16){
93
                int index = (max+12)%16;
94
                if (index==0) { 
95
                         
96
                }
97
                else if (index<8) right(170);
98
                else left(170);
99
        }
100
}
101
void orient(void){
102
        int max_index = -1;
103
        while (max_index!=4) {
104
                /* Refresh and make sure the table is updated */
105
                bom_refresh(BOM_ALL);
106
                max_index = bom_get_max();
107
                turn_to_beacon(max_index);
108
                delay_ms(22);
109
        }
110
}
111
void orient2(void){
112
        int max_index = -1;
113
        while (max_index!=4) {
114
                /* Refresh and make sure the table is updated */
115
                bom_refresh(BOM_ALL);
116
                max_index = bom_get_max();
117
                turn_to_beacon2(max_index);
118
                delay_ms(22);
119
        }
120
}
121
void go_straight(void){                                                // drives forward a hardcoded distance. May not be useful.
122
        forward(200);
123
        encoder_rst_dx(LEFT);
124
        encoder_rst_dx(RIGHT);
125
        delay_ms(100); 
126
        int x_left = encoder_get_x(LEFT), x_right = encoder_get_x(RIGHT);
127
        int count = 0;
128
        int d;
129
        while (count<25){                                                //count = 25 when bot6; count <12
130
                x_left = encoder_get_x(LEFT);
131
                x_right = encoder_get_x(RIGHT);
132
                d = x_right-x_left;
133
                if (d>13 || d<-13){
134
                        if(d<50 && d>-50){
135
                                d = round(1.0*d/4);
136
                                setforward(200+d, 200-d);
137
                        }
138
                }
139
                delay_ms(32);
140
                count++;
141
        }
142
}
143
void go_straight_onefoot(void){                                // essentially, another name for the above.  Should be removed.
144
        go_straight();
145
}
146

    
147
void blink(int num) {
148
        for(int i = 0; i<num; i++)
149
        {
150
                orb_set_color(ORB_OFF);
151
                delay_ms(500);
152
                orb_set_color(RED);
153
                delay_ms(500);
154
        }
155
        orb_set_color(ORB_OFF);
156
}
157

    
158

    
159

    
160
int main(void)
161
{
162
        /* Initialize dragonfly board */
163
        dragonfly_init(ALL_ON);
164
        xbee_init();
165
        encoders_init();
166
        /* Initialize the basic wireless library */
167
        wl_basic_init_default();
168
        /* Set the XBee channel to your assigned channel */
169
        wl_set_channel(24);
170

    
171
        int robotid = get_robotid();
172
        int used[16];
173
        for (int i=0; i<16; i++) used[i] = 0;
174
        char send_buffer[2];
175
        int data_length;
176
        unsigned char *packet_data=wl_basic_do_default(&data_length);
177
        
178
        
179
        int state = EDGE;
180
        int beacon_State=0;
181
        int NUM_ROBOTS=2;
182
        int robotsRecieved=0;
183
        if(wheel()<100)
184
        {
185
                state=EDGE;
186
        }
187
        else
188
        {
189
                state=BEACON;
190
        }
191
        
192
        int distance=1000;                                                // how far away to stop.
193
        int onefoot=300, speed=200;                                // one foot is 490 for bot 1; one foot is 200 for bot6
194
        
195
        while(1)
196
        {
197
                switch(state)
198
                {
199
                        case 0:                        // EDGE
200
                                
201
                                orb_set_color(GREEN);
202
                                while(1)
203
                                {
204
                                        orb_set_color(YELLOW);
205
                                        packet_data=wl_basic_do_default(&data_length);
206
                                        if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_EXIST)
207
                                        {
208
                                                send_buffer[0]=CIRCLE_ACTION_ACK;
209
                                                send_buffer[1]=robotid;
210
                                                
211
                                                wl_basic_send_global_packet(42,send_buffer,2);
212
                                                break;
213
                                        }
214
                                }
215
                                
216
                                while(1)                // wait for the center bot to count all the robots and send a "done" packet
217
                                {
218
                                        orb_set_color(RED);
219
                                        packet_data=wl_basic_do_default(&data_length);
220
                                        wl_basic_send_global_packet(42,send_buffer,2);
221
                                        
222
                                        if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE)
223
                                        {
224
                                                break;
225
                                        }
226
                                }
227
                                
228
                                orb_set_color(GREEN);
229
                                
230
                                orient();
231
                                forward(speed);
232
                                //range_init();
233
                                
234
                                orb_set_color(BLUE);
235
                                
236
                                distance = get_distance();
237
                                while (distance>=onefoot || distance==0)
238
                                {
239
                                        if(distance==0)
240
                                                orb_set_color(WHITE);
241
                                        distance = get_distance();
242
                                        orient2();
243
                                        forward(speed);
244
                                        delay_ms(14);
245
                                }
246
                                stop();
247
                                orient();
248
                                
249
                                //button1_wait ();                        // code for lab1.
250
                                //go_straight_onefoot();
251
                                stop();
252
                                break;
253
                                
254
                                
255
                                
256
                                
257
                        case 1:                        // BEACON
258
                                switch(beacon_State) {
259
                                case 0:                // wait for a button to be pressed, then go to state 1
260
                                        bom_on();
261
                                        orb_set_color(PURPLE);
262
                                        if(button1_click()) beacon_State=1;
263
                                break;        
264
                                case 1:                // sends a global exist packet to see how many robots there are
265
                                        send_buffer[0]=CIRCLE_ACTION_EXIST;
266
                                        send_buffer[1]=get_robotid();
267
                                        wl_basic_send_global_packet(42,send_buffer,2);
268
                                        beacon_State=2;
269
                                break;
270
                                case 2:         // find out how many robots there are
271
                                orb_set_color(ORANGE);
272
                                packet_data=wl_basic_do_default(&data_length);
273
                                if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
274
                                {
275
                                        orb_set_color(WHITE);
276
                                        if(used[packet_data[1]]==0){                //only add to robots seen if you haven't gotten an ACK from this robot
277
                                                robotsRecieved++;
278
                                                used[packet_data[1]]=1;
279
                                        }
280
                                }
281
                                if(robotsRecieved==NUM_ROBOTS)
282
                                        beacon_State=3;
283
                                break;
284
                                case 3:
285
                                send_buffer[0]=CIRCLE_ACTION_DONE;
286
                                wl_basic_send_global_packet(42,send_buffer,2);
287
                                break;
288
                                }
289
                        break;
290
                }
291
        }
292

    
293
        orb_set_color(RED);
294
        while(1); /* END HERE */
295

    
296
        return 0;
297
}