Project

General

Profile

Revision 1695

created branch of trunk/code for controlls project

View differences:

branches/16299_s10/behaviors/formation_control/circle/circle.c
1
#include <dragonfly_lib.h>
2
#include <wl_basic.h>
3
#include <encoders.h>
4
#include "circle.h"
5

  
6
int EDGE = 0;
7
int BEACON = 1;
8
int timeout = 0;
9
int sending = 0;
10
int stop2 = 0;
11
struct vector slave_position;
12
int desired_max_bom;
13
int bom_max_counter;
14

  
15
//Last used 12,13,7(BOM)
16
void set_desired_max_bom(int desired_angle)
17
{
18
	if (desired_angle >= 348 || desired_angle < 11) desired_max_bom = 0;
19
	if (desired_angle >= 11 && desired_angle < 33) desired_max_bom = 1;
20
	if (desired_angle >= 33 && desired_angle < 56) desired_max_bom = 2;
21
	if (desired_angle >= 56 && desired_angle < 78) desired_max_bom = 3;
22
	if (desired_angle >= 78 && desired_angle < 101) desired_max_bom = 4;
23
	if (desired_angle >= 101 && desired_angle < 123) desired_max_bom = 5;
24
	if (desired_angle >= 123 && desired_angle < 145) desired_max_bom = 6;
25
	if (desired_angle >= 145 && desired_angle < 167) desired_max_bom = 7;
26
	if (desired_angle >= 167 && desired_angle < 190) desired_max_bom = 8;
27
	if (desired_angle >= 190 && desired_angle < 212) desired_max_bom = 9;
28
	if (desired_angle >= 212 && desired_angle < 235) desired_max_bom = 10;
29
	if (desired_angle >= 235 && desired_angle < 257) desired_max_bom = 11;
30
	if (desired_angle >= 257 && desired_angle < 280) desired_max_bom = 12;
31
	if (desired_angle >= 280 && desired_angle < 302) desired_max_bom = 13;
32
	if (desired_angle >= 302 && desired_angle < 325) desired_max_bom = 14;
33
	if (desired_angle >= 325 && desired_angle < 348) desired_max_bom = 15;
34
}
35

  
36
void switch_sending(void)
37
{
38
	if(sending)
39
	{
40
		sending = 0;
41
		bom_off();
42
	}
43
	else
44
	{
45
		sending = 1;
46
		bom_on();
47
	}
48
}
49

  
50
/*
51
Current situation:
52
	go to the center. ends when each edge robto send "I am here" message
53

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

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

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

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

  
66
  In general:
67
    More testing.  Especially with robots that are actually working.
68
*/
69

  
70

  
71
/*
72
	This program is used to make robots target a center (leader) robot using the BOM,
73
	then drive toward it and stop at a certain distance away.
74
	
75
	The distance will eventually be adjustable.
76

  
77
	With adjustment, the leader robot will be able to turn and use its standardized
78
	rangefinder to reposition or space the robots evenly.
79
	
80
	AuTHORS: Nico, Alex, Reva, Echo, Steve
81
*/
82

  
83

  
84
/* 
85
TODO:
86
	Used: Bots 1, 7
87
	16 Performed Badly
88
	12 worked ok as beacon, not well as edge
89
	
90
		Fix orient code so the bot does not toggle back and forth when it tries to turn
91
		
92
		Use the center bot to check distances
93
Done-->	Count them ("spam" method)
94
		Use beacon to find relative positions
95
		Beacon tells them how to move to be at the right distance
96
		*done*Wireless communication, initialization
97
*/
98

  
99

  
100

  
101
void forward(int speed){			// set the motors to this forward speed.
102
	motor_l_set(FORWARD,speed);
103
	motor_r_set(FORWARD,speed);
104
}
105
void left(int speed){				// turn left at this speed.
106
	motor_l_set(FORWARD,speed);
107
	motor_r_set(BACKWARD,speed);
108
}
109
void right(int speed){
110
	motor_l_set(BACKWARD,speed);
111
	motor_r_set(FORWARD,speed);
112
}
113
void stop(void){					// could be set to motors_off(), or just use this as an alternative.
114
	motor_l_set(BACKWARD,0);			// stop() is better - motors_off() creates a slight delay to turn them back on.
115
	motor_r_set(FORWARD,0);
116
}
117
void setforward(int spd1, int spd2){
118
	motor_l_set(FORWARD,spd1);
119
	motor_r_set(FORWARD,spd2);
120
}
121
void backward(int speed){
122
	motor_l_set(BACKWARD, speed);
123
	motor_r_set(BACKWARD, speed);
124
}
125
int get_distance(void){				// takes an averaged reading of the front rangefinder
126
	int temp,distance,kk=5;			// kk sets this to 5 readings.
127
	distance =0;
128
	for (int i=0; i<kk; i++){
129
		temp = range_read_distance(IR2);
130
		if (temp == -1)
131
		{
132
			//temp=0;
133
			i--;
134
		}
135
		else
136
			distance+= temp;
137
		delay_ms(3);
138
	}
139
	if (kk>0)
140
		return (int)(distance/kk);
141
	else 
142
		return 0;
143
}
144

  
145

  
146

  
147
/*
148
	Orients the robot so that it is facing the beacon (or the broadcasting BOM).
149
	
150
*/
151
void correctTurn(void)
152
{
153
	orb1_set_color(BLUE);			// BLUE and PURPLE
154
	left(220);
155
	while(1)
156
	{
157
		int bomNum = 0;				// bomNum is the current maximum reading
158
		bom_refresh(BOM_ALL);
159
		bomNum = bom_get_max();
160
		usb_puti(bomNum);
161
		if(bomNum == 4)				// when it's turned the right way, stop
162
		{
163
			timeout = 0;
164
			//motor_l_set(1, 200);
165
			//motor_r_set(1, 200);
166
			break;				// exits the while() loop to stop the method
167
		}
168
		else					// facing the wrong way
169
		{
170
			if(bomNum == -1)
171
			{
172
				timeout++;
173
				
174
				if(timeout > 5000)	// if it's been looking too long, move a little bit as it turns
175
				{
176
					motor_r_set(FORWARD, 210);
177
					motor_l_set(BACKWARD, 190);
178
				}
179
			}
180
			else if((bomNum >= 12) || (bomNum < 4))
181
			{
182
				motor_l_set(FORWARD, 200);
183
				motor_r_set(BACKWARD, 200);
184
				timeout = 0;
185
			}
186
			else
187
			{
188
				motor_l_set(BACKWARD, 200);
189
				motor_r_set(FORWARD, 200);
190
				timeout = 0;
191
			}
192
		}
193
	}
194
	return;
195
}
196

  
197

  
198
/*
199
	This is supposed to (essentially) do a correct turn, then move forward or something.
200
	Actually, we should just get rid of this.
201
*/
202
void correctApproach(void)
203
{
204
	int bomNum = 0;
205
	bom_refresh(BOM_ALL);
206
	bomNum = bom_get_max();
207
	usb_puti(bomNum);
208
	if(bomNum == 4)
209
	{	
210
		motor_l_set(1, 200);
211
		motor_r_set(1, 200);
212
	}
213
	else
214
	{
215
		if(bomNum == -1){}
216
		else if((bomNum >= 12) || (bomNum < 4))
217
		{
218
			motor_l_set(FORWARD, 200);
219
			motor_r_set(BACKWARD, 200);
220
		}
221
		else
222
		{
223
			motor_l_set(BACKWARD, 200);
224
			motor_r_set(FORWARD, 200);
225
		}
226
		delay_ms(100);
227
	}
228
}
229

  
230
/* 
231
	drives forward a hardcoded distance. May not be useful.
232
*/
233
void go_straight(void){
234
	forward(200);
235
	encoder_rst_dx(LEFT);
236
	encoder_rst_dx(RIGHT);
237
	delay_ms(100); 
238
	int x_left = encoder_get_x(LEFT), x_right = encoder_get_x(RIGHT);
239
	int count = 0;
240
	int d;
241
	while (count<25){						//count = 25 when bot6; count <12
242
		x_left = encoder_get_x(LEFT);
243
		x_right = encoder_get_x(RIGHT);
244
		d = x_right-x_left;
245
		if (d>13 || d<-13){
246
			if(d<50 && d>-50){
247
				d = round(1.0*d/4);
248
				setforward(200+d, 200-d);
249
			}
250
		}
251
		delay_ms(32);
252
		count++;
253
	}
254
}
255

  
256

  
257
/* 
258
    BLINK the given number times
259
*/
260
void blink(int num) {
261
	for(int i = 0; i<num; i++)
262
	{
263
		orb_set_color(ORB_OFF);
264
		delay_ms(350);
265
		orb_set_color(RED);
266
		delay_ms(200);
267
	}
268
	orb_set_color(ORB_OFF);
269
}
270

  
271

  
272

  
273

  
274

  
275

  
276

  
277
//*****************************************************************************************************************************************************************************************
278

  
279

  
280

  
281

  
282

  
283

  
284
/*
285
	A double state machine.  The robot is either an "edge" or a "beacon" depending on the initial potentiometer reading.
286
*/
287
int main(void)
288
{
289
	/* Initialize dragonfly board */
290
    	dragonfly_init(ALL_ON);
291
    	/* Initialize the basic wireless library */
292
    	wl_basic_init_default();
293
    	/* Set the XBee channel to your assigned channel */	/* Set the XBee channel to your assigned channel */
294
	wl_set_channel(24);
295

  
296
	int sending_counter = 0;
297
	int robotid = get_robotid();
298
	int used[16];
299
	int usedPointer=0;
300
	for (int i=0; i<16; i++) used[i] = 0;
301
	char send_buffer[2];
302
	int data_length;
303
	unsigned char *packet_data=wl_basic_do_default(&data_length);
304
	
305
	
306
	int state = EDGE;
307
	int beacon_State=0;
308
	int edge_State=0;
309
	int waitingCounter=0;
310
	int robotsReceived=0;
311
	int offset = 20, time=0;
312
	
313
	if(wheel()<100)
314
	{
315
		state=EDGE;
316
	}
317
	else
318
	{
319
		state=BEACON;
320
	}
321
	
322
	int distance=1000;					// how far away to stop.
323
	int onefoot=250, speed=250;				// one foot is 490 for bot 1; one foot is 200 for bot6
324
	
325
	while(1)
326
	{
327
		bom_refresh(BOM_ALL);
328
		
329
		/*
330
		*******TERMinology**************
331
		EDGE=0 other names: slave. Definition: robots on the edge of  the circle;
332
		BEACON=1 other name: master. Definition: robots in the center of the circle;
333
		
334
		
335
		*******EXPECTED MOVES ********** 
336
		The designed movement:
337
		 1. one center robot, several edge robots are on;
338
		 2. center robots: button 1 is pressed;
339
		 3. center robots: send global package telling edges that he exists;
340
		 4. EDGE robots response with ACK. 
341
		 5. EDGE robots wait for center robots to finish counting (DONE package)
342
		 6. EDGE robtos approach the center robtot and stop at the "onefoot" distance, send message to the center
343
		*/
344
		
345
		
346
		// decide if its is center or not.
347
		switch(state)
348
		{
349
			/**********
350
				if  EDGE /slave robots
351
			*/
352
			case 0:	
353
				switch(edge_State)
354
				{
355
					/*
356
						0. EDGE robots are on. 
357
						1. They are waiting for ExiST pacakage from the Center robots
358
						2. After they receive the package, they send ACK package to center.
359
						3. Wait the center robot to finish counting all EDGE robots
360
					*/
361
					case 0:   
362
						bom_off();
363
						orb1_set_color(YELLOW);orb2_set_color(CYAN);
364
						packet_data=wl_basic_do_default(&data_length);
365
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_EXIST)
366
						{
367
							send_buffer[0]=CIRCLE_ACTION_ACK;
368
							send_buffer[1]=robotid;
369
							
370
							wl_basic_send_global_packet(42,send_buffer,2);
371
							edge_State=1;
372
						}
373
					break;
374
					/*
375
						1. Wait for DONE package 
376
						2. The counting process is DONE
377
					*/
378
					case 1:		
379
					
380
						orb_set_color(YELLOW);orb2_set_color(PURPLE);
381
						packet_data=wl_basic_do_default(&data_length);
382
						//wl_basic_send_global_packet(42,send_buffer,2);
383
						
384
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE)
385
						{
386
							edge_State=2;
387
						}
388
					break;
389
					
390
					case 2:
391
						// COLOR afer DONE ---> MAGENTA
392
						orb_set_color(MAGENTA);
393
						correctTurn();			// turn to face the beacon
394
						forward(175);
395
						//range_init();
396
						
397
						
398
						distance = get_distance();
399
						time=0;
400
						while ((distance-offset)>=onefoot || distance==0 || (distance+offset)<onefoot)
401
						{
402
							if(distance==0)
403
								orb_set_color(WHITE);
404
							else if(distance-offset>=onefoot)
405
								forward(175);
406
							else
407
								backward(175);
408
							//correctApproach();
409
							distance = get_distance();
410
							delay_ms(14);
411
							time+=14;
412
							if(time>500){
413
								correctTurn();
414
								time=0;
415
							}
416
						}
417
							
418
						stop();
419
						orb_set_color(LIME);
420

  
421
						send_buffer[0]=CIRCLE_ACTION_ACK;
422
						send_buffer[1]=robotid;	
423
						wl_basic_send_global_packet(42,send_buffer,2);
424

  
425
						edge_State=3;
426
					break;
427
					
428
					// wait until the beacon sends out its robot ID
429
/*
430
	// as we don't check distance to center one by one now,  
431
	no more private communication at this point. 
432
					case 3:
433
						orb_set_color(YELLOW);
434
						orb2_set_color(GREEN);
435

  
436
						packet_data=wl_basic_do_default(&data_length);
437
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK && packet_data[1]==robotid)
438
						{
439
							bom_on();
440
							orb_set_color(ORANGE);
441
						}
442
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE && packet_data[1]==robotid)
443
						{
444
							bom_off();
445
							orb_set_color(YELLOW);
446
						}
447
					break;
448
*/
449
				}
450

  
451
*/				
452
				// NEW CODE FROM JOEL
453
				/*
454
				while(1)
455
				{
456
					packet_data = wl_basic_do_default(&data_length);
457
					
458
					if(packet_data[0]=='s') stop2=1;
459
					if(packet_data[0]=='a') switch_sending();
460
						
461
					if(sending)
462
					{
463
					
464
					}
465
				
466
					else // recieving
467
					{
468
				
469
						if(stop2)
470
						{
471
							motor_l_set(FORWARD,0);
472
							motor_r_set(FORWARD,0);
473
							orb1_set_color(GREEN);
474
						}
475
				
476
						else
477
						{
478
							int max_bom = bom_get_max();
479
								/*usb_puts("bom_get_max : ");
480
							usb_puti(max_bom);
481
							usb_puts("/n/r");*/
482
					/*	
483
						
484
							if(max_bom == 8)
485
							{	
486
								orb2_set_color(BLUE);
487
								motor_r_set(FORWARD,180);
488
								motor_l_set(FORWARD,180);
489
								
490
							}
491
							else if(max_bom == 7 || max_bom == 6 || max_bom == 5)
492
							{
493
								motor_l_set(FORWARD,180);
494
								motor_r_set(FORWARD,0);
495
							}
496
							else if(max_bom == -1);
497
							else 
498
							{
499
								orb2_set_color(GREEN);
500
								motor_l_set(FORWARD,0);
501
								motor_r_set(FORWARD,180);
502
							}
503
						}
504
					
505
					}
506
				
507
				delay_ms(10);
508
				
509
				} //end while
510
				*/
511
				//break;
512
				
513
				// END for EDGE robots
514
			
515

  
516

  
517

  
518

  
519

  
520
	
521
//*****************************************************************************************************************************************************************************************
522
			
523

  
524

  
525

  
526

  
527

  
528

  
529
			/*
530
			   The CENTER/BEACON/MASTER robot
531
			*/	
532
			case 1:			// BEACON /master /enter robots
533
				switch(beacon_State) {
534
				/*
535
				   0. center  robots on wait for pressing button 1
536
				*/
537
				case 0:		
538
					bom_on();
539
					orb_set_color(PURPLE);
540
					if(button1_click()) beacon_State=1;
541
					break;	
542
				/*
543
					1. Send EXIST package to EDGE robots
544
				*/
545
				case 1:		// sends a global exist packet to see how many robots there are
546
					orb_set_color(RED);
547
					send_buffer[0]=CIRCLE_ACTION_EXIST;
548
					send_buffer[1]=get_robotid();
549
					wl_basic_send_global_packet(42,send_buffer,2);
550
					usedPointer = 0;
551
					beacon_State=2;
552
					// wait for the edge to send for 1sec. 
553
					delay_ms(1000);
554
					break;
555
				/*
556
					2. Count the number of the EDGE robots 
557
					*******NOTE: at most  1500  times of loop ******
558
				*/
559
				case 2: 	
560
					waitingCounter++;
561
					orb1_set_color(YELLOW);
562
					orb2_set_color(BLUE);
563
					packet_data=wl_basic_do_default(&data_length);
564
					
565
					if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
566
					{
567
						orb_set_color(RED);
568
						orb2_set_color(BLUE);
569
						//only add to robots seen if you haven't gotten an ACK from this robot
570
						if(used[packet_data[1]]==0){		
571
							robotsReceived++;
572
							used[usedPointer] = packet_data[1];
573
							usedPointer++;
574

  
575
							usb_puts("Added: ");
576
							usb_puti(packet_data[1]);
577
							usb_puts("\r\n");
578
						}
579
					}
580
					if(waitingCounter >= 2000){
581
						beacon_State=3;
582
					}
583
					break;
584
				/*
585
					COUNTing is DONE.
586
					Sending DONE package.
587
				*/	
588
				case 3:
589
					blink(robotsReceived);
590
					orb_set_color(GREEN);
591
					send_buffer[0]=CIRCLE_ACTION_DONE;
592
					wl_basic_send_global_packet(42,send_buffer,2);
593
					beacon_State=4;
594
					break;
595
				/*
596
					Wait for all the robots to get to right distance/position 
597
				*/
598
				case 4: 
599
					orb1_set_color(YELLOW);
600
					orb2_set_color(WHITE);
601
					
602
					int numOk = 0;
603
					
604
					while(numOk<robotsReceived)
605
					{
606
						packet_data=wl_basic_do_default(&data_length);
607
						if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
608
						{
609
							numOk++;
610
						}
611
					}
612
					
613
					beacon_State = 5;
614
					break; 
615
				
616
				/**
617
 TODO: no need for "private" communication if we don't check distance one by one  
618
   So comment out this part at least for now.
619

  
620
				    Starts repositioning the edge robots one by one
621
				*/
622
/*				case 5:
623
					orb_set_color(MAGENTA);
624
					bom_off();
625
					for(int i=0; i<robotsReceived; i++)
626
										
627
					{
628
						usb_puts("used = ");
629
						usb_puti(used[i]);
630
						usb_puts("\r\n");
631
						send_buffer[0]=CIRCLE_ACTION_ACK;
632
						send_buffer[1]=used[i];
633
						wl_basic_send_global_packet(42,send_buffer,2);
634
						
635
						delay_ms(1000);
636

  
637
						send_buffer[0]=CIRCLE_ACTION_DONE;
638
						send_buffer[1]=used[i];
639
						wl_basic_send_global_packet(42,send_buffer,2);
640

  
641
						delay_ms(1000);
642
					}
643
*/
644

  
645
					/*orb_set_color(BLUE);
646
					// clock for switching the BOMs between the master and slave
647
					if(sending_counter++>4)	
648
					{
649
						switch_sending();
650
						sending_counter = 0;
651
						send_buffer[0] = 'a';
652
						wl_basic_send_global_packet(42, send_buffer, 1);
653
					}
654
					
655
					
656
					if(sending)
657
					{
658
						
659
					}
660
					
661
					else // recieving
662
					{
663
						int max_bom = bom_get_max();
664
						usb_puts("bom_get_max : ");
665
						usb_puti(max_bom);
666
						usb_puts("\n\r");
667
						
668
						if(max_bom == desired_max_bom)
669
						{
670
							// only stops the slave if two consecutive boms 
671
							//     reading give the desired bom as the max one. Filters the noise.
672
							if(bom_max_counter)                 
673
							{
674
								send_buffer[0] = 's';
675
								wl_basic_send_global_packet(42, send_buffer, 2);
676
							}
677
							bom_max_counter =1;
678
						}
679
						else bom_max_counter = 0;
680
						
681
					}
682
					*/
683
					//break;
684
			}
685
		}
