root / branches / encoders / code / projects / colonet / testing / wl_network_colonet / wl_adhoc.c @ 1390
History | View | Annotate | Download (20 KB)
1 |
/**
|
---|---|
2 |
\file wl_adhoc.c
|
3 |
Wireless ad hoc networking.
|
4 |
NOW WITH SENSORS
|
5 |
Robots can come in and out of the ring.
|
6 |
*/
|
7 |
|
8 |
/*
|
9 |
Wireless ad hoc networking + sensors
|
10 |
|
11 |
If a robot is the first to turn on, it will set itself as the leader
|
12 |
|
13 |
The next robot will receive that packet and tokenize with it.
|
14 |
Each other robot turned on will receive packets, and join the ring.
|
15 |
All the robots will also change their network topology (num_bots)
|
16 |
|
17 |
|
18 |
2006-11-21: Felix
|
19 |
Fixed buzzer.c code (copied from a different dir).
|
20 |
Code still works on robots at this time
|
21 |
|
22 |
Felix used this code to figure out the robot resetting problem. BOM sensor 10
|
23 |
needs to be taped up.
|
24 |
You may put this event in the history books.
|
25 |
|
26 |
|
27 |
2006-10-31 Kevin
|
28 |
Changed the boards to the 115200 Baud rate. Changed the pound define to reflect this.
|
29 |
The boards have been hardcoded to do this. They are labelled in case you do not know
|
30 |
which ones do this. It works.
|
31 |
|
32 |
2006-10-13: Kevin
|
33 |
Made improvements to make the module more modular and general
|
34 |
so that you can just drag and drop it into any behavior.
|
35 |
Began the integration of autonomous charging. We're using the
|
36 |
error system that is built into wl_adhoc originally to ping the
|
37 |
charge stations. Do not know if it works, can't test it yet. But
|
38 |
wireless normally still works.
|
39 |
|
40 |
2006-08-07: Felix
|
41 |
Added the use of the sensor row that was being transmitted
|
42 |
Robots now share a common table of sensor 'positions'
|
43 |
Just add light sensing and you're good to go
|
44 |
|
45 |
WARNING: Robots seem to reset randomly due to batteries, especially
|
46 |
when moving around. Could be brownout detector kicking in.
|
47 |
Added a beep at startup to detect reset.
|
48 |
|
49 |
2006-08-03: Felix
|
50 |
Now added follow-the-leader code
|
51 |
Battery problem -- testing only really worked on power supply
|
52 |
|
53 |
Robots follow the leader (theoretically).
|
54 |
They fill their own row of the sensors matrix, but do not get
|
55 |
the other robots' row -- not in the code.
|
56 |
|
57 |
2006-07-27: Felix
|
58 |
Created new directory for sensors use
|
59 |
|
60 |
2006-07-24: Felix
|
61 |
Added BOM.c/BOM.h
|
62 |
bom_test works -- gets max bom
|
63 |
|
64 |
Added the get_maxbom each time you get a wireless packet
|
65 |
---NEEDS TESTING
|
66 |
|
67 |
Also, packet sent should contain your 'row'
|
68 |
Also, received packet should be stored in matrix
|
69 |
|
70 |
2006-07-13: Felix
|
71 |
Works for the most part
|
72 |
W00t
|
73 |
|
74 |
Still a few kinds I imagine, but robot death & birth work
|
75 |
*/
|
76 |
|
77 |
#include "firefly+_lib.h" |
78 |
#include "wl_adhoc.h" |
79 |
#include <avr/interrupt.h> |
80 |
#include <colonet.h> |
81 |
|
82 |
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
83 |
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
84 |
|
85 |
unsigned char set_orb_wireless = 0; |
86 |
//unsigned char set_orb_wireless = 1;
|
87 |
|
88 |
/*
|
89 |
int main( void )
|
90 |
{
|
91 |
wl_adhoc();
|
92 |
bom_test();
|
93 |
|
94 |
return 0;
|
95 |
}
|
96 |
*/
|
97 |
|
98 |
void bom_test (void) |
99 |
{ |
100 |
int maxb;
|
101 |
|
102 |
lcd_init(); |
103 |
analog_init(); |
104 |
|
105 |
while(1) { |
106 |
if(button1_read()){
|
107 |
lcd_clear_screen(); |
108 |
bom_on(); |
109 |
delay_ms(100);
|
110 |
} |
111 |
|
112 |
if(button2_read()) {
|
113 |
lcd_clear_screen(); |
114 |
bom_off(); |
115 |
delay_ms(100);
|
116 |
} |
117 |
|
118 |
maxb = getMaxBom(); |
119 |
|
120 |
lcd_putint(maxb); |
121 |
|
122 |
delay_ms(50);
|
123 |
} |
124 |
} |
125 |
|
126 |
void wl_adhoc()
|
127 |
{ |
128 |
//initialize the serial modules
|
129 |
serial_init(WL_BAUD); //XBee
|
130 |
serial1_init(BAUD115200); //Serial port
|
131 |
|
132 |
//lcd, orb, all that good stuff
|
133 |
lcd_init(); |
134 |
analog_init(); |
135 |
led_init(); |
136 |
orb_init(); |
137 |
motors_init(); |
138 |
buzzer_init(); |
139 |
|
140 |
//init the wireless
|
141 |
wl_init(); |
142 |
|
143 |
//int max_bom_to_follow;
|
144 |
|
145 |
while(1){ |
146 |
//this needs to happen continuously -- it handles the packet
|
147 |
parse_buffer(); |
148 |
|
149 |
/*
|
150 |
if(SRC == 0) {
|
151 |
//leader -- just drive
|
152 |
drive_forward();
|
153 |
}
|
154 |
else {
|
155 |
max_bom_to_follow = getSelfSensor(SRC, PREV, NUM_BOTS);
|
156 |
//lcd_putchar('f');
|
157 |
//lcd_putchar(max_bom_to_follow + 48);
|
158 |
//lcd_putchar(' ');
|
159 |
seek(max_bom_to_follow);
|
160 |
}
|
161 |
*/
|
162 |
|
163 |
//button1 prints debug information
|
164 |
if(button1_read()) {
|
165 |
//lcd_clear_screen();
|
166 |
display_debug(); |
167 |
delay_ms(10);
|
168 |
} |
169 |
|
170 |
/*
|
171 |
//button2 does nothing
|
172 |
if(button2_read()) {
|
173 |
//wl_create_packet();
|
174 |
//wl_send();
|
175 |
//delay_ms(10);
|
176 |
}
|
177 |
*/
|
178 |
} |
179 |
|
180 |
return;
|
181 |
} |
182 |
|
183 |
/**
|
184 |
\fn display_debug
|
185 |
\brief displays debug information
|
186 |
|
187 |
Prints out 4 numbers, in the following order
|
188 |
( PREV | SRC | DEST | NUM_BOTS | wl_to_death_count )
|
189 |
where PREV is the previous robot before you
|
190 |
SRC is you
|
191 |
DEST is your destination
|
192 |
NUM_BOTS is the total number of robots in the ring
|
193 |
wl_do_death_count is the number of timeouts that will result in a death
|
194 |
*/
|
195 |
void display_debug()
|
196 |
{ |
197 |
lcd_clear_screen(); |
198 |
lcd_putchar('(');
|
199 |
lcd_putchar(PREV+48);
|
200 |
lcd_putchar('|');
|
201 |
lcd_putchar(SRC+48);
|
202 |
lcd_putchar('|');
|
203 |
lcd_putchar(DEST+48);
|
204 |
lcd_putchar('|');
|
205 |
lcd_putchar(NUM_BOTS+48);
|
206 |
lcd_putchar('|');
|
207 |
lcd_putint(wl_to_death_count); |
208 |
lcd_putchar(')');
|
209 |
|
210 |
//print table
|
211 |
int y = 1; |
212 |
lcd_gotoxy(0, y);
|
213 |
int i, j;
|
214 |
|
215 |
for(i = 0; i < NUM_BOTS; i++) { |
216 |
for(j = 0; j < NUM_BOTS; j++) { |
217 |
lcd_putchar( getSelfSensor(i, j, NUM_BOTS) + 48);
|
218 |
lcd_putchar(' ');
|
219 |
} |
220 |
y++; |
221 |
lcd_gotoxy(0, y);
|
222 |
} |
223 |
} |
224 |
|
225 |
/*
|
226 |
\fn wl_timeout_handler
|
227 |
Handles the timeout case.
|
228 |
|
229 |
A time out occurs about every 1/4 second. This function is called each time
|
230 |
one occurs. In the case where a robot first turns on, it will wait for a
|
231 |
long time before declaring itself the leader. Otherwise, if enough
|
232 |
time-outs occur in a row, wl_to_flag will be set to 1. This will cause a
|
233 |
timeout packet to be sent next time around
|
234 |
|
235 |
*/
|
236 |
void wl_timeout_handler( void ) { |
237 |
//increment the total number of wireless time-outs
|
238 |
wl_to_count++; |
239 |
//lcd_putchar('w');
|
240 |
|
241 |
static int wl_first_to_count = 0; |
242 |
|
243 |
//first time time out routine - listen for a long time
|
244 |
if(first_time) {
|
245 |
if(wl_to_count > WL_TO_INITIAL){
|
246 |
//increment the counter for first timeouts
|
247 |
wl_first_to_count++; |
248 |
|
249 |
//lcd_putchar('Z');
|
250 |
|
251 |
//you don't actually want to send out a packet -- you would confuse
|
252 |
//other robots
|
253 |
wl_to_flag = 0;
|
254 |
wl_to_count = 0;
|
255 |
} |
256 |
}else{
|
257 |
//not the first time - regular time out routine
|
258 |
|
259 |
//if you have enough timeouts
|
260 |
if(wl_to_count > WL_TIMEOUT){
|
261 |
//lcd_putchar('z');
|
262 |
|
263 |
//change the time-out flag to 1
|
264 |
wl_to_flag = 1;
|
265 |
wl_to_count = 0;
|
266 |
|
267 |
//increment the count for robot death
|
268 |
if(NUM_BOTS > 1) { |
269 |
//only increase death count if there are robots that can die
|
270 |
//if numbots = 1, you are the only robot (no suicidal robots... yet)
|
271 |
wl_to_death_count++; |
272 |
} |
273 |
|
274 |
//check for a robot death
|
275 |
if(wl_to_death_count > WL_TO_DEATH) {
|
276 |
//a robot has died :(
|
277 |
wl_to_death_flag = 1;
|
278 |
wl_death_handler(); |
279 |
} |
280 |
} |
281 |
} |
282 |
|
283 |
//take care of the case where you time out so much that you become the leader
|
284 |
if(wl_first_to_count > WL_TO_LEADER) {
|
285 |
//you are now the leader
|
286 |
//lcd_putchar('L');
|
287 |
|
288 |
first_time = 0;
|
289 |
|
290 |
NUM_BOTS = 1; //there are (1) robot in the ring |
291 |
SRC = 0; //you are robot # 1 |
292 |
DEST = 1; //you are 'speaking' to (nonexistent) robot #1 |
293 |
|
294 |
lcd_putchar('[');
|
295 |
lcd_putchar(SRC+48);
|
296 |
lcd_putchar('|');
|
297 |
lcd_putchar(DEST+48);
|
298 |
lcd_putchar('|');
|
299 |
lcd_putchar(NUM_BOTS+48);
|
300 |
lcd_putchar('|');
|
301 |
lcd_putint(wl_to_death_count); |
302 |
lcd_putchar(']');
|
303 |
|
304 |
//create a a packet and send it
|
305 |
wl_create_packet(); |
306 |
wl_send(); |
307 |
|
308 |
//change the timeout count to 0
|
309 |
wl_to_count = 0;
|
310 |
wl_first_to_count = 0;
|
311 |
} |
312 |
} |
313 |
|
314 |
/**
|
315 |
\fn wl_error_handler(int errcode)
|
316 |
Handles error codes.
|
317 |
\param errcode The error code.
|
318 |
At the time, the only real error that happens is robot death.
|
319 |
|
320 |
Robot death requires that wl_buf have been set (either by receiving a
|
321 |
error packet or by calling wl_death_handler.
|
322 |
|
323 |
Robot death:
|
324 |
Number of robots will decrement.
|
325 |
Robots above the dead robot will decrement their ID and their source.
|
326 |
The loop remains closed.
|
327 |
|
328 |
*/
|
329 |
void wl_error_handler(unsigned char errcode) |
330 |
{ |
331 |
//which robot is dead
|
332 |
int dead_robot;
|
333 |
|
334 |
//print debug information
|
335 |
lcd_clear_screen(); |
336 |
lcd_gotoxy(0,0); |
337 |
lcd_putstr("error handler ");
|
338 |
lcd_putint(errcode); |
339 |
lcd_gotoxy(0,1); |
340 |
|
341 |
switch(errcode) {
|
342 |
case WL_ERRCODE_ROBOTDEATH:
|
343 |
lcd_putstr(" dead_robot: ");
|
344 |
lcd_putint(wl_buf[WL_ERR_DEAD_LOC]); |
345 |
break;
|
346 |
case WL_ERRCODE_NEEDTOCHARGE:
|
347 |
lcd_putstr(" charge_robot: ");
|
348 |
lcd_putint(wl_buf[WL_SRC_LOC]); |
349 |
break;
|
350 |
default:
|
351 |
break;
|
352 |
} |
353 |
|
354 |
lcd_gotoxy(0,2); |
355 |
|
356 |
//set all the time-out counts and flags to 0
|
357 |
wl_to_count = 0;
|
358 |
wl_to_flag = 0;
|
359 |
wl_to_death_flag = 0;
|
360 |
wl_to_death_count = 0;
|
361 |
|
362 |
//acknowledge receipt of the error packet by setting the errorcode in the
|
363 |
//packet to 0
|
364 |
wl_buf[WL_ERROR_LOC] = 0;
|
365 |
//also set checksum to !0
|
366 |
wl_chksum = 1;
|
367 |
|
368 |
//switch the error code
|
369 |
switch(errcode) {
|
370 |
//ROBOT DEATH
|
371 |
case WL_ERRCODE_ROBOTDEATH:
|
372 |
//get which robot has died
|
373 |
dead_robot = wl_buf[WL_ERR_DEAD_LOC]; |
374 |
|
375 |
//decrement the total number of robots
|
376 |
NUM_BOTS--; |
377 |
|
378 |
//see if you are above the dead robot
|
379 |
if( SRC > dead_robot ) {
|
380 |
//if you are the last robot (since NUM_ROBOTS was decremented,
|
381 |
//you can check that way) then decrement your number
|
382 |
//and set your destination to 0
|
383 |
if( SRC == NUM_BOTS) {
|
384 |
lcd_putchar('+');
|
385 |
lcd_putchar('1');
|
386 |
lcd_putchar('+');
|
387 |
SRC--; |
388 |
DEST = 0;
|
389 |
} else {
|
390 |
//otherwise decrement both your ID and the destination by 1
|
391 |
lcd_putchar('+');
|
392 |
lcd_putchar('2');
|
393 |
lcd_putchar('+');
|
394 |
//decrement src and dest
|
395 |
SRC--; |
396 |
DEST--; |
397 |
} |
398 |
} |
399 |
|
400 |
//ensure that the last robot talks to the 0th one
|
401 |
//this won't be set if the LAST robot dies (all robots are < dead)
|
402 |
if(SRC == (NUM_BOTS - 1) ) { |
403 |
DEST = 0;
|
404 |
} |
405 |
|
406 |
//now your SRC and DEST have been set properly
|
407 |
//if you are the robot before the dead robot - send a message
|
408 |
if(SRC == dead_robot) {
|
409 |
lcd_putstr(" send packet ");
|
410 |
//you took the place of the dead robot
|
411 |
//you start the token ring again
|
412 |
wl_create_packet(); |
413 |
wl_send(); |
414 |
} |
415 |
break;
|
416 |
|
417 |
case WL_ERRCODE_NEEDTOCHARGE:
|
418 |
if (CHARGESTATION == 1) { |
419 |
/*Turn on BOM for the length of time robots normally would have their
|
420 |
BOM on. This is effectively telling everyone where the charging
|
421 |
station is. Assuming only one charging station at the moment.
|
422 |
*/
|
423 |
bom_on(); |
424 |
delay_ms(WL_DELAY_BOM_PRE); |
425 |
wl_create_error_packet(WL_ERRCODE_CHARGESTATION); |
426 |
wl_send(); |
427 |
delay_ms(WL_DELAY_BOM_POST); |
428 |
bom_off(); |
429 |
} |
430 |
break; //Do nothing about this, yet |
431 |
|
432 |
case WL_ERRCODE_CHARGESTATION:
|
433 |
// If the Charging Station responds, look for where it's comming from and
|
434 |
//store that value for later
|
435 |
//wl_csloc = getMaxBOM();
|
436 |
break;
|
437 |
|
438 |
default:
|
439 |
//do other stuff;
|
440 |
break;
|
441 |
} |
442 |
} |
443 |
|
444 |
/**
|
445 |
\fn wl_death_handler
|
446 |
|
447 |
Handles robot death (for the one robot that detects death).
|
448 |
|
449 |
The robot that currently 'senses' robot death is the robot AFTER the dead
|
450 |
robot in the ring. It knows that PREV (the robot right before it) is dead.
|
451 |
Robot creates a error packet and sends it.
|
452 |
|
453 |
This will also call wl_error_handler since wl_buf was set with the current
|
454 |
dead robot
|
455 |
*/
|
456 |
void wl_death_handler( void ) |
457 |
{ |
458 |
//set time out and death count/flags to 0
|
459 |
wl_to_count = 0;
|
460 |
wl_to_flag = 0;
|
461 |
wl_to_death_flag = 0;
|
462 |
wl_to_death_count = 0;
|
463 |
|
464 |
//create a packet with the error
|
465 |
wl_create_error_packet(WL_ERRCODE_ROBOTDEATH); |
466 |
wl_buf[WL_ERR_DEAD_LOC] = PREV; //PREV is the robot that is dead
|
467 |
wl_make_checksum(); //Recompute checksum after adding data
|
468 |
|
469 |
//send the packet
|
470 |
wl_send(); |
471 |
|
472 |
//handle the error yourself
|
473 |
wl_error_handler(wl_buf[WL_ERROR_LOC]); |
474 |
|
475 |
return;
|
476 |
} |
477 |
|
478 |
/**
|
479 |
\fun parse_buffer
|
480 |
Parses the buffer in wl_buf.
|
481 |
|
482 |
Does nothing if the buffer isn't full.
|
483 |
*/
|
484 |
void parse_buffer(void) |
485 |
{ |
486 |
//deal with timeout case
|
487 |
if( wl_to_flag ) {
|
488 |
wl_to_flag = 0;
|
489 |
wl_create_packet(); |
490 |
wl_send(); |
491 |
return;
|
492 |
} |
493 |
|
494 |
//do nothing is packet is not complete
|
495 |
if( (wl_chksum != 0) || (wl_index != 0) ) { |
496 |
return;
|
497 |
} |
498 |
|
499 |
//acknowledge you take the packet by changing the chksum to nonzero
|
500 |
wl_chksum = 1;
|
501 |
|
502 |
if(wl_buf[WL_DATA_DATA1] == COLONET_REQUEST ||
|
503 |
wl_buf[WL_DATA_DATA1] == COLONET_COMMAND){ |
504 |
printf("colonet message received: code %d\n", wl_buf[WL_DATA_DATA2]);
|
505 |
colonet_handle_message(SRC, wl_buf); |
506 |
}else{
|
507 |
printf("\ndata1:%d\n", wl_buf[WL_DATA_DATA1]);
|
508 |
} |
509 |
|
510 |
if(first_time == 1) { |
511 |
//you received a first packet from someone
|
512 |
first_time = 0;
|
513 |
|
514 |
//get the current number of robots
|
515 |
NUM_BOTS = wl_buf[NUM_BOTS_LOC]; |
516 |
|
517 |
//you are now the last robot in the line
|
518 |
SRC = NUM_BOTS; |
519 |
//you are sending back to the first robot
|
520 |
DEST = 0;
|
521 |
|
522 |
//since you've just added yourself, increase numbots
|
523 |
NUM_BOTS++; |
524 |
|
525 |
//figure out a way to send out a packet TODO
|
526 |
//wl_wait_for_turn = 1;
|
527 |
|
528 |
//create and send a packet
|
529 |
wl_create_packet(); |
530 |
wl_send(); |
531 |
} |
532 |
|
533 |
//IS NOT CALLED FOR NOW
|
534 |
if(wl_wait_for_turn) {
|
535 |
if( wl_buf[WL_DEST_LOC] == (NUM_BOTS - 1) ) { |
536 |
//you just got a packet from the 'old' last robot send yours
|
537 |
//lcd_putchar('S');
|
538 |
wl_create_packet(); |
539 |
wl_send(); |
540 |
}else{
|
541 |
//otherwise just exit out of parse
|
542 |
return;
|
543 |
} |
544 |
} |
545 |
|
546 |
//check for error packet first
|
547 |
if(wl_buf[WL_DEST_LOC] == WL_PKT_ERROR){
|
548 |
//handle error packet
|
549 |
wl_error_handler( wl_buf[WL_ERROR_LOC] ); |
550 |
return;
|
551 |
} |
552 |
|
553 |
//see if there are more robots this turn around -- NUM_ROBOTS would have
|
554 |
//increased
|
555 |
if(wl_buf[NUM_BOTS_LOC] > NUM_BOTS){
|
556 |
//if you are the last robot
|
557 |
if(DEST == 0){ |
558 |
//if you are the last robot in the ring
|
559 |
//change your dest to the new number (the last bot)
|
560 |
DEST = NUM_BOTS; |
561 |
//lcd_putchar('j');
|
562 |
} |
563 |
|
564 |
//increase the number of robots to what it is in the incoming packet
|
565 |
NUM_BOTS = wl_buf[NUM_BOTS_LOC]; |
566 |
} |
567 |
|
568 |
//make sure packet isn't your own (shouldn't really happen)
|
569 |
if(wl_buf[WL_SRC_LOC] == SRC) {
|
570 |
//lcd_putchar('d');
|
571 |
return;
|
572 |
} |
573 |
|
574 |
//get the data out of the sensor row
|
575 |
int i = 0; |
576 |
int self = wl_buf[WL_SRC_LOC];
|
577 |
//13-4 = 9
|
578 |
int end = MIN(WL_DATA_ROW_END, NUM_BOTS+WL_DATA_ROW_START);
|
579 |
//lcd_putchar('s');
|
580 |
//lcd_putchar(self+48);
|
581 |
//lcd_putchar(':');
|
582 |
//lcd_putchar(end+48);
|
583 |
for(i = WL_DATA_ROW_START; i < end; i++){
|
584 |
addSensor(wl_buf[i], self, (i-WL_DATA_ROW_START), NUM_BOTS); |
585 |
} |
586 |
|
587 |
//if you are the destination - respond
|
588 |
if(wl_buf[WL_DEST_LOC] == SRC) {
|
589 |
//you know that you got a message addressed to you -- previous robot must
|
590 |
//not be dead
|
591 |
wl_to_death_count = 0;
|
592 |
//the robot previous to you is in wl_buf[WL_SRC_LOC]
|
593 |
PREV = wl_buf[WL_SRC_LOC]; |
594 |
|
595 |
//create a packet
|
596 |
//lcd_putchar('s');
|
597 |
wl_create_packet(); |
598 |
wl_send(); |
599 |
} |
600 |
|
601 |
return;
|
602 |
} |
603 |
|
604 |
/**
|
605 |
\fun wl_init
|
606 |
*/
|
607 |
void wl_init(void) |
608 |
{ |
609 |
lcd_putchar('~');
|
610 |
lcd_putchar(SRC+48);
|
611 |
lcd_putchar('~');
|
612 |
lcd_putchar(DEST+48);
|
613 |
lcd_putchar('~');
|
614 |
lcd_putchar(NUM_BOTS+48);
|
615 |
lcd_putchar('~');
|
616 |
|
617 |
buzzer_init(); |
618 |
buzzer_set_freq(C5); |
619 |
delay_ms(800);
|
620 |
buzzer_off(); |
621 |
|
622 |
wl_index = 0;
|
623 |
wl_chksum = 1;
|
624 |
wl_buf[0] = 'R'; |
625 |
wl_buf[1] = 'C'; |
626 |
|
627 |
/* executes the function about every 1/4 sec */
|
628 |
rtc_init(PRESCALE_DIV_128, 64, &wl_timeout_handler);
|
629 |
|
630 |
wl_to_flag = 0;
|
631 |
wl_to_count = 0;
|
632 |
wl_to_death_count = 0;
|
633 |
wl_to_death_flag = 0;
|
634 |
|
635 |
wl_to_max = WL_TO_INITIAL; |
636 |
first_time = 1;
|
637 |
wl_wait_for_turn = 0;
|
638 |
|
639 |
UCSR0B |= _BV(RXCIE) | _BV(RXEN); |
640 |
|
641 |
sei(); |
642 |
} |
643 |
|
644 |
void wl_send ( void ) { |
645 |
int i = 0; |
646 |
|
647 |
if(set_orb_wireless) {
|
648 |
orb_set_color(BLUE); |
649 |
} |
650 |
|
651 |
led_user(1);
|
652 |
|
653 |
if(SRC == (NUM_BOTS - 1) ) { |
654 |
//if you are the last robot
|
655 |
//delay for some time
|
656 |
if(set_orb_wireless) {
|
657 |
orb_set_color(RED); |
658 |
} |
659 |
delay_ms(LAST_ROBOT_DELAY); |
660 |
|
661 |
//warning: delay is actually 0 -- adding the delay back causes issues.
|
662 |
} |
663 |
|
664 |
//this is where you would turn on the BOM
|
665 |
bom_on(); |
666 |
delay_ms(WL_DELAY_BOM_PRE); |
667 |
for(i = 0; i < WL_PKT_LEN; i++) { |
668 |
serial_putchar(wl_buf[i]); |
669 |
serial1_putchar(wl_buf[i]); |
670 |
} |
671 |
|
672 |
delay_ms(WL_DELAY_BOM_POST); |
673 |
//this is where you would turn the BOM off
|
674 |
bom_off(); |
675 |
|
676 |
led_user(0);
|
677 |
//sprintf(buf, "%d\n\r", wl_buf[WL_CHK_LOC]);
|
678 |
//put_string(buf);
|
679 |
} |
680 |
|
681 |
void wl_create_packet() {
|
682 |
//Header for Colony Project
|
683 |
wl_buf[0] = 'R'; |
684 |
wl_buf[1] = 'C'; |
685 |
|
686 |
wl_buf[WL_SRC_LOC] = SRC; //Where the packet came from
|
687 |
wl_buf[WL_DEST_LOC] = DEST; //Who the packet is for
|
688 |
|
689 |
//Behavior Specific Data goes here
|
690 |
wl_buf[WL_DATA_DATA0] = 0;
|
691 |
wl_buf[WL_DATA_DATA1] = 0;
|
692 |
wl_buf[WL_DATA_DATA2] = 0;
|
693 |
|
694 |
//fill packet with data -- sensor row
|
695 |
for(int i = WL_DATA_ROW_START; i <= WL_DATA_ROW_END; i++) { |
696 |
wl_buf[i] = sensors[SRC][i - WL_DATA_ROW_START]; |
697 |
} |
698 |
|
699 |
//add the number of robots in there
|
700 |
wl_buf[NUM_BOTS_LOC] = NUM_BOTS; |
701 |
|
702 |
//create the checksum
|
703 |
wl_make_checksum(); |
704 |
} |
705 |
|
706 |
//Add custom data to the packets
|
707 |
void wl_create_data_packet(unsigned char d0, unsigned char d1, |
708 |
unsigned char d2) |
709 |
{ |
710 |
//Header for Colony Project
|
711 |
wl_buf[0] = 'R'; |
712 |
wl_buf[1] = 'C'; |
713 |
|
714 |
wl_buf[WL_SRC_LOC] = SRC; //Where the packet came from
|
715 |
wl_buf[WL_DEST_LOC] = DEST; //Who the packet is for
|
716 |
|
717 |
//Behavior Specific Data goes here
|
718 |
wl_buf[WL_DATA_DATA0] = d0; |
719 |
wl_buf[WL_DATA_DATA1] = d1; |
720 |
wl_buf[WL_DATA_DATA2] = d2; |
721 |
|
722 |
//fill packet with data -- sensor row
|
723 |
for(int i = WL_DATA_ROW_START; i <= WL_DATA_ROW_END; i++) { |
724 |
wl_buf[i] = sensors[SRC][i - WL_DATA_ROW_START]; |
725 |
} |
726 |
|
727 |
//add the number of robots in there
|
728 |
wl_buf[NUM_BOTS_LOC] = NUM_BOTS; |
729 |
|
730 |
//create the checksum
|
731 |
wl_make_checksum(); |
732 |
} |
733 |
|
734 |
//Send an error packet
|
735 |
void wl_create_error_packet(unsigned char errcode) |
736 |
{ |
737 |
//Header for Colony Project
|
738 |
wl_buf[0] = 'R'; |
739 |
wl_buf[1] = 'C'; |
740 |
|
741 |
//DEST is all robots
|
742 |
wl_buf[WL_SRC_LOC] = SRC; |
743 |
wl_buf[WL_DEST_LOC] = WL_PKT_ERROR; |
744 |
wl_buf[WL_ERROR_LOC] = errcode; |
745 |
|
746 |
//rest of the packet is just a bunch of 0s
|
747 |
for(int i = WL_ERR_DEAD_LOC + 1; i <= WL_DATA_END; i++) { |
748 |
wl_buf[i] = 0;
|
749 |
} |
750 |
|
751 |
//add the number of robots in there
|
752 |
wl_buf[NUM_BOTS_LOC] = NUM_BOTS; |
753 |
|
754 |
//create the checksum
|
755 |
wl_make_checksum(); |
756 |
} |
757 |
|
758 |
//Computes the checksum
|
759 |
void wl_make_checksum()
|
760 |
{ |
761 |
char checksum = 0; |
762 |
|
763 |
for(int i = WL_SRC_LOC; i < WL_CHK_LOC; i++) { |
764 |
checksum -= wl_buf[i]; |
765 |
} |
766 |
|
767 |
wl_buf[WL_CHK_LOC] = checksum; |
768 |
} |
769 |
|
770 |
//use on new avr-libc
|
771 |
//ISR(USART0_RX_vect)
|
772 |
SIGNAL(SIG_USART0_RECV) |
773 |
{ |
774 |
int max_bom;
|
775 |
|
776 |
wl_input = UDR0; |
777 |
|
778 |
//printf("%d ", wl_input);
|
779 |
|
780 |
if((wl_index == 0) && (wl_chksum != 0)){ |
781 |
//first packet? - check chksum to make sure we're not beginning
|
782 |
if( wl_input == 'R' ) { |
783 |
//got the first code
|
784 |
wl_index++; |
785 |
|
786 |
//if(set_orb_wireless) {
|
787 |
// orb_set_color(GREEN);
|
788 |
//}
|
789 |
//lcd_putchar('R');
|
790 |
//serial1_putchar('R');
|
791 |
|
792 |
wl_to_count = 0; //at this point we're not timing out, reset counter |
793 |
} |
794 |
return;
|
795 |
}else if( wl_index == 1 ){ |
796 |
if(wl_input == 'C') { |
797 |
wl_index++; |
798 |
wl_chksum = 0;
|
799 |
//lcd_putchar('C');
|
800 |
//serial1_putchar('C');
|
801 |
}else{
|
802 |
//incomplete packet header
|
803 |
wl_index = 0;
|
804 |
} |
805 |
return;
|
806 |
} |
807 |
|
808 |
if( wl_index >= WL_SRC_LOC ) {
|
809 |
if( wl_index < WL_CHK_LOC ) {
|
810 |
//getting the rest of the packet
|
811 |
wl_buf[wl_index] = wl_input; |
812 |
wl_chksum += wl_input; |
813 |
wl_index++; |
814 |
}else{
|
815 |
//we are at checksum location
|
816 |
wl_buf[wl_index] = 0;
|
817 |
wl_chksum += wl_input; |
818 |
wl_index = 0;
|
819 |
if(!wl_chksum) {
|
820 |
//checksum is correct - equal to zero
|
821 |
//if(set_orb_wireless) {
|
822 |
// orb_set_color(ORB_OFF);
|
823 |
//}
|
824 |
//lcd_putchar('p');
|
825 |
|
826 |
//get the maximum BOM from the person who sent you the packet
|
827 |
max_bom = getMaxBom(); |
828 |
//lcd_putint(max_bom);
|
829 |
//lcd_putchar(' ');
|
830 |
//add to your own sensor the other robot's direction
|
831 |
|
832 |
// max_bom you them
|
833 |
addSensor(max_bom, SRC, wl_buf[WL_SRC_LOC], NUM_BOTS); |
834 |
|
835 |
//also set whether that robot can see the light or not
|
836 |
//set_light_status(wl_buf[WL_SRC_LOC], wl_buf[WL_DATA_LIGHT_LOC]);
|
837 |
}else{
|
838 |
//chksum failed
|
839 |
//serial1_putchar('F');
|
840 |
//lcd_putchar('F');
|
841 |
} |
842 |
} |
843 |
} |
844 |
} |