Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / traffic_navigation / main-intersectionDebug.c @ 1999

History | View | Annotate | Download (12 KB)

1
#ifdef INTERSECTION_MAIN_DEBUG
2
/*
3
 * main.c for Traffic Navigation, Intersection queue debugging (version 2)
4
 * Runs the highest level behavior for the Dynamic Traffic Navigation (DTM) SURG
5
 *
6
 * Author: Colony Project, CMU Robotics Club
7
 */
8
#include "traffic_navigation.h"
9

    
10
        static int state, sign, turnDir;
11
        //resolvPrevBotID: -3 : not initialized
12
        //                 -2 : recieved a resolv packet but still have not
13
        //                      found someone to be before me
14
        //                 -1 : bot that was there is done getting in queue
15
        //                 otherwise, that bot needs to get in the queue before this one
16
        static char sendBuffer[PACKET_LENGTH], queuePrevBot, queueNextBot, id, intersectionNum, resolvPrevBotID = -3;
17
        unsigned char resolvSeed = 0xC9, resolvDraw = 0, resolvPrevBotDraw = 0;
18

    
19
        /* Wireless packet parsing */
20
        int wirelessPacketHandle(int state);
21
        void enterIntersection(void);
22
        void sendResolv(bool override);
23
        unsigned char resolvRandomNumberGen();