686
	}
687

  
688
	orb_set_color(RED);
689
	while(1); /* END HERE */
690

  
691
	//return 0;
692
}
branches/16299_s10/behaviors/formation_control/circle/Makefile
1
# this is a local makefile
2

  
3
# Relative path to the root directory (containing lib directory)
4
ifndef COLONYROOT
5
COLONYROOT := ..
6

  
7
# Target file name (without extension).
8
TARGET = main
9

  
10
# Uncomment this to use the wireless library
11
USE_WIRELESS = 1
12

  
13
# com1 = serial port. Use lpt1 to connect to parallel port.
14
AVRDUDE_PORT = $(shell if uname -s |grep -i w32 >/dev/null; then echo 'COM4:'; else echo '/dev/ttyUSB0'; fi)
15
#AVRDUDE_PORT = $(shell if uname -s |grep -i w32 >/dev/null; then echo 'COM4:'; else echo '/dev/ttyUSB0'; fi)
16
else
17
COLONYROOT := ../$(COLONYROOT)
18
endif
19

  
20
include $(COLONYROOT)/Makefile
branches/16299_s10/behaviors/formation_control/circle/circle.h
1
#ifndef _CIRCLE_H
2
#define _CIRCLE_H
3

  
4
#include <inttypes.h>
5

  
6
/**** This file should not be edited! ****/
7

  
8
/*
9
 * The packet structure is 2 bytes
10
 * byte 0 is the action, which is one of the values below
11
 * byte 1 is the robot id
12
 */
