Revision 1807 trunk/code/behaviors/formation_control/circle/circle.c

circle.c (revision 1807)
25 25
student representative Chris Mar.
26 26
	
27 27
   AUTHORS: James Carroll, Steve DeVincentis, Hanzhang (Echo) Hu, Nico Paris,
28
Joel Rey, Reva Street, Alex Zirbel	 						*/
28
Joel Rey, Reva Street, Alex Zirbel
29
 	*/
29 30

  
30 31

  
31 32
#include <dragonfly_lib.h>
......
49 50

  
50 51
   -Consider using the center bot to check distances
51 52

  
52
   -More testing is always good and necessary.					*/
53
   -More testing is always good and necessary.					
54
*/
53 55

  
54 56
/*** BOT LOG ***
55 57

  
56 58
   4-1-2010: BOT 7 as BEACON and BOT 1 as EDGE worked extremely well.
57 59
   4-2-2010: BOT 7 and BOT 14 worked extremely well, no matter states.  BOT 1
58
       	started well, but malfunctioned later.					        */
60
       	started well, but malfunctioned later.
61
        */
59 62

  
60 63
/*** TERMINOLOGY ***
61 64

  
62
	WAITINGSTATE:
63
	The robot waits to be given a signal to do something.  Wireless is on, in
64
		case the robot is called on to turn into an EDGE.  The color should be LIME
65
		or YELLOW-GREEN.
65
  WAITINGSTATE:
66
   The robot waits to be given a signal to do something.  Wireless is on,
67
in case the robot is called on to turn into an EDGE.  The color should be LIME
68
or YELLOW-GREEN.
66 69

  
67
	BEACON_CONTROL:
68
		The code that executes commands when a robot is turned to BEACON mode.  This
69
		code may run predefined methods for simplicity.  One goal is to make these
70
		methods change the robot turn to to BEACON_MACHINE mode for a while, and then
71
		return to the CONTROL code where they left off.
70
  BEACON_CONTROL:
71
   The code that executes commands when a robot is turned to BEACON mode.  This
72
code may run predefined methods for simplicity.  One goal is to make these
73
methods change the robot turn to to BEACON_MACHINE mode for a while, and then
74
return to the CONTROL code where they left off.
72 75

  
73
	EDGE_CONTROL:
74
		Like BEACON_CONTROL, executes whatever orders are required of the robot as an
75
		EDGE.
76
  EDGE_CONTROL:
77
   Like BEACON_CONTROL, executes whatever orders are required of the robot as an
78
EDGE.
76 79

  
77
	BEACON_MACHINE:
78
		A hardcoded list of functions which the robot is capable of running through.
79
		Consists of a finite state machine, where the robot executes a set of commands
80
		in a procedural manner and then returns to wherever it was in the control code.
80
  BEACON_MACHINE:
81
   A hardcoded list of functions which the robot is capable of running through.
82
Consists of a finite state machine, where the robot executes a set of commands
83
in a procedural manner and then returns to wherever it was in the control code.
81 84

  
82
	EDGE_MACHINE:
83
		Like the BEACON_MACHINE, but contains the same sort of procedural information
84
		for EDGE robots.
85
  EDGE_MACHINE:
86
   Like the BEACON_MACHINE, but contains the same sort of procedural information
87
for EDGE robots.
85 88

  
86
	END:
87
		A terminal state of the machine, where the robot just sits and waits.  The
88
		color should be GREEN and WHITE.
89
  END:
90
   A terminal state of the machine, where the robot just sits and waits.  The
91
color should be GREEN and WHITE.
89 92

  
90 93

  
91
	TYPES OF WIRELESS PACKETS:
92
		CIRCLE_ACTION_EXIST 'E'
93
		CIRCLE_ACTION_POSITION 'P'
94
		CIRCLE_ACTION_ACK 'A'
95
			A general acknowledgement package.
96
		CIRCLE_ACTION_DONE 'D'
97
			Used by robots to tell when they have finished their action.
98
		CIRCLE_ACTION_GOTYOU 'G'
99
			Used by the BEACON to tell a robot when it has been checked off.
100
			At this point, the EDGE has been recognized.  Used for times when
101
			all EDGE robots have to communicate to the center via the spam method.
102
		CIRCLE_ACTION_FORWARD 'F'
103
			The BEACON tells the rest of the robots to move forward.
104
		CIRCLE_CLAIM_CENTER 'C'
105
			Sent out by a robot when it takes over as BEACON.		*/
94
  TYPES OF WIRELESS PACKETS:
106 95

  
96
   CIRCLE_ACTION_EXIST 'E'
97
   CIRCLE_ACTION_POSITION 'P'
98
   CIRCLE_ACTION_ACK 'A'
99
 	A general acknowledgement package.
100
   CIRCLE_ACTION_DONE 'D'
101
 	Used by robots to tell when they have finished their action.
102
   CIRCLE_ACTION_GOTYOU 'G'
103
 	Used by the BEACON to tell a robot when it has been checked off.
104
 	At this point, the EDGE has been recognized.  Used for times when
105
 	all EDGE robots have to communicate to the center via the spam method.
106
   CIRCLE_ACTION_FORWARD 'F'
107
 	The BEACON tells the rest of the robots to move forward.
108
   CIRCLE_CLAIM_CENTER 'C'
109
 	Sent out by a robot when it takes over as BEACON.
110
 	*/
107 111

  
108 112

  
113
/* Define some variables to keep track of the state machine.*/
109 114
int END = 100;	
110
int WAITINGSTATE = 0;		/* Define some variables to keep track of the state machine.*/
115
int WAITINGSTATE = 0;
111 116
int EDGE_CONTROL = 1;
112 117
int BEACON_CONTROL = 2;
113 118
int EDGE_MACHINE = 3;
......
117 122
int CIRCLEUP = 1;
118 123
int ORIENT = 2;
119 124
int DRIVE = 3;
125
int TURNL = 4;
126
int TURNR = 5;
120 127

  
121 128
int currentPos = 0;
122 129
int state = 0;
123 130

  
131
// keep track of the speed and duration of group movements.
132
int speed = 20;
133
int duration = 2;
124 134

  
125 135
int timeout = 0;
126 136
int sending = 0;
......
144 154
	}