24

    
25

    
26
int main (void) {
27
        
28
        /* Initialize the dragonfly boards, the xbee, encoders, lineFollowing */
29
        dragonfly_init(ALL_ON);
30
        xbee_init();
31
        encoders_init();
32
        rtc_init(SIXTEENTH_SECOND, NULL);
33
        wl_basic_init_default();
34
        wl_set_channel(13);
35
        initializeData();
36
        
37
        id = get_robotid();
38
        sign = 0;
39
        
40
        //Test code
41
        state = SROAD;
42

    
43
        sendBuffer[1] = id;
44

    
45
        /*
46
        doDrive(200);
47
        turn(DOUBLE, ILEFT);
48
        */
49
        
50
        while (1) {
51
                /*DTM Finite State Machine*/
52
                switch(state){
53
                case SROAD:/*Following a normal road*/
54

    
55
                        //idle parsing
56
                        wirelessPacketHandle(SROAD);
57

    
58
//                        sign = lineFollow();
59
                        //other road behaviors
60
                                //tailgating?
61
                        //read barcode
62
                        orb1_set_color(ORB_OFF);
63
                        orb2_set_color(ORB_OFF);
64
                        if(button1_click()){
65
                                state = SINTERSECTION_ENTER;
66
                        }
67
                        break;
68
                case SINTERSECTION_ENTER:/*Entering, and in intersection*/
69
                        orb1_set_color(RED);
70
                        orb2_set_color(ORB_OFF);
71

    
72
                        usb_puts("STATE: SINTERSECTION_ENTER\n");
73

    
74
                        //empty packet queue
75
                        //while(wirelessPacketHandle(SCLEARPACKET) != ENOPACKET);
76

    
77
                        /*Intersection queue:
78
                         *Each robot when entering the intersection will check for other robots
79
                         *in the intersection, and insert itself in a queue to go through.
80
                         */
81
                        queuePrevBot = -1;
82
                        queueNextBot = -1;
83
                        resolvPrevBotID = -3;
84
                        resolvPrevBotDraw = 0;
85
                        resolvDraw = 0;
86

    
87
                        sign = 0; //Test code until barcodes integrated
88
                        intersectionNum = 0; //actually set this.
89
                        turnDir = 1;
90

    
91
                        enterIntersection(); //sends wireless packet for entry
92
                        state = SINTERSECTION_WAIT;
93

    
94
                        rtc_reset(); //reset rtc for timeout wait for reply
95

    
96
                        bool done = false;
97
                        bool retried = false;
98
                        while(rtc_get() < 8 && !done){//waits for a reply, otherwise assumes it is first in queue
99
                                int ret = wirelessPacketHandle(SINTERSECTION_ENTER);
100
                                if(rtc_get() > 6 && !retried){//by now all resolvs should be done from bots that arrived earlier...
101
                                        orb2_set_color(PURPLE);
102
                                        enterIntersection();
103
                                        retried = true;
104
                                }
105
                                switch (ret) {
106
                                        case KPLACEDINQUEUE:
107
                                                orb2_set_color(GREEN); //entered queue!
108
                                                done = true;
109
                                                break;
110
                                        case KFAILEDTOQUEUE:
111
                                                usb_puts("Failed to queue D:\n");
112
                                                orb2_set_color(RED);
113
                                                enterIntersection();
114
                                                rtc_reset();
115
                                                break;
116
                                        case KRESOLVINGENTER:
117
                                                orb2_set_color(ORANGE);
118
                                                state = SINTERSECTION_ENTER_RESOLV;
119
                                                done = true;
120
                                                break;
121
                                }
122
                        }
123
                        break;
124
                case SINTERSECTION_ENTER_RESOLV:
125
                        orb1_set_color(PINK);
126
                        orb2_set_color(ORB_OFF);
127

    
128
                        usb_puts("STATE: SINTERSECTION_ENTER_RESOLV\n");
129
                        rtc_reset();
130

    
131
                        done = false;
132
                        retried = false;
133
                        while(rtc_get() < 4 && !done){
134
                                int ret = wirelessPacketHandle(SINTERSECTION_ENTER_RESOLV);
135
                                switch (ret) {
136
                                        case KRESOLVINGENTER:
137
                                                orb2_set_color(YELLOW);
138
                                                break;
139
                                        case KPLACEDINQUEUE:
140
                                                orb2_set_color(GREEN); //entered queue!
141
                                                done = true;
142
                                                break;
143
                                        case KFAILEDTOQUEUE:
144
                                                usb_puts("Failed to queue D:\n");
145
                                                orb2_set_color(RED);
146
                                                enterIntersection();
147
                                                rtc_reset();
148
                                                break;
149
                                }
150
                                if(!done && resolvPrevBotID == (char) -1 && !retried){
151
                                        enterIntersection();
152
                                        rtc_reset();
153
                                        retried = true;
154
                                } else if(!done && resolvPrevBotID == (char) -2 && rtc_get() > 2){
155
                                        //send a intersection reply to myself to
156
                                        //trigger other bots to enter queue.
157
                                        sendBuffer[0] = WINTERSECTIONREPLY;
158
                                        sendBuffer[2] = intersectionNum;
159
                                        sendBuffer[3] = id;
160
                                        wl_basic_send_global_packet(42, sendBuffer, PACKET_LENGTH);
161

    
162
                                        done = true;
163
                                        break;
164
                                }
165
                        }
166
                        state = SINTERSECTION_WAIT;
167
                        break;
168
                case SINTERSECTION_WAIT:/*Waiting in intersection */
169
                        orb1_set_color(YELLOW);
170
                        orb2_set_color(ORB_OFF);
171
                        usb_puts("STATE: SINTERSECTION_WAIT\n");
172

    
173
                        done = false;
174
                        while(queuePrevBot != (char) -1){
175
                                done = true;
176
                                int ret = wirelessPacketHandle(state);
177
                                switch (ret){
178
                                        case KFIRSTINQUEUE:
179
                                                orb2_set_color(GREEN);
180
                                                state = SINTERSECTION_DRIVE;
181
                                                break;
182
                                        case KREPLIEDTOENTER:
183
                                                orb2_set_color(BLUE);
184
                                                break;
185
                                        case KRESOLVINGENTER:
186
                                                orb2_set_color(ORANGE);
187
                                                break;
188
                                }
189
                        }
190
                        //hack to make sure bot that just left intersection is
191
                        //really out of the intersection.
192
                        rtc_reset();
193
                        while(rtc_get() < 2 && done){//wait one second
194
                                wirelessPacketHandle(state);
195
                        }
196

    
197
                        state = SINTERSECTION_DRIVE;
198
                        break;
199
                        state = SINTERSECTION_DRIVE;
200
                        break;
201
                case SINTERSECTION_DRIVE:
202
                        usb_puts("STATE: SINTERSECTION_DRIVE\n");
203
                        orb1_set_color(GREEN);
204
                        orb2_set_color(ORB_OFF);
205

    
206
                         while(!button2_click()){
207
                                 int ret = wirelessPacketHandle(state);
208
                                 switch (ret){
209
                                         case KREPLIEDTOENTER:
210
                                                orb2_set_color(BLUE);
211
                                                break;
212
                                         case KRESOLVINGENTER:
213
                                                 orb2_set_color(ORANGE);
214
                                                break;
215
                                 }
216
                         }
217
                        
218
                        //Exits intersection
219
                        orb1_set_color(WHITE);
220

    
221
                        sendBuffer[0] = WINTERSECTIONEXIT;
222
                        sendBuffer[2] = intersectionNum;//Intersection #
223
                        wl_basic_send_global_packet(42, sendBuffer, PACKET_LENGTH);
224

    
225
                        state = SROAD;
226
                        break;
227
                default:
228
                        usb_puts("I got stuck in an unknown state! My state is ");
229
                        usb_puti(state);
230
                }
231
        }
232

    
233
}
234

    
235
int wirelessPacketHandle(int state){
236
        int dataLength = 0;
237
        unsigned char *packet = NULL;
238
        packet = wl_basic_do_default(&dataLength);
239
        
240
        /* sanity check */
241
        if(dataLength == 0 || packet == NULL) //no packet
242
                return ENOPACKET;
243

    
244
        if(dataLength != PACKET_LENGTH)
245
                return EPACKETLEN;
246

    
247
        usb_puts("Recieved Wireless Packet: ");
248
        for(int i = 0; i < dataLength; i++){
249
                usb_puti(packet[i]);
250
                usb_putc(' ');
251
        }
252
        usb_putc('\n');
253

    
254
        switch (packet[0]){
255
                case WROADENTRY: //[type, bot, road]
256
                        return ENOACTION;
257
                        break;
258
                case WROADEXIT: //[type, bot, road]
259
                        return ENOACTION;
260
                        break;
261
                case WROADSTOP: //[type, bot, road]
262
                        return ENOACTION;
263
                        break;
264
                case WINTERSECTIONENTRY: //[type, bot, intersection, fromDir, toDir]
265
                        if (packet[2] == intersectionNum){
266
                                switch (state){
267
                                        case SINTERSECTION_ENTER:
268
                                                sendResolv(false);
269
                                                resolvPrevBotID = -2;
270
                                                return KRESOLVINGENTER;
271
                                                break;
272
                                        case SINTERSECTION_ENTER_RESOLV:
273
                                                return ENOACTION;
274
                                        case SINTERSECTION_WAIT:
275
                                        case SINTERSECTION_DRIVE:
276
                                                if(queueNextBot == (char) -1){
277
                                                        sendBuffer[0] = WINTERSECTIONREPLY;
278
                                                        sendBuffer[2] = intersectionNum;
279
                                                        sendBuffer[3] = packet[1];
280
                                                        wl_basic_send_global_packet(42, sendBuffer, PACKET_LENGTH);
281
                                                        queueNextBot = packet[1];
282
                                                        return KREPLIEDTOENTER;
283
                                                }
284
                                                break;
285

    
286
                                }
287
                        }
288
                        break;
289
                case WINTERSECTIONREPLY: //[type, fromBot, intersection, toBot]
290
                        if (packet[2] == intersectionNum){
291
                                switch (state){
292
                                        case SINTERSECTION_ENTER:
293
                                        case SINTERSECTION_ENTER_RESOLV:
294
                                                if(packet[3] == id){ //Reply for me
295
                                                        queuePrevBot = packet[1];
296
                                                        return KPLACEDINQUEUE;
297
                                                } else {
298
                                                        if(packet[3] == resolvPrevBotID)
299
                                                                resolvPrevBotID = -1;
300
                                                        return KFAILEDTOQUEUE;
301
                                                }
302
                                                break;
303
                                        default:
304
                                                return ENOACTION;
305
                                }
306
                        }
307
                        break;
308
                case WINTERSECTIONEXIT: //[type, bot, intersection]
309
                        if (packet[2] == intersectionNum){
310
                                switch (state){
311
                                        case SINTERSECTION_WAIT:
312
                                                if(packet[1]==queuePrevBot){
313
                                                        queuePrevBot=-1;
314
                                                        return KFIRSTINQUEUE;
315
                                                }
316
                                }
317
                        }
318
                        break;
319
                case WINTERSECTIONGO: //[type, bot, intersection]
320
                        break;
321
                case WINTERSECTIONPOLICEENTRY: //[?]
322
                        return ENOACTION;
323
                        break;
324
                case WINTERSECTIONRESOLVERACE: //[type, bot, intersection, num]
325
                        //in the case robots draw the same number these will be
326
                        //arbitrated using the sending robot's id, prefering
327
                        //lower ids
328
                        usb_puts("Now in wireless WINTERSECTIONRESOLVERACE handler: resolvPrevBotID: ");
329
                        usb_puti((int) resolvPrevBotID);
330
                        usb_putc('\n');
331
                        if (packet[2] == intersectionNum){
332
                                switch (state){
333
                                        case SINTERSECTION_ENTER:
334
                                        case SINTERSECTION_ENTER_RESOLV:
335
                                                if(resolvPrevBotID == (char) -3){
336
                                                        usb_puts("resolvPrevBotID == -3; sending a resolv packet and setting to -2\n");
337
                                                        sendResolv(false);
338
                                                        resolvPrevBotID = -2;
339
                                                }
340
                                                if((unsigned char) packet[3] == resolvDraw && id > packet[1]){
341
                                                        //other bot drew same number as me,
342
                                                        //and i have a higher id, so it goes first.
343
                                                        usb_puts("bot ");
344
                                                        usb_puti(packet[1]);
345
                                                        usb_puts(" Drew the same number as me and I have a higher id, so it goes first\n");
346
                                                        resolvPrevBotID = packet[1];
347
                                                } else if((unsigned char) packet[3] == resolvPrevBotDraw && resolvPrevBotID > packet[1]){
348
                                                        //other bot drew same number as the bot before me,
349
                                                        //so if it has a higher id than the bot before me,
350
                                                        //it is going to go in between that one and me.
351
                                                        usb_puts("bot ");
352
                                                        usb_puti(packet[1]);
353
                                                        usb_puts(" Drew the same number as the bot before me, and the bot before me has have a higher id, so this goes first\n");
354
                                                        resolvPrevBotID = packet[1];
355
                                                } else if((unsigned char)packet[3] < resolvDraw && (unsigned char)packet[3] > resolvPrevBotDraw){
356
                                                        //found a bot that goes in between the bot before me
357
                                                        //and me, so now it is before me.
358
                                                        usb_puts("bot ");
359
                                                        usb_puti(packet[1]);
360
                                                        usb_puts(" Drew a lower number bot before me, and the bot before me has have a higher id, so this goes first\n");
361
                                                        resolvPrevBotDraw = packet[3];
362
                                                        resolvPrevBotID = packet[1];
363
                                                }
364
                                                return KRESOLVINGENTER;
365
                                                break;
366
                                        case SINTERSECTION_WAIT:
367
                                        case SINTERSECTION_DRIVE:
368
                                                usb_puts("Trying to resolv in non resolv case...queueNextbot = "); usb_puti(queueNextBot); usb_puts("\n");
369
                                                if(queueNextBot == (char) -1){
370
                                                        sendResolv(true);
371
                                                }
372
                                                return KRESOLVINGENTER;
373
                                                break;
374
                                }
375
                                
376
                        }
377
                        break;
378
                case WHIGHWAYENTRY: //[type, bot, highway]
379
                        return ENOACTION;
380
                        break;
381
                case WHIGHWAYREPLY: //[type, fromBot, highway, toBot]
382
                        return ENOACTION;
383
                        break;
384
                case WHIGHWAYEXIT: //[type, bot, highway]
385
                        return ENOACTION;
386
                        break;
387
                case WPINGGLOBAL: //[type, bot]
388
                        return ENOACTION;
389
                        break;
390
                case WPINGBOT: //[type, fromBot, toBot]
391
                        return ENOACTION;
392
                        break;
393
                case WPINGQUEUE: //[type, fromBot, toBot]
394
                        return ENOACTION;
395
                        break;
396
                case WPINGREPLY: //[type, fromBot, toBot]
397
                        return ENOACTION;
398
                        break;
399
                case WCOLLISIONAVOID: //[type, bot, intersection, collision-int] //Note: collision is an int and thus takes two spaces
400
                        return ENOACTION;
401
                        break;
402
                default:
403
                        return ENOACTION;
404
                        break;
405
        }
406
}
407

    
408
unsigned char resolvRandomNumberGen(){
409
        if ((resolvSeed *= (rtc_get())%9) == 0){
410
                return resolvSeed + 1; //0 is a reseved priority value for the last
411
                                 //bot that is already in the queue.
412
        }
413
        return resolvSeed;
414
}
415
void sendResolv(bool override){
416
        if(!override)
417
                resolvDraw = resolvRandomNumberGen();
418
        else
419
                resolvDraw = 0;
420
        sendBuffer[0] = WINTERSECTIONRESOLVERACE;
421
        sendBuffer[2] = intersectionNum;
422
        sendBuffer[3] = resolvDraw;
423
        wl_basic_send_global_packet(42, sendBuffer, PACKET_LENGTH);
424
}
425
void enterIntersection(void){
426
        //Sends packet announcing its entry to the intersection
427
        sendBuffer[0] = WINTERSECTIONENTRY;
428
        sendBuffer[2] = intersectionNum;//Intersection #
429
        sendBuffer[3] = 0; //getIntersectPos(sign);
430
        sendBuffer[4] = turnDir;
431
        wl_basic_send_global_packet(42, sendBuffer, PACKET_LENGTH);
432
}
433
#endif