13

  
14
#define CIRCLE_ACTION_EXIST 'E'
15
#define CIRCLE_ACTION_POSITION 'P'
16
#define CIRCLE_ACTION_ACK 'A'
17
#define CIRCLE_ACTION_DONE 'D'
18
//#define EDGE 0;
19
//#define BEACON 1;
20

  
21
#endif
branches/16299_s10/behaviors/formation_control/circle_spacing/circle_spacing.c
1
#include <dragonfly_lib.h>
2
#include <wl_basic.h>
3
#include<encoders.h>
4

  
5

  
6
int master = 0;
7
int sending = 0;
8
int stop = 0;
9
struct vector slave_position;
10
int desired_max_bom;
11
int bom_max_counter;
12

  
13

  
14
void set_desired_max_bom(int desired_angle)
15
{
16
	if (desired_angle >= 348 || desired_angle < 11) desired_max_bom = 0;
17
	if (desired_angle >= 11 && desired_angle < 33) desired_max_bom = 1;
18
	if (desired_angle >= 33 && desired_angle < 56) desired_max_bom = 2;
19
	if (desired_angle >= 56 && desired_angle < 78) desired_max_bom = 3;
20
	if (desired_angle >= 78 && desired_angle < 101) desired_max_bom = 4;
21
	if (desired_angle >= 101 && desired_angle < 123) desired_max_bom = 5;
22
	if (desired_angle >= 123 && desired_angle < 145) desired_max_bom = 6;
23
	if (desired_angle >= 145 && desired_angle < 167) desired_max_bom = 7;
24
	if (desired_angle >= 167 && desired_angle < 190) desired_max_bom = 8;
25
	if (desired_angle >= 190 && desired_angle < 212) desired_max_bom = 9;
26
	if (desired_angle >= 212 && desired_angle < 235) desired_max_bom = 10;
27
	if (desired_angle >= 235 && desired_angle < 257) desired_max_bom = 11;
28
	if (desired_angle >= 257 && desired_angle < 280) desired_max_bom = 12;
29
	if (desired_angle >= 280 && desired_angle < 302) desired_max_bom = 13;
30
	if (desired_angle >= 302 && desired_angle < 325) desired_max_bom = 14;
31
	if (desired_angle >= 325 && desired_angle < 348) desired_max_bom = 15;
32
}
33

  
34

  
35

  
36

  
37

  
38

  
39
void switch_sending ()
40
{
41
	if(sending)
42
	{
43
		sending = 0;
44
		bom_off();
45
	}
46
	else
47
	{
48
		sending = 1;
49
		bom_on();
50
	}
51
}
52

  
53

  
54

  
55
int main(void)
56
{
57

  
58
	
59
	
60
	int sending_counter = 0;
61
	
62
    /* Initialize dragonfly board */
63
	
64
    dragonfly_init(ALL_ON);
65
	xbee_init();
66
	wl_basic_init_default();
67
	wl_set_channel(12);
68
    int data_length;
69
	unsigned char *packet_data;
70
	char send_buffer[2];
71
	
72
	
73
	if(master) {orb1_set_color(RED); set_desired_max_bom(30);}
74
	else orb1_set_color(BLUE);
75
	
76
	
77
	while(1)
78
	{
79
	
80
	
81
		
82
	
83
		bom_refresh(BOM_ALL);
84
		
85
		
86
		
87
		if(master)
88
		{
89
		
90
			if(sending_counter++>4)	// clock for switching the BOMs between the master and slave
91
			{
92
				switch_sending();
93
				sending_counter = 0;
94
				send_buffer[0] = 'a';
95
				wl_basic_send_global_packet(42, send_buffer, 1);
96
			}
97
		
98
			
99
			if(sending)
100
			{
101
		
102
				
103
			
104
			
105

  
106
			}
107
			
108
			else // recieving
109
			{
110
				int max_bom = bom_get_max();
111
					usb_puts("bom_get_max : ");
112
					usb_puti(max_bom);
113
					usb_puts("\n\r");
114
			
115
				if(max_bom == desired_max_bom)
116
				{
117
					if(bom_max_counter)                 // only stops the slave if two consecutive boms reading give the desired bom as the max one. Filters the noise.
118
					{
119
					send_buffer[0] = 's';
120
					wl_basic_send_global_packet(42, send_buffer, 2);
121
					}
122
				bom_max_counter =1;
123
				}
124
				else bom_max_counter = 0;
125
				
126
			}
127
		}
128
		
129
		
130
		
131
		else // slave
132
		{
133
			if(packet_data[0]=='s') stop=1;
134
			if(packet_data[0]=='a') switch_sending();
135
		
136
			if(sending)
137
			{
138
			
139
			}
140
			
141
			else // recieving
142
			{
143
			
144
				if(stop)
145
				{
146
				motor_l_set(FORWARD,0);
147
				motor_r_set(FORWARD,0);
148
				orb1_set_color(GREEN);
149
				}
150
				
151
				else
152
				{
153
					int max_bom = bom_get_max();
154
					/*usb_puts("bom_get_max : ");
155
					usb_puti(max_bom);
156
					usb_puts("/n/r");*/
157
				
158
				
159
				   if(max_bom == 8)
160
				   {	
161
					orb2_set_color(BLUE);
162
					motor_r_set(FORWARD,180);
163
					motor_l_set(FORWARD,180);
164
					
165
				   }
166
				   else if(max_bom == 7 || max_bom == 6 || max_bom == 5)
167
				   {
168
					motor_l_set(FORWARD,180);
169
					motor_r_set(FORWARD,0);
170
					}
171
					else if(max_bom == -1);
172
				   else 
173
				   {
174
					orb2_set_color(GREEN);
175
					motor_l_set(FORWARD,0);
176
					motor_r_set(FORWARD,180);
177
					}
178
				}
179
			
180
			
181
			}
182
		
183
		
184
		}
185
		
186
		packet_data = wl_basic_do_default(&data_length);
187
		delay_ms(10);
188
	}
189
	
190
  
191
  return 0;
192
  
193
  
194
	
195
	
196
}
197

  
198

  
199

  
200

  
201

  
202

  
branches/16299_s10/behaviors/formation_control/circle_spacing/Makefile
1
# this is a local makefile
2

  
3
# Relative path to the root directory (containing lib directory)
4
ifndef COLONYROOT
5
COLONYROOT := ..
6

  
7
# Target file name (without extension).
8
TARGET = main
9

  
10
# Uncomment this to use the wireless library
11
USE_WIRELESS = 1
12

  
13
# com1 = serial port. Use lpt1 to connect to parallel port.
14
AVRDUDE_PORT = $(shell if uname -s |grep -i w32 >/dev/null; then echo 'COM7:'; else echo '/dev/ttyUSB0'; fi)
15

  
16
else
17
COLONYROOT := ../$(COLONYROOT)
18
endif
19

  
20
include $(COLONYROOT)/Makefile
branches/16299_s10/behaviors/formation_control/push_pull/Makefile
1
# this is a local makefile
2

  
3
# Relative path to the root directory (containing lib directory)
4
ifndef COLONYROOT
5
COLONYROOT := ..
6

  
7
# Target file name (without extension).
8
TARGET = main
9

  
10
# Uncomment this to use the wireless library
11
USE_WIRELESS = 1
12

  
13
# com1 = serial port. Use lpt1 to connect to parallel port.
14
AVRDUDE_PORT = $(shell if uname -s |grep -i w32 >/dev/null; then echo 'COM4:'; else echo '/dev/ttyUSB0'; fi)
15

  
16
else
17
COLONYROOT := ../$(COLONYROOT)
18
endif
19

  
20
include $(COLONYROOT)/Makefile
branches/16299_s10/behaviors/formation_control/push_pull/push_pull.c
1
#include <stdint.h>
2
#include <dragonfly_lib.h>
3
#include <wl_basic.h>
4
#include <stdlib.h>
5

  
6
int main (void) {
7

  
8
	Vector v;
9

  
10
	dragonfly_init(ALL_ON);
11
	xbee_init();
12
	encoders_init();
13

  
14
	orbs_set_color(BLUE, GREEN);
15
	delay_ms(1000);
16
	orbs_set_color(GREEN, BLUE);
17
	delay_ms(1000);
18
	orbs_set_color(RED, RED);
19

  
20
	while (1) {
21
		bom_print_usb(NULL);
22

  
23
		bom_get_vector(&v, NULL);
24

  
25
		usb_puts("x: ");
26
		usb_puti(v.x);
27
		usb_puts("\ty: ");
28
		usb_puti(v.y);
29
		usb_puts("\n");
30

  
31
		delay_ms(50);
32
	}
33

  
34
	while(1);
35

  
36
}
branches/16299_s10/behaviors/formation_control/push_pull/vectorSizeSpecs.m
1
% vectorSizeSpecs - Script used to help calculate the max scalar value by
2
% 		which to multiply the BOM unit vectors (thus increasing the
3
%		precision of the scaled vectors) such that in the worst case, the
4
%		total net sum will not overflow the data type used to represent
5
%		the net vector components.
6
%
7
%	Author: John Sexton, Colony Project, CMU Robotics Club
8

  
9

  
10
% Parameters
11
maxIntensity = 255;
12
dataBits = 16;
13
scalar = 25;
14

  
15
n = 0:8;
16
angle = n * 2 * pi / 16;
17

  
18
vector_components = sin(angle);
19
max_net_component = sum(vector_components);
20

  
21
% Formula for max_net_component (mnc), obtained by summing
22
% values from the unit circle at angles of 0 : pi/8 : pi
23
% in quadrants I and II
24
mnc = 1;									%sin(pi/2)
25
mnc = mnc + (2*  (1/2)*sqrt(2+sqrt(2)));	%sin(3pi/8) and sin(5pi/8)
26
mnc = mnc + (2*  sqrt(2)/2);				%sin(pi/4) and sin(3pi/4)
27
mnc = mnc + (2*  (1/2)*sqrt(2-sqrt(2)));	%sin(pi/8) and sin(7pi/8)
28

  
29

  
30
calc_scalar = (2^(dataBits-1)-1) / (max_net_component * maxIntensity);
31
% calc_scalar = 25.560 for 16 bits => use 25 as scalar for int data type
32

  
33
fprintf('With %d data bits, calculated scalar value: %.3f\n\n', dataBits, calc_scalar);
34

  
35

  
36
% Check worst case
37
scaled_vector_components = scalar * vector_components;
38

  
39
worst_case = fix(scaled_vector_components) * maxIntensity;
40
worst_sum = sum(worst_case);
41
fprintf('With scalar %d, max worst case sum: %d\n', scalar, round(worst_sum));
42
fprintf('Max number: 2^(%d-1) - 1 = %d\n', dataBits, (2^(dataBits-1)-1));
43

  
44

  
45
% Calculate the x and y component arrays which should be used in the
46
% BOM Vector Component Tables in push_pull.c
47
N = 0:15;
48
x_comp = fix(scalar * cos(2 * pi / 16 * N))
49
y_comp = fix(scalar * sin(2 * pi / 16 * N))
branches/16299_s10/behaviors/formation_control/Makefile
1
# this is a local makefile
2

  
3
# Relative path to the root directory (containing lib directory)
4
ifndef COLONYROOT
5
COLONYROOT := ..
6

  
7
# Target file name (without extension).
8
TARGET = main
9

  
10
# Uncomment this to use the wireless library
11
USE_WIRELESS = 1
12

  
13
# com1 = serial port. Use lpt1 to connect to parallel port.
14
AVRDUDE_PORT = $(shell if uname -s |grep -i w32 >/dev/null; then echo 'COM4:'; else echo '/dev/ttyUSB0'; fi)
15

  
16
else
17
COLONYROOT := ../$(COLONYROOT)
18
endif
19

  
20
include $(COLONYROOT)/Makefile
branches/16299_s10/behaviors/hunter_prey/john/main.c
1
/*
2
 * Hunter-Prey main.c File - Implementation of Hunter-Prey behavior which
3
 * 		uses finite state machines to manage the behavior. A top level
4
 * 		state machine controls the high level behavior switches between
5
 * 		"hunter" and "prey" and manages the wireless communication. Two
6
 * 		additional state machines control the behavior of the robot when
7
 * 		it is in "prey" mode and when it is in "hunter" mode.
8
 *
9
 * Author: John Sexton, Colony Project, CMU Robotics Club
10
 */