145 155
}
146 156

  
147
void forward(int speed){			// set the motors to this forward speed.
157
// set the motors to this forward speed.
158
void forward(int speed)
159
{		
148 160
	motor_l_set(FORWARD,speed);
149 161
	motor_r_set(FORWARD,speed);
150 162
}
151
void left(int speed){				// turn left at this speed.
163
// turn left at this speed.
164
void left(int speed)
165
{	
152 166
	motor_l_set(BACKWARD,speed);
153 167
	motor_r_set(FORWARD,speed);
154 168
}
155
void right(int speed){
169
void right(int speed)
170
{
156 171
	motor_l_set(FORWARD,speed);
157 172
	motor_r_set(BACKWARD,speed);
158 173
}
159
void stop(void){			// could be set to motors_off(), or just use this as an alternative.
160
	motor_l_set(BACKWARD,0);	// stop() is better - motors_off() creates a slight delay to turn them back on.
174
// stop() is better than motors_off(), which creates a slight delay when
175
// reactivating the motors.  Stop() is faster.
176
void stop(void)
177
{
178
	motor_l_set(BACKWARD,0);
161 179
	motor_r_set(FORWARD,0);
162 180
}
163
void setforward(int spd1, int spd2){
181
void setforward(int spd1, int spd2)
182
{
164 183
	motor_l_set(FORWARD,spd1);
165 184
	motor_r_set(FORWARD,spd2);
166 185
}
167
void backward(int speed){
186
void backward(int speed)
187
{
168 188
	motor_l_set(BACKWARD, speed);
169 189
	motor_r_set(BACKWARD, speed);
170 190
}
171
int get_distance(void){				// takes an averaged reading of the front rangefinder
172
	int temp,distance,kk=5;			// kk sets this to 5 readings.
191
// takes an averaged reading of the front rangefinder
192
int get_distance(void)
193
{
194
	// kk sets this to 5 readings.
195
	int temp,distance,kk=5;			
173 196
	distance =0;
174
	for (int i=0; i<kk; i++){
197
	for (int i=0; i<kk; i++)
198
	{
175 199
		temp = range_read_distance(IR2);
176 200
		if (temp == -1)
177 201
		{
......
208 232
}
209 233

  
210 234
/*
211
	Orients the robot so that it is facing the beacon (or the broadcasting BOM).
212
	
235
   Orients the robot so that it is facing the beacon (or the broadcasting BOM).
213 236
*/
214 237
void faceFront(void)
215 238
{
......
236 259
	return;
237 260
}
238 261

  
262
/*
263
   Turns the robot slowly to the right until it reaches the BOM reading goal.
264
   More stable code than what was implemented ealier, with smart turning,
265
   but slower.
266
*/
239 267
void aboutFace(int goal)
240 268
{
241 269
	int bomNum = -1;
242 270
	int speed = 170;	// speed with which to turn
243 271

  
244
	orb1_set_color(BLUE);			// BLUE and PURPLE
272
	orb1_set_color(BLUE);	// BLUE and PURPLE
245 273
	
246 274
	while(bomNum != goal)
247 275
	{
......
256 284

  
257 285

  
258 286
/* 
259
    BLINK the given number times
287
   BLINK the given number times
260 288
*/
261 289
void blink(int num)
262 290
{
......
271 299
}
272 300

  
273 301
/* 
274
    BLINK slowly the given number times
302
   BLINK slowly the given number times
275 303
*/
276 304
void slowblink(int num)
277 305
{
......
285 313
	orb_set_color(ORB_OFF);
286 314
}
287 315

  
316
/*
317
   A method for the higher-level code for the BEACON.  The beacon can make
318
   any of the preprogrammed commands, and this code sends the packet and
319
   transitions the robots correctly.
320
*/
288 321
void order(int action)
289 322
{
290 323
	currentPos++;
......
292 325
	state = 20 + action;
293 326
}
294 327

  
328
/*
329
   A method for the higher-level code for the BEACON.  The beacond sends
330
   not only the command, but also the speed and duration for which the
331
   (movement) command is to be executed.
332
*/
333
void orderMove(int action, int newSpeed, int newDuration)
334
{
335
	currentPos++;
336
	speed = newSpeed;
337
	duration = newDuration;
338
	send2(CIRCLE_EXECUTE, action);
339
	state = 20 + action;
340
}
341

  
342
/*
343
   Turns off the motors, sends an EXECUTE packet, and blinks green and white
344
   forever.
345
*/
295 346
void terminate(void)
296 347
{
348
	motors_off();
297 349
	send2(CIRCLE_EXECUTE, 100);
298 350
	orb_set_color(GREEN);
299 351
	orb2_set_color(WHITE);
......
301 353
}
302 354

  
303 355

  
356
//******************************************************************************
357
//******************************************************************************
358
//******************************************************************************
304 359

  
305 360

  
306
//*****************************************************************************************************************************************************************************************
307
//*****************************************************************************************************************************************************************************************
308
//*****************************************************************************************************************************************************************************************
309 361

  
310

  
311 362
/*
312
	A state machine with five states.  The robot starts out in WAITINGSTATE mode, from which
313
	it recieves a signal of some sort and moves to a different state.
363
   A state machine with five states.  The robot starts out in WAITINGSTATE mode,
364
from which it recieves a signal of some sort and moves to a different state.
314 365
*/
315 366
int main(void)
316 367
{
......
322 373
	wl_set_channel(24);
323 374

  
324 375
	int robotid = get_robotid();
325
	int centerid = 0;		// once the EDGE gets the first signal from a center, it stores who the center is.
326
	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
	for (int i=0; i<17; i++) used[i] = 0;		// initially, no robots in the group.
328 376

  
329
	int data_length;		// keeps track of the length of wireless packets received.
377
	// once the EDGE gets the first signal from a center, it stores who the 	// center is.
378
	int centerid = 0;
379

  
380
	// stores a list of bots which are in the group by storing a "1" in the
381
	// array if the robot of that index is in the group.	
382
	int used[17];
383
	int numOk;
384

  
385
	// initially, no robots in the group.
386
	for (int i=0; i<17; i++)
387
		used[i] = 0;
388

  
389
	// keeps track of the length of wireless packets received.
390
	int data_length;
330 391
	unsigned char *packet_data=wl_basic_do_default(&data_length);
331
	
332
	int beacon_State=0;		// these variables keep track of the inner state machines in the procedural MACHINE states.
392

  
393
	// these variables keep track of the inner state machines in the
394
	//  procedural MACHINE states.	
395
	int beacon_State=0;
333 396
	int edge_State=0;
334 397

  
335 398
	int waitingCounter=0;
336
	int robotsReceived=0;		// an important variable that stores the size of the group.
337
	int offset = 20;		// offset for the approaching: how far off the rangefinders can be
399
	
400
	// an important variable that stores the size of the group.
401
	int robotsReceived=0;
402
	
403
	// offset for the approaching: how far off the rangefinders can be
404
	int offset = 20;
338 405
	int time=0;
339
	int direction = 4;		// keeps track of which way robots are facing relative to the center
340
	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
						// right distance away.
342
	int onefoot = 250;		// how far away to stop.
406

  
407
	// keeps track of which way robots are facing relative to the center
408
	int direction = 4;
409

  
410
	// how far away the robot is.  Initialized to a large value to ensure
411
	// that the robot doesn't think it is already the right distance away.
412
	int distance=1000;
413
	int onefoot = 250;	// how far away to stop.
343 414
	
344 415
	while(1)
345 416
	{
346 417
		bom_refresh(BOM_ALL);
347 418

  
348
				/*		
349
				*******EXPECTED MOVES **********   (OUT OF DATE.  Will be updated once changes have been made.)
350
				The designed movement:
351
				 1. one center robot, several edge robots are on;
352
				 2. center robots: button 1 is pressed;
353
				 3. center robots: send global package telling edges that he exists;
354
				 4. EDGE robots response with ACK. 
355
				 5. EDGE robots wait for center robots to finish counting (DONE package)
356
				 6. EDGE robtos approach the center robtot and stop at the "onefoot" distance, send message to the center
357
				*/
419
	/***EXPECTED MOVES***
420
	   (OUT OF DATE.  Will be updated once changes have been made.)
421
	The designed movement:
422
	 1. one center robot, several edge robots are on;
423
	 2. center robots: button 1 is pressed;
424
	 3. center robots: send global package telling edges that he exists;
425
	 4. EDGE robots response with ACK. 
426
	 5. EDGE robots wait for center robots to finish counting (DONE package)
427
	 6. EDGE robtos approach the center robtot and stop at the "onefoot"
428
		 distance, send message to the center
429
		*/
358 430
		
359 431
		
360
		/* This is the MAIN SWITCH LOOP, which governs the overall status of the robot. */
432
		/*
433
		  This is the MAIN SWITCH LOOP, which governs the overall
434
		  status of the robot.
435
		 */
361 436
		switch(state)
362 437
		{
363 438

  
364 439

  
365
			/*
366
				The WAITINGSTATE.  This state constantly checks for wireless packets,
367
				and updates its state as soon as it receives a signal.
368
			*/
369
			case 0:
440
		/*
441
		The WAITINGSTATE.  This state constantly checks for wireless
442
		packets,
443
		and updates its state as soon as it receives a signal.
444
		*/
445
		case 0:
370 446

  
371
				orb_set_color(YELLOW);
372
				packet_data=wl_basic_do_default(&data_length);
373
				if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_CLAIM_CENTER)
374
				{
375
					centerid = packet_data[1];
447
			orb_set_color(YELLOW);
448
			packet_data=wl_basic_do_default(&data_length);
449
			if(packet_data != 0 && data_length>=2
450
				&& packet_data[0]==CIRCLE_CLAIM_CENTER)
451
			{
452
				centerid = packet_data[1];
453
				state = 1;
454
			}
376 455

  
377
					state = 1;
378
				}
456
			if(button1_read())
457
			{
458
				// becomes the center if button1 is clicked.
459
				send2(CIRCLE_CLAIM_CENTER, robotid); 	
460
				state = 2;
461
			}
462
		break;
379 463

  
380
				if(button1_read())
381
				{
382
					send2(CIRCLE_CLAIM_CENTER, robotid); 	// becomes the center if button1 is clicked.
383
					state = 2;
384
				}
385 464

  
386
			break;
387 465

  
466
//******************************************************************************
467
//******************************************************************************
388 468

  
389 469

  
390
//***********************************************************************************************************************************************************************************
470
		/*
471
		The CONTROL for the EDGE state.  This sets a certain procedure
472
		to follow, in the form of simple
473
		commands, for a robot to follow if it is set to an EDGE.
474
		*/
391 475

  
476
		case 1:
477
			orb_set_color(CYAN);
478
			orb1_set_color(YELLOW);
392 479

  
480
			int command = -1;
481
			
482
			packet_data=wl_basic_do_default(&data_length);
393 483

  
394
			/*
395
				The CONTROL for the EDGE state.  This sets a certain procedure to follow, in the form of simple
396
				commands, for a robot to follow if it is set to an EDGE.
397
			*/
484
			if(packet_data != 0 && data_length>=2 &&
485
			   packet_data[0]==CIRCLE_EXECUTE)
486
			{
487
				command = packet_data[1];
488
			}
398 489

  
399
			case 1:
400
				orb_set_color(CYAN);
401
				orb1_set_color(YELLOW);
402

  
403
				int command = -1;
404
				
405
				packet_data=wl_basic_do_default(&data_length);
406
				if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_EXECUTE)
490
			if(command != -1)
491
			{
492
				edge_State = 0;
493
				switch(command)
407 494
				{
408
					command = packet_data[1];
409
				}
495
				case 0:
496
					state = 10; break;
410 497

  
411
				if(command != -1)
412
				{
413
					edge_State = 0;
414
					switch(command)
415
					{
416
						case 0:
417
							state = 10; break;
498
				case 1:
499
					state = 11; break;
418 500

  
419
						case 1:
420
							state = 11; break;
501
				case 2:
502
					state = 12; break;
421 503

  
422
						case 2:
423
							state = 12; break;
504
				case 3:
505
					state = 13; break;
424 506

  
425
						case 3:
426
							state = 13; break;
507
				case 4:
508
					state = 14; break;
427 509

  
428
						case 100:
429
							terminate(); break;
430
					}
510
				case 5:
511
					state = 15; break;
512

  
513
				case 100:
514
					terminate(); break;
431 515
				}
516
			}
432 517

  
433
			break;
518
		break;
434 519

  
435 520

  
436 521

  
437
//***********************************************************************************************************************************************************************************
522
//******************************************************************************
523
//******************************************************************************
438 524

  
439 525

  
526
		/*
527
		The CONTROL for the BEACON state.  This sets a certain procedure
528
		to follow, in the form of simple commands, for a robot to follow
529
		if it is set to a BEACON.
530
		*/
531
		case 2:
532
			orb_set_color(PURPLE);
533
			beacon_State = 0;
440 534

  
441
			/*
442
				The CONTROL for the BEACON state.  This sets a certain procedure to follow, in the form of simple
443
				commands, for a robot to follow if it is set to a BEACON.
444
			*/
445
			case 2:
446
				orb_set_color(PURPLE);
447
				beacon_State = 0;
448
				
449
				switch(currentPos)
450
				{
451
					case 0:
452
						order(COUNT);	break;
535
			switch(currentPos)
536
			{
537
			case 0:
538
				order(COUNT);	break;
453 539

  
454
					case 1:
455
						order(CIRCLEUP); break;
540
			case 1:
541
				order(CIRCLEUP); break;
456 542

  
457
					case 2:
458
						order(ORIENT); break;
543
			case 2:
544
				order(ORIENT); break;
459 545

  
460
					case 3:
461
						order(DRIVE); break;
546
			case 3:
547
				orderMove(TURNL,20,2); break;
462 548

  
463
					case 4:
464
						terminate(); break;
465
				}
549
			case 4:
550
				terminate(); break;
551
			}
466 552
				
467
			break;
553
		break;
468 554

  
469 555

  
556
//******************************************************************************
557
//******************************************************************************
470 558

  
471
//***********************************************************************************************************************************************************************************
472 559

  
560
	/* The following states are MACHINE states for the EDGE robot. */
473 561

  
474
			/* The following states are MACHINE states for the EDGE robot. */
562
		/*
563
			EDGE on COUNT
564
		*/
565
		case 10:	
475 566

  
476
			/*
477
				EDGE on COUNT
478
			*/
479
			case 10:	
567
			switch(edge_State)
568
			{
569
				/*
570
				0. EDGE robots are on. 
571
				1. They are waiting for EXIST pacakage from the
572
					Center robots
573
				2. After they receive the package, they send ACK
574
					package to center.
575
				3. Done for now: display green.
576
				*/
577
			case 0:
578
				bom_off();
579
				orb1_set_color(YELLOW);
580
				orb2_set_color(BLUE);
581
				packet_data=wl_basic_do_default(&data_length);
480 582

  
481

  
482
				switch(edge_State)
583
				if(packet_data != 0 && data_length>=2 &&
584
				   packet_data[0]==CIRCLE_ACTION_EXIST)
483 585
				{
484
					/*
485
						0. EDGE robots are on. 
486
						1. They are waiting for EXIST pacakage from the Center robots
487
						2. After they receive the package, they send ACK package to center.
488
						3. Done for now: display green.
489
					*/
490
					case 0:
491
						bom_off();
492
						orb1_set_color(YELLOW);
493
						orb2_set_color(BLUE);
494
						packet_data=wl_basic_do_default(&data_length);
495
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_EXIST)
496
						{
497
							centerid = packet_data[1];
586
					centerid = packet_data[1];
498 587

  
499
							send2(CIRCLE_ACTION_ACK,robotid);
588
					send2(CIRCLE_ACTION_ACK,robotid);
500 589

  
501
							edge_State=1;
502
						}
503
					break;
504
					/*
505
						1. Wait for DONE package 
506
						2. The counting process is DONE
507
					*/
508
					case 1:		
590
					edge_State=1;
591
				}
592
			break;
593

  
594
			/*
595
				1. Wait for DONE package 
596
				2. The counting process is DONE
597
			*/
598
			case 1:		
509 599
					
510
						orb_set_color(YELLOW);
511
						orb2_set_color(PURPLE);
600
				orb_set_color(YELLOW);
601
				orb2_set_color(PURPLE);
512 602

  
513
						send2(CIRCLE_ACTION_ACK,robotid);		// keep sending the packet until we get a response
603
				// keep sending the packet until we get a
604
				// response
605
				send2(CIRCLE_ACTION_ACK,robotid);
514 606
						
515
						packet_data=wl_basic_do_default(&data_length);
516
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_GOTYOU && packet_data[1] == robotid)
517
						{
518
							edge_State=2;
519
						}
520
					break;
607
				packet_data=wl_basic_do_default(&data_length);
608
				if(packet_data != 0 && data_length>=2 &&
609
				   packet_data[0]==CIRCLE_ACTION_GOTYOU &&
610
				   packet_data[1] == robotid)
611
				{
612
					edge_State=2;
613
				}
614
			break;
521 615

  
522
					case 2:	// wait for the second, general, done packet.
616
			// wait for the second, general, done packet.
617
			case 2:	
523 618

  
524
						orb_set_color(YELLOW);
525
						packet_data=wl_basic_do_default(&data_length);
526
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE && packet_data[1] == centerid)
527
						{
528
							state = 1;
529
						}
530
					break;
619
				orb_set_color(YELLOW);
620
				packet_data=wl_basic_do_default(&data_length);
621
				if(packet_data != 0 && data_length>=2 &&
622
				   packet_data[0]==CIRCLE_ACTION_DONE &&
623
				   packet_data[1] == centerid)
624
				{
625
					state = 1;
531 626
				}
532

  
533 627
			break;
628
			}
534 629

  
535
			/* The CIRCLEUP command for EDGE */
630
		break;
536 631

  
537
			case 11:
632
		/* The CIRCLEUP command for EDGE */
538 633

  
539
				switch(edge_State)
540
				{
634
		case 11:
635

  
636
			switch(edge_State)
637
			{
541 638
					
542
					case 0:
543
						// COLOR afer DONE ---> MAGENTA
544
						orb_set_color(MAGENTA);
545
						faceFront();			// turn to face the beacon
546
						forward(175);
547
						//range_init();
639
			case 0:
640
				// COLOR afer DONE ---> MAGENTA
641
				orb_set_color(MAGENTA);
642
				// turn to face the beacon
643
				faceFront();
644
				forward(175);
645
				//range_init();
548 646
						
549 647
						
550
						distance = get_distance();
648
				distance = get_distance();
649
				time=0;
650
				while ((distance-offset)>=onefoot ||
651
				   distance==0 || (distance+offset)<onefoot)
652
				{
653
					if(distance==0)
654
						orb_set_color(WHITE);
655
					else if(distance-offset>=onefoot)
656
						forward(175);
657
					else
658
						backward(175);
659
					distance = get_distance();
660
					delay_ms(14);
661
					time+=14;
662
					if(time>50)
663
					{
664
						faceFront();
551 665
						time=0;
552
						while ((distance-offset)>=onefoot || distance==0 || (distance+offset)<onefoot)
553
						{
554
							if(distance==0)
555
								orb_set_color(WHITE);
556
							else if(distance-offset>=onefoot)
557
								forward(175);
558
							else
559
								backward(175);
560
							distance = get_distance();
561
							delay_ms(14);
562
							time+=14;
563
							if(time>50)
564
							{
565
								faceFront;
566
								time=0;
567
							}
568
						}
666
					}
667
				}
569 668
							
570
						stop();
571
						orb_set_color(GREEN);
669
				stop();
670
				orb_set_color(GREEN);
572 671

  
573
						send2(CIRCLE_ACTION_ACK, robotid);
672
				send2(CIRCLE_ACTION_ACK, robotid);
574 673

  
575
						stop();
576
						state = 1;
577
					break;
674
				stop();
675
				state = 1;
676
			break;
677
			}
578 678

  
579
				}
580 679

  
581

  
582
			break;
680
		break;
583 681
		
584
			/* An ORIENT series of steps for the EDGE robot. */
682
		/* An ORIENT series of steps for the EDGE robot. */
585 683

  
586
			case 12:
684
		case 12:
587 685
			
686
			switch(edge_State)
687
			{
588 688

  
589
				switch(edge_State)
689
			// waits for a packet to tell it to turn on the bom.
690
			case 0:
691
				packet_data=wl_basic_do_default(&data_length);
692
				if(packet_data != 0 && data_length==2 &&
693
				   packet_data[0]==CIRCLE_ACTION_GOTYOU &&
694
				   packet_data[1] == robotid)
590 695
				{
696
					bom_on();
697
					orb_set_color(ORANGE);
698
					send2(CIRCLE_ACTION_ACK,centerid);
699
					edge_State = 1;
700
				}
701
			break;
591 702

  
592
					// waits for a packet to tell it to turn on the bom.
593
					case 0:
594
						packet_data=wl_basic_do_default(&data_length);
595
						if(packet_data != 0 && data_length==2 && packet_data[0]==CIRCLE_ACTION_GOTYOU && packet_data[1] == robotid)
596
						{
597
							bom_on();
598
							orb_set_color(ORANGE);
599
							send2(CIRCLE_ACTION_ACK,centerid);
600
							edge_State = 1;
601
						}
602
					break;
703
			// waits for a packet to tell it that it has been
704
			// received.
705
			case 1:
706
				orb2_set_color(YELLOW);
707
				packet_data=wl_basic_do_default(&data_length);
708
				if(packet_data != 0 && data_length==3 &&
709
				   packet_data[0]==CIRCLE_ACTION_GOTYOU &&
710
				   packet_data[1] == robotid)
711
				{
712
					bom_off();
713
					direction = packet_data[2];
714
					orb_set_color(YELLOW);
715
					edge_State = 2;
716
				}
717
			break;
603 718

  
604
					// waits for a packet to tell it that it has been received.
605
					case 1:
606
						orb2_set_color(YELLOW);
607
						packet_data=wl_basic_do_default(&data_length);
608
						if(packet_data != 0 && data_length==3 && packet_data[0]==CIRCLE_ACTION_GOTYOU && packet_data[1] == robotid)
609
						{
610
							bom_off();
611
							direction = packet_data[2];
612
							orb_set_color(YELLOW);
613
							edge_State = 2;
614
						}
615
					break;
719
			/*
720
			 Wait for the center bot to send a DONE packet; then
721
			 turn to face the right direction.
722
			*/
723
			case 2:
724
				orb_set_color(GREEN);
725
				packet_data=wl_basic_do_default(&data_length);
726
				if(packet_data != 0 && data_length>=2 &&
727
				   packet_data[0]==CIRCLE_ACTION_DONE)
728
				{
729
					orb_set_color(WHITE);
730
					orb2_set_color(CYAN);
731
					edge_State = 3;
732
				}
733
			break;
616 734

  
617
					/* Wait for the center bot to send a DONE packet; then turn to face the right direction. */
618
					case 2:
619
						orb_set_color(GREEN);
620
						packet_data=wl_basic_do_default(&data_length);
621
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE)
622
						{
623
							orb_set_color(WHITE);
624
							orb2_set_color(CYAN);
625
							edge_State = 3;
626
						}
627
					break;
735
			/* Turn until we reach the right direction */
736
			case 3:
737
				aboutFace(direction);
738
				stop();
739
				orb_set_color(YELLOW);
740
				send2(CIRCLE_ACTION_DONE,robotid);
741
				state = 1;
742
			break;
628 743

  
629
					/* Turn until we reach the right direction (DIRECTION) */
630
					case 3:
631
						aboutFace(direction);
632
					break;
744
			}
633 745

  
634
				}
746
		break;
635 747

  
636 748

  
637
			break;
749
		/* The DRIVE steps for the EDGE robot */
638 750

  
751
		case 13:
639 752

  
640
			/* The MOVE steps for the EDGE robot */
753
			switch(edge_State)
754
			{
755
			
756
			/* Wait for the command to move forward. */
757
			case 0:
758
				packet_data=wl_basic_do_default(&data_length);
759
				if(packet_data != 0 && data_length>=3 &&
760
				   packet_data[0]==CIRCLE_ACTION_FORWARD)
761
				{
762
					orb_set_color(BLUE);
763
					forward(packet_data[1]*10);
764
					delay_ms(packet_data[2]*1000);
765
					stop();
766
					state = 1;
767
				}
768
			break;
641 769

  
642
			case 13:
643 770

  
644
				switch(edge_State)
645
				{
646
				
647
					/* Wait for the command to move forward. */
648
					case 0:
649
						packet_data=wl_basic_do_default(&data_length);
650
						if(packet_data != 0 && data_length>=3 && packet_data[0]==CIRCLE_ACTION_FORWARD)
651
						{
652
							orb_set_color(BLUE);
653
							forward(packet_data[1]*10);
654
							delay_ms(packet_data[2]*1000);
655
							edge_State = 1;
656
						}
657
					break;
771
			}
658 772

  
659
					/* Terminal. */
660
					case 1:
661
						stop();
662
						state = 1;
663
					break;
773
		break;
664 774

  
775
		/* The TURNL steps for the EDGE robot */
776
		case 14:
777
			orb_set_color(RED);
665 778

  
666
				}	// end the EdgeState switch
779
			/* Wait for specifications for the turn. */
667 780

  
668
			break;		// break the Edge state in the main switch loop
669
				
670
			// END for EDGE robots
671
			
781
			packet_data=wl_basic_do_default(&data_length);
782
			if(packet_data != 0 && data_length>=3 &&
783
			   packet_data[0]==CIRCLE_ACTION_TURN)
784
			{
785
				orb_set_color(BLUE);
672 786

  
787
				left(packet_data[1]*10);
788
				delay_ms(packet_data[2]*1000);
789
				stop();
790
				state = 1;
791
			}
792
		break;
673 793

  
794
		/* The TURNR steps for the EDGE robot */
795
		case 15:
796
			orb_set_color(RED);
674 797

  
798
			/* Wait for specifications for the turn. */
675 799

  
800
			packet_data=wl_basic_do_default(&data_length);
801
			if(packet_data != 0 && data_length>=3 &&
802
			   packet_data[0]==CIRCLE_ACTION_TURN)
803
			{
804
				orb_set_color(BLUE);
676 805

  
677
//***********************************************************************************************************************************************************************************
806
				right(packet_data[1]*10);
807
				delay_ms(packet_data[2]*1000);
808
				stop();
809
				state = 1;
810
			}
811
		break;
812
				
813
	// END for EDGE robots
814
			
678 815

  
679 816

  
817
//******************************************************************************
818
//******************************************************************************
680 819

  
681 820

  
682
			/*
683
			   The MACHINE for the BEACON state
684
			*/
821
		/*
822
		   The MACHINE for the BEACON state
823
		*/
685 824

  
686
			/* the COUNT code for the BEACON */
687
			case 20:
688
				switch(beacon_State) 
689
				{
825
		/* the COUNT code for the BEACON */
826
		case 20:
827
			switch(beacon_State) 
828
			{
690 829

  
691
					/* 0. center  robots on wait for pressing button 1 */
692
					case 0:
693
						bom_on();
694
						orb_set_color(BLUE);
695
						robotsReceived = 0;
696
						beacon_State=1;
697
					break;	
830
			/* 0. center  robots on wait for pressing button 1 */
831
			case 0:
832
				bom_on();
833
				orb_set_color(BLUE);
834
				robotsReceived = 0;
835
				beacon_State=1;
836
			break;	
698 837

  
699
					/* 1. Send EXIST package to EDGE robots */
700
					case 1:
701
						orb_set_color(RED);
702
						send2(CIRCLE_ACTION_EXIST,robotid);
703
						beacon_State=2;
704
					break;
838
			/* 1. Send EXIST package to EDGE robots */
839
			case 1:
840
				orb_set_color(RED);
841
				send2(CIRCLE_ACTION_EXIST,robotid);
842
				beacon_State=2;
843
			break;
705 844

  
706
					/* 2. Count the number of the EDGE robots *******NOTE: at most  1000  times of loop ******  */
707
					case 2:
708
						waitingCounter++;
709
						orb1_set_color(YELLOW);
710
						orb2_set_color(BLUE);
711
						packet_data=wl_basic_do_default(&data_length);
845
			/* 2. Count the number of the EDGE robots
846
			 *******NOTE: at most  1000  times of loop ******  */
847
			case 2:
848
				waitingCounter++;
849
				orb1_set_color(YELLOW);
850
				orb2_set_color(BLUE);
851
				packet_data=wl_basic_do_default(&data_length);
712 852
					
713
						if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
714
						{
715
							orb_set_color(RED);
716
							orb2_set_color(BLUE);
717
							//only add to robots seen if you haven't gotten an ACK from this robot
718
							if(used[packet_data[1]]==0)
719
							{
720
								robotsReceived++;
721
								used[packet_data[1]] = 1;
853
				if(packet_data!=0 && data_length>=2 &&
854
				   packet_data[0]==CIRCLE_ACTION_ACK)
855
				{
856
					orb_set_color(RED);
857
					orb2_set_color(BLUE);
858
					// only add to list seen if you haven't
859
					// gotten an ACK from this robot
860
					if(used[packet_data[1]]==0)
861
					{
862
						robotsReceived++;
863
						used[packet_data[1]] = 1;
722 864

  
723
								usb_puts("Added: ");
724
								usb_puti(packet_data[1]);
725
								usb_puts("\r\n");
726
							}
865
						usb_puts("Added: ");
866
						usb_puti(packet_data[1]);
867
						usb_puts("\r\n");
868
					}
727 869

  
728
							// NEW: sends a packet to each robot it receives telling them to be done.
729
							send2(CIRCLE_ACTION_GOTYOU,packet_data[1]);
730
						}
731
						if(waitingCounter >= 300){
732
							beacon_State=3;
733
						}
734
					break;
735

  
736
					/* COUNTing is DONE.  Sending DONE package. */	
737
					case 3:
738
						blink(robotsReceived);
739
						orb_set_color(GREEN);
740
						send2(CIRCLE_ACTION_DONE, robotid);
741
						state = 2;
742
					break;
870
					// NEW: sends a packet to each robot it
871
					// receives telling them to be done.
872
					send2(CIRCLE_ACTION_GOTYOU,
873
						packet_data[1]);
743 874
				}
875
				if(waitingCounter >= 300)
876
				{
877
					beacon_State=3;
878
				}
879
			break;
744 880

  
881
			/* COUNTing is DONE.  Sending DONE package. */	
882
			case 3:
883
				blink(robotsReceived);
884
				orb_set_color(GREEN);
885
				send2(CIRCLE_ACTION_DONE, robotid);
886
				state = 2;
745 887
			break;
888
			}
746 889

  
747
			/* The CIRCLEUP method for BEACON */
748
			case 21:
890
		break;
749 891

  
750
				switch(beacon_State)
892
		/* The CIRCLEUP method for BEACON */
893
		case 21:
894

  
895
			switch(beacon_State)
896
			{
897

  
898
			/* Wait for all the robots to get to right distance */
899
			case 0: 
900
				left(170);
901
				orb1_set_color(YELLOW);
902
				orb2_set_color(WHITE);
903
			
904
				numOk = 0;
905
			
906
				while(numOk<robotsReceived)
751 907
				{
752

  
753
					/* Wait for all the robots to get to right distance/position */
754
					case 0: 
755
						left(170);
756
						orb1_set_color(YELLOW);
757
						orb2_set_color(WHITE);
908
					packet_data=
909
					   wl_basic_do_default(&data_length);
910
					if(packet_data!=0 && data_length>=2 &&
911
					   packet_data[0]==CIRCLE_ACTION_ACK)
912
					{
913
						numOk++;
914
					}
915
				}
758 916
					
759
						int numOk = 0;
760
					
761
						while(numOk<robotsReceived)
762
						{
763
							packet_data=wl_basic_do_default(&data_length);
764
							if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
765
							{
766
								numOk++;
767
							}
768
						}
769
					
770
						state = 2;
771
					break;
772
				}
773

  
917
				state = 2;
774 918
			break;
919
			}
775 920

  
921
		break;
776 922

  
777
			/* The ORIENT code for the beacon */
778
			case 22:
779 923

  
780
				switch(beacon_State)
924
		/* The ORIENT code for the beacon */
925
		case 22:
926

  
927
			switch(beacon_State)
928
			{
929
			/* Turns all the robots in the same direction */
930
			case 0:
931
				stop();
932
				bom_off();
933
				orb_set_color(ORANGE);
934
						
935
				// for each robot, tells them to turn their bom
936
				// on, then tells them which way to face.
937
				for(int i=0; i < 17; i++)
781 938
				{
782
					/* Turns all the robots in the same direction */
783
					case 0:
784
						stop();
785
						bom_off();
939
				    if(used[i] == 1)
940
				    {
941
					send2(CIRCLE_ACTION_GOTYOU, i);
942
					// waits for a response so it knows the
943
					// BOM is on.
944
					while(1)
945
					{
946
					    orb_set_color(RED);
947
					    orb2_set_color(WHITE);
948
					    packet_data=wl_basic_do_default(
949
						&data_length);
950
					    if(packet_data!=0 && data_length>=2
951
						&& packet_data[0]==
952
						CIRCLE_ACTION_ACK)
953
					    {
786 954
						orb_set_color(ORANGE);
787
						
788
						// for each robot, tells them to turn their bom on, then tells them which way they should face.
789
						for(int i=0; i < 17; i++)
790
						{
791
							if(used[i] == 1)
792
							{
793
								send2(CIRCLE_ACTION_GOTYOU, i);
794
								while(1)	// waits for a response so it knows the BOM is on.
795
								{
796
									orb_set_color(RED);
797
									orb2_set_color(WHITE);
798
									packet_data=wl_basic_do_default(&data_length);
799
									if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
800
									{
801
										orb_set_color(ORANGE);
802
										break;
803
									}
804
								}
955
						break;
956
					    }
957
					}
958
					delay_ms(20);
959
					bom_refresh(BOM_ALL);
960
					direction = bom_get_max();
961
				
962
					direction += 8;
963
					if(direction > 15) direction -= 16;
805 964

  
806
								bom_refresh(BOM_ALL);
807
								direction = bom_get_max();
808
								direction += 8;
809
								if(direction > 15) direction -= 16;
810
								send3(CIRCLE_ACTION_GOTYOU, i, direction);
811
								delay_ms(20);
812
							}
813
						}
814
						beacon_State = 1;
815
					break;
965
					delay_ms(20);
816 966
			
817
					/* Sends a DONE packet to signify that it has read in all the robots' directions and sent packets.
818
						Edge robots should now turn to face the right direction. */
819
					case 1:
820
						send2(CIRCLE_ACTION_DONE,robotid);
821
						bom_on();
822
						state = 2;
823
					break;
967
					send3(CIRCLE_ACTION_GOTYOU, i,
968
					     direction);
969
		
970
					delay_ms(20);
971
				    }
824 972
				}
973
				beacon_State = 1;
974
			break;
975
			
976
			/*
977
			Sends a DONE packet to signify that it has read in all
978
			the robots' directions and sent packets.
979
			Edge robots should now turn to face the right direction.
980
			*/
981
			case 1:
982
				send2(CIRCLE_ACTION_DONE,robotid);
983
				bom_on();
984
				beacon_State = 2;
985
			break;
986
			
987
			case 2:
988
				numOk = 0;
825 989

  
990
				while(numOk < robotsReceived)
991
				{
992
					orb_set_color(ORANGE);
993
					packet_data=wl_basic_do_default(
994
					   &data_length);
995

  
996
					if(packet_data!=0 && data_length>=2 &&
997
					   packet_data[0]==CIRCLE_ACTION_DONE)
998
					{
999
						numOk++;
1000
					}
1001
				}
1002
				state = 2;
826 1003
			break;
1004
			}
827 1005

  
1006
		break;
828 1007

  
829
			/* The DRIVE code for the beacon */
830
			case 23:
831 1008

  
832
				switch(beacon_State)
833
				{
1009
		/* The DRIVE code for the beacon */
1010
		case 23:
834 1011

  
835
					/* Tells the robots to move forward and moves itself. */
836
					case 0:
837
						orb_set_color(YELLOW);
838
						delay_ms(5000);
1012
			switch(beacon_State)
1013
			{
839 1014

  
840
						// format: type of ack, speed divided by 10, time in seconds.
841
						send3(CIRCLE_ACTION_FORWARD,20,2);
842
						orb_set_color(BLUE);
843
						forward(200);
844
						delay_ms(2000);
845
						stop();
846
						beacon_State = 1;
847
					break;
1015
			/* Tells the robots to move forward and moves itself. */
1016
			case 0:
1017
				orb_set_color(YELLOW);
1018
				delay_ms(50);
848 1019

  
849
					/* Terminal. */
850
					case 1:
851
						stop();
852
						state = 2;
853
					break;
854
				}
1020
				// format: type of ack, speed divided by 10,
1021
				// time in seconds.
1022
				send3(CIRCLE_ACTION_FORWARD,speed,duration);
1023
				orb_set_color(BLUE);
1024
				forward(speed*10);
1025
				delay_ms(duration*1000);
1026
				stop();
1027
				beacon_State = 1;
855 1028
			break;
856 1029

  
857
//***********************************************************************************************************************************************************************************
858
			
1030
			/* Terminal. */
1031
			case 1:
1032
				stop();
1033
				state = 2;
1034
			break;
1035
			}
1036
		break;
1037

  
1038
		/* The TURNL code for the beacon */
1039
		case 24:
1040

  
1041
			orb_set_color(YELLOW);
1042
			delay_ms(50);
1043

  
1044
			// format: type of ack, speed divided by 10,
1045
			// time in seconds.
1046
			for(int i = 0 ; i < 5; i++)
1047
				send3(CIRCLE_ACTION_TURN,speed,duration);
1048
			orb_set_color(BLUE);
1049
			left(speed*10);
1050
			delay_ms(duration*1000);
1051
			stop();
1052
			state = 2;
1053

  
1054
		break;
1055

  
1056
		/* The TURNR code for the beacon */
1057
		case 25:
1058

  
1059
			orb_set_color(YELLOW);
1060
			delay_ms(50);
1061

  
1062
			// format: type of ack, speed divided by 10,
1063
			// time in seconds.
1064
			for(int i = 0 ; i < 5; i++)
1065
				send3(CIRCLE_ACTION_TURN,speed,duration);
1066
			orb_set_color(BLUE);
1067
			right(speed*10);
1068
			delay_ms(duration*1000);
1069
			stop();
1070
			state = 2;
1071

  
1072
		break;
1073

  
1074

  
1075
//******************************************************************************
1076
//******************************************************************************
1077
		
859 1078
		}	// ends the main switch
860 1079
	}		// ends the main while loop
861 1080

  
862
	orb_set_color(RED);	// error, we should never break from the while loop!
1081
	// error, we should never break from the while loop!
1082
	orb_set_color(RED);	
863 1083

  
864
	while(1); /* END HERE, just in case something happened.  This way we can see the red orb. */
1084
	/*
1085
	 END HERE, just in case something happened.
1086
	 This way we can see the red orb.
1087
	*/
1088
	while(1); 
865 1089
}
866

  
867

  

Also available in: Unified diff