11

  
12
#include <dragonfly_lib.h>
13
#include <wl_basic.h>
14
#include "hunter_prey.h"
15
#include "encoders.h"
16

  
17
#define WL_CHANNEL 					24
18

  
19
#define BACK_THRESHOLD 			-1000
20
#define TURN_DIST						1024
21
#define IR_DIST_THRESHOLD		150
22
#define WAIT_DELAY_MS				2000
23

  
24
/* State Macros */
25

  
26
/* Top Level FSM States */
27
#define TOP_INIT						0
28
#define TOP_HUNTER_HUNT			1
29
#define TOP_HUNTER_TAG			2
30
#define TOP_HUNTER_PURSUE		3
31
#define TOP_PREY_AVOID			4
32
#define TOP_HUNTER_WAIT			5
33
#define TOP_ERROR						6
34

  
35
/* Hunter FSM States */
36
#define HUNTER_SPIRAL				0
37
#define HUNTER_CHASE				1
38

  
39
/* Prey FSM States */
40
#define PREY_START_BACK			0
41
#define PREY_BACKING				1
42
#define PREY_TURN						2
43
#define PREY_AVOID					3
44

  
45

  
46
/* Function prototype declarations */
47
int hunter_FSM(int, int, int);
48
int prey_FSM(int);
49

  
50
/* Variables used to receive packets */
51
unsigned char* packet_data;
52
int data_length;
53

  
54
/*  Data buffer used to send packets */
55
char send_buffer[2];
56

  
57
int main(void)
58
{
59

  
60
    /* Initialize dragonfly board */
61
    dragonfly_init(ALL_ON);
62
		xbee_init();
63
		encoders_init();
64

  
65
    /* Initialize the basic wireless library */
66
    wl_basic_init_default();
67

  
68
    /* Set the XBee channel to assigned channel */
69
    wl_set_channel(WL_CHANNEL);
70

  
71

  
72
    /* ****** CODE HERE ******* */
73

  
74
		/* Initialize state machines */
75
		int state = TOP_INIT;
76
		int hunter_state = HUNTER_SPIRAL;
77
		int prey_state = PREY_AVOID;
78

  
79
		int frontIR = 0;
80
		int maxBOM = 0;
81
		int robotID = get_robotid();
82
		int oldTime = 0, curTime = 0;
83

  
84
		while (1) {
85

  
86
			/* Check if we've received a wireless packet */
87
			packet_data = wl_basic_do_default(&data_length);
88

  
89
			/* Top level state machines */
90
			switch(state) {
91

  
92
				case TOP_INIT:
93
					orbs_set_color(RED, GREEN);
94
					delay_ms(500);
95
					orbs_set_color(GREEN, RED);
96
					delay_ms(500);
97

  
98
					/* Allow user to pick the starting behavior */
99
					if (button1_read()) {
100
						state = TOP_PREY_AVOID;
101
						prey_state = PREY_AVOID;
102
					} else {
103
						state = TOP_HUNTER_HUNT;
104
						hunter_state = HUNTER_SPIRAL;
105
					}
106
					break;
107
				case TOP_HUNTER_HUNT:
108
					orbs_set_color(RED, RED);
109

  
110
					if (packet_data && data_length == 2
111
							&& packet_data[0] == HUNTER_PREY_ACTION_ACK) {
112
						/* If we've received an ACK, we need to wait */
113
						state = TOP_HUNTER_WAIT;
114
					} else {
115
						/* Record some sensor readings and check if we can TAG */
116
						bom_refresh(BOM_ALL);
117
						frontIR = range_read_distance(IR2);
118
						maxBOM = get_max_bom();
119
						if (hunter_prey_tagged(maxBOM, frontIR)) {
120
							state = TOP_HUNTER_TAG;
121
						} else {
122
							/* If we haven't tagged, then enter hunter FSM */
123
							hunter_state = hunter_FSM(hunter_state, maxBOM, frontIR);
124
						}
125
					}
126
					break;
127
				case TOP_HUNTER_TAG:
128
					orbs_set_color(RED, PURPLE);
129

  
130
					if (packet_data && data_length == 2
131
							&& packet_data[0] == HUNTER_PREY_ACTION_ACK) {
132
						/* If we've received an ACK, then someone beat us to the TAG and
133
 						 * we need to wait. */
134
						state = TOP_HUNTER_WAIT;
135
					} else {
136
						/* Prepare and send the TAG packet */
137
						send_buffer[0] = HUNTER_PREY_ACTION_TAG;
138
						send_buffer[1] = robotID;
139
						wl_basic_send_global_packet(42, send_buffer, 2);
140

  
141
						/* Record the time so we don't spam a TAG message on the network */
142
						oldTime = rtc_get();
143
						state = TOP_HUNTER_PURSUE;
144
					}
145
					break;
146
				case TOP_HUNTER_PURSUE:
147
					orbs_set_color(RED, BLUE);
148
					curTime = rtc_get();
149
					
150
					if (packet_data && data_length == 2
151
							&& packet_data[0] == HUNTER_PREY_ACTION_ACK) {
152
						/* Check if we've received a new wireless packet */
153

  
154
						if (packet_data[1] == robotID) {
155
							/* We've been ACKed, so we can now become the prey */
156
							state = TOP_PREY_AVOID;
157
							prey_state = PREY_START_BACK;
158
						} else {
159
							/* If we get an ACK with a different robotID, then someone beat us
160
							 * to the TAG, so we must wait */
161
							state = TOP_HUNTER_WAIT;
162
						}
163

  
164
					} else if (curTime - oldTime > 1) {
165
						/* If 1 second has ellapsed, return to normal hunting state (we can
166
						 * TAG again now) */
167
						state = TOP_HUNTER_HUNT;
168
					} else if (oldTime > curTime) {
169
						/* If for some reason the timer overflows, or the wireless library
170
						 * (which is also using the same timer) resets the timer,
171
						 * reinitialize the timer so that we don't wait too long for the
172
						 * timer to catch back up. */
173
						oldTime = curTime;
174
					} else {
175
						/* If no other behavioral changes need to be made, then continue
176
						 * with the hunter FSM where we left off */
177
						bom_refresh(BOM_ALL);
178
						frontIR = range_read_distance(IR2);
179
						maxBOM = get_max_bom();
180
						hunter_state = hunter_FSM(hunter_state, maxBOM, frontIR);
181
					}
182
					break;
183
				case TOP_PREY_AVOID:
184
					orbs_set_color(GREEN, GREEN);
185
					if (packet_data && data_length == 2
186
							&& packet_data[0] == HUNTER_PREY_ACTION_TAG) {
187
						/* Check if we've received a TAG yet. If so then send an ACK back */
188

  
189
						send_buffer[0] = HUNTER_PREY_ACTION_ACK;
190
						send_buffer[1] = packet_data[1];
191
						wl_basic_send_global_packet(42, send_buffer, 2);
192
						
193
						state = TOP_HUNTER_WAIT;
194
					} else {
195
						/* If we haven't received a TAG yet, continue with prey FSM */
196
						bom_on();
197
						prey_state = prey_FSM(prey_state);
198
					}					
199
					break;
200
				case TOP_HUNTER_WAIT:
201
					/* Set orb colors and wait to give the prey the 5 second head start */
202
					orbs_set_color(BLUE, BLUE);
203
					bom_off();
204
					motors_off();
205
					delay_ms(WAIT_DELAY_MS);
206
					state = TOP_HUNTER_HUNT;
207
					hunter_state = HUNTER_SPIRAL;
208
					break;
209
				case TOP_ERROR:
210
				default:
211
					orbs_set_color(PURPLE, PURPLE);
212
					state = TOP_ERROR;
213
					while(1);
214
					break;
215
			}
216

  
217
		}
218

  
219
    /* ****** END HERE ******* */
220

  
221
    while(1);
222

  
223
    return 0;
224

  
225
}
226

  
227

  
228
/*
229
 * prey_FSM - Prey finite state machine which starts by backing away, turning,
230
 * 		and then running and avoiding obstacles.
231
 *
232
 * Arguments:
233
 * 	prey_state - Current prey state.
234
 *
235
 * returns - The new state of the prey state machine.
236
 */
237

  
238
int prey_FSM(int prey_state) {
239

  
240
	/* Variable to store the front rangefinder readings */
241
	int rangeVals[3] = {0, 0, 0};
242

  
243
	switch (prey_state) {
244

  
245
		case PREY_START_BACK:
246
			motor_l_set(BACKWARD, 255);
247
			motor_r_set(BACKWARD, 255);
248
			encoder_rst_dx(LEFT);
249
			encoder_rst_dx(RIGHT);
250
			return PREY_BACKING;
251
			break;
252
		case PREY_BACKING:
253
			if (encoder_get_x(LEFT) < BACK_THRESHOLD
254
											|| encoder_get_x(RIGHT) < BACK_THRESHOLD) {
255
				motor_l_set(BACKWARD, 255);
256
				motor_r_set(FORWARD, 255);
257
				encoder_rst_dx(LEFT);
258
				encoder_rst_dx(RIGHT);
259
				return PREY_TURN;
260
			} else {
261
				return PREY_BACKING;
262
			}
263
			break;
264
		case PREY_TURN:
265
			if (encoder_get_x(LEFT) < -TURN_DIST
266
											|| encoder_get_x(RIGHT) > TURN_DIST) {
267
				return PREY_AVOID;				
268
			} else {
269
				return PREY_TURN;
270
			}
271
			break;
272
		case PREY_AVOID:
273
			rangeVals[0] = range_read_distance(IR1);
274
			rangeVals[1] = range_read_distance(IR2);
275
			rangeVals[2] = range_read_distance(IR3);
276

  
277
			/* Drive away if we detect obstacles using the rangefinders */
278
			if (rangeVals[1] > 0 && rangeVals[1] < IR_DIST_THRESHOLD) {
279
				if (rangeVals[0] < rangeVals[2]) {
280
					motor_l_set(FORWARD, 255);
281
					motor_r_set(BACKWARD, 255);
282
				} else {
283
					motor_l_set(BACKWARD, 255);
284
					motor_r_set(FORWARD, 255);
285
				}
286
				return PREY_AVOID;
287
			} else if (rangeVals[0] > 0 && rangeVals[0] < IR_DIST_THRESHOLD) {
288
				motor_l_set(FORWARD, 255);
289
				motor_r_set(FORWARD, 170);
290
				return PREY_AVOID;
291
			} else if (rangeVals[2] > 0 && rangeVals[2] < IR_DIST_THRESHOLD) {
292
				motor_l_set(FORWARD, 170);
293
				motor_r_set(FORWARD, 255);
294
				return PREY_AVOID;
295
			} else {			
296
				motor_l_set(FORWARD, 255);
297
				motor_r_set(FORWARD, 255);
298
				return PREY_AVOID;
299
			}
300
			break;
301
		default:
302
			return PREY_AVOID;
303
			break;
304

  
305
	}
306
	
307
	return prey_state;
308

  
309
}
310

  
311

  
312
/*
313
 * hunter_FSM - Hunter finite state machine which defaults to spiraling
314
 * 		outwards until the BOM can locate the prey. Once the BOM locates
315
 * 		the prey, chase the prey as fast as possible.
316
 *
317
 * Arguments:
318
 * 	hunter_state - Current hunter state.
319
 * 	maxBOM - Current maximum BOM value.
320
 * 	frontIR - Current front IR rangefinder reading value.
321
 *
322
 * returns - The new state of the hunter state machine.
323
 */
324

  
325
int hunter_FSM(int hunter_state, int maxBOM, int frontIR) {
326

  
327
	switch(hunter_state) {
328

  
329
		case HUNTER_SPIRAL:
330
			if (maxBOM != -1) {
331
				return HUNTER_CHASE;
332
			} else {
333
				motor_l_set(FORWARD, 170);
334
				motor_r_set(FORWARD, 190);
335
				return HUNTER_SPIRAL;
336
			}
337
			break;
338
		case HUNTER_CHASE:
339
						
340
			if (maxBOM == -1) {
341
				return HUNTER_CHASE;
342
			} else if (maxBOM == 4) {
343
				motor_l_set(FORWARD, 255);
344
				motor_r_set(FORWARD, 255);
345
				return HUNTER_CHASE;
346
			} else if (maxBOM == 3) {
347
				motor_l_set(FORWARD, 255);
348
				motor_r_set(FORWARD, 240);
349
				return HUNTER_CHASE;
350
			} else if (maxBOM == 5) {
351
				motor_l_set(FORWARD, 240);
352
				motor_r_set(FORWARD, 255);
353
				return HUNTER_CHASE;
354
			} else if (maxBOM < 3) {
355
				motor_l_set(FORWARD, 255);
356
				motor_r_set(FORWARD, 170);
357
				return HUNTER_CHASE;
358
			} else if (maxBOM > 5 && maxBOM <= 8) {
359
				motor_l_set(FORWARD, 170);
360
				motor_r_set(FORWARD, 255);
361
				return HUNTER_CHASE;
362
			} else if (maxBOM > 8 && maxBOM < 12) {
363
				motor_l_set(BACKWARD, 255);
364
				motor_r_set(FORWARD, 255);
365
				return HUNTER_CHASE;
366
			} else {
367
				motor_l_set(FORWARD, 255);
368
				motor_r_set(BACKWARD, 255);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff