Project

General

Profile

Revision 1809

Added by Joel Rey about 14 years ago

Woking version

View differences:

trunk/code/behaviors/formation_control/circle_spacing/circle_spacing.c
1 1
#include <dragonfly_lib.h>
2 2
#include <wl_basic.h>
3 3
#include<encoders.h>
4
#include "circle_spacing.h"
4 5

  
6
enum role_e {MASTER,SLAVE};
7
enum state_e {INIT, ID, MAPPING, PLANNING, WAIT, SENDING, RECIEVING, FINISH};
5 8

  
9
enum role_e role = SLAVE;
10
enum state_e current_state = INIT;
11
enum state_e next_state = INIT;
12

  
13
int used[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};  // if a robot is here, the value of the indice equal to its id is 1, esle 0
14
int map[17] = {20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20};  // Angular position of the robot which id equals the indice (20 for not here)
15
int neighbour[17] = {20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20}; // clockwise neighbour
16
int gap[17] = {20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20};  // gap to the left of the robot 
17
int stop = 0;
18
struct vector slave_position;
19
int desired_max_bom;
20
int bom_max_counter;
21
int robotid;
22
int centerid = 0;
23
int robotsRecieved=0;
24
int target_slave = 0;
25

  
26

  
27
void set_desired_max_bom(int desired_angle)
28
{
29
	if (desired_angle >= 348 || desired_angle < 11) desired_max_bom = 0;
30
	if (desired_angle >= 11 && desired_angle < 33) desired_max_bom = 1;
31
	if (desired_angle >= 33 && desired_angle < 56) desired_max_bom = 2;
32
	if (desired_angle >= 56 && desired_angle < 78) desired_max_bom = 3;
33
	if (desired_angle >= 78 && desired_angle < 101) desired_max_bom = 4;
34
	if (desired_angle >= 101 && desired_angle < 123) desired_max_bom = 5;
35
	if (desired_angle >= 123 && desired_angle < 145) desired_max_bom = 6;
36
	if (desired_angle >= 145 && desired_angle < 167) desired_max_bom = 7;
37
	if (desired_angle >= 167 && desired_angle < 190) desired_max_bom = 8;
38
	if (desired_angle >= 190 && desired_angle < 212) desired_max_bom = 9;
39
	if (desired_angle >= 212 && desired_angle < 235) desired_max_bom = 10;
40
	if (desired_angle >= 235 && desired_angle < 257) desired_max_bom = 11;
41
	if (desired_angle >= 257 && desired_angle < 280) desired_max_bom = 12;
42
	if (desired_angle >= 280 && desired_angle < 302) desired_max_bom = 13;
43
	if (desired_angle >= 302 && desired_angle < 325) desired_max_bom = 14;
44
	if (desired_angle >= 325 && desired_angle < 348) desired_max_bom = 15;
45
}
46

  
47
// collects the angular position of the slave robots by making them switch their bom one by one.
48

  
49
void map_slaves()
50
{
51
	int bom_max;
52
	
53
	for(int i=0; i<17; i++)
54
	{
55
		if(used[i])
56
		{
57
			send2(CIRCLE_ACTION_MAP,i);
58
			delay_ms(1000);
59
			
60
			do
61
			{	
62
				bom_refresh(BOM_ALL);
63
				bom_max = bom_get_max();
64
			}
65
			while(bom_max == -1);
66
				
67
			map[i] = bom_max;
68
			send2(CIRCLE_ACTION_DONE,i);
69
		}
70
	}
71
	
72
	usb_puts("Map: \r\n");
73
	for(int i=0; i<17; i++)
74
	{
75
		usb_puti(map[i]);
76
		usb_puts("\r\n");
77
	}
78
}
79

  
80
void plan()
81
{
82
	static int k = 0;
83
	
84
	target_slave++;
85
	
86
	if(target_slave>16) 
87
	{
88
		next_state = FINISH;
89
		orb1_set_color(YELLOW);
90
	}
91
	else if(used[target_slave]) 
92
	{
93
		k++;
94
		usb_puts("K: ");
95
								usb_puti(k);
96
								usb_puts("\r\n");
97
		set_desired_max_bom(360/robotsRecieved*k);
98
		send2(CIRCLE_ACTION_MOVE,target_slave);
99
		delay_ms(500);
100
		next_state = SENDING;
101
	}
102
	
103
	
104
}
105

  
106
void plan2()
107
{
108
	int order[robotsRecieved];
109
	int check[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
110
	
111
	
112
	
113
	for(int i=0; i<robotsRecieved; i++)
114
	{
115
		int current;
116
		int min = 20;
117
		for(int j=0; j<17; j++)
118
		{
119
			if(map[j]<min && !check[j])
120
			{
121
				current = j;
122
				min = map[j];
123
				usb_puts("Test \r\n");
124
			}
125
			
126
		}
127
		
128
		order[i]=current;
129
		check[current]=1;
130
			
131
			usb_puti(i);
132
			usb_puts("  Current: ");
133
			usb_puti(current);
134
			usb_puts("\r\n");
135
	}
136
	usb_puts("Order: \r\n");
137
	for(int i=0; i<robotsRecieved; i++)
138
	{	usb_puti(i);
139
		usb_puts("   ");
140
		usb_puti(order[i]);
141
		usb_puts("\r\n");
142
	}
143
	
144
	for(int i=0; i<robotsRecieved; i++)
145
	{
146
		if(i==robotsRecieved-1) gap[order[i]]= map[order[0]] - map[order[i]] +16; // closes the loop
147
		else gap[order[i]]= map[order[i+1]] - map[order[i]];
148
	}
149
	
150
	usb_puts("Gap: \r\n");
151
	for(int i=0; i<17; i++)
152
	{
153
		usb_puti(gap[i]);
154
		usb_puts("\r\n");
155
	}
156
	
157
	for(int i=0; i<robotsRecieved; i++)
158
	{
159
		if(i==0) neighbour[order[i]]=order[robotsRecieved-1];
160
		else neighbour[order[i]]=order[i-1];
161
		
162
	}
163
	
164
	usb_puts("Neighbour: \r\n");
165
	for(int i=0; i<17; i++)
166
	{
167
		usb_puti(neighbour[i]);
168
		usb_puts("\r\n");
169
	}
170
}
171

  
172
void plan3()
173
{
174
	static int move_counter =0;
175
	int max = 0;
176
	int move_gap = 0;
177
	
178
	for(int j=0; j<17; j++)
179
	{
180
		if(gap[j]>max && gap[j]!=20)
181
		{
182
			target_slave = j;
183
			max = gap[j];
184
		}
185
			
186
	}
187
	
188
	move_counter++;
189
	if(move_counter==robotsRecieved) next_state = FINISH;
190
	else
191
	{
192
		move_gap = gap[target_slave]-16/robotsRecieved;
193
		desired_max_bom = map[target_slave]+move_gap;
194
		if(desired_max_bom>15) desired_max_bom-=16;
195
		gap[target_slave]-=move_gap;
196
		gap[neighbour[target_slave]] += move_gap;
197
		usb_puts("Target:");
198
		usb_puti(target_slave);
199
		usb_puts("  Destination:");
200
		usb_puti(desired_max_bom);
201
		usb_puts("\n\r");
202
		send2(CIRCLE_ACTION_MOVE,target_slave);
203
		delay_ms(500);
204
		next_state = SENDING;
205
	}
206
}
207

  
208

  
209
void switch_state ()
210
{
211
	switch(role)
212
	{
213
		case MASTER:
214
			switch(current_state)
215
			{
216
				case PLANNING:
217
					orb1_set_color(RED);
218
					break;
219
				case SENDING:
220
					bom_off();
221
					break;
222
			}
223
			
224
			
225
			
226
			switch(next_state)
227
			{
228
				case ID:
229
					send2(CIRCLE_ACTION_EXIST,robotid);
230
					break;
231
					
232
				case MAPPING:
233
					map_slaves();
234
					plan2();
235
					break;
236
					
237
				case PLANNING:
238
				
239
					orb1_set_color(PINK);
240
				
241
					break;
242
					
243
				case SENDING:
244
					bom_on();
245
					break;
246
				
247
				case RECIEVING:
248
					break;
249
			}
250
			break;
251
			
252
		case SLAVE:
253
			switch(current_state)
254
			{
255
				case SENDING:
256
					bom_off();
257
					break;
258
					
259
			}
260
			
261
			
262
			
263
			switch(next_state)
264
			{
265
				case ID:
266
					
267
					break;
268
					
269
				case MAPPING:
270
					orb1_set_color(PINK);
271
					break;
272
					
273
				case SENDING:
274
					bom_on();
275
					break;
276
				
277
				case RECIEVING:
278
					bom_off();
279
					break;
280
				case FINISH:
281
					motor_l_set(FORWARD,0);
282
					motor_r_set(FORWARD,0);
283
					orb1_set_color(YELLOW);
284
					break;
285
			}
286
			break;
287
	}
288
	
289
	
290
	current_state = next_state;
291
}
292

  
293

  
294
void send2(char arg0, char arg1)
295
{
296
	char send_buffer[2];
297
	send_buffer[0]=arg0;
298
	send_buffer[1]=arg1;
299
	wl_basic_send_global_packet(42,send_buffer,2);
300
}
301

  
302

  
303
int main(void)
304
{
305

  
306

  
307
	int sending_counter = 0;
308
	int waitingCounter=0;
309
	int max_bom;
310
	
311
    /* Initialize dragonfly board */
312
	
313
    dragonfly_init(ALL_ON);
314
	xbee_init();
315
	wl_basic_init_default();
316
	wl_set_channel(12);
317
    int data_length;
318
	unsigned char *packet_data;
319
	char send_buffer[2];
320
	
321

  
322
	robotid = get_robotid();
323
	
324
	if(wheel()>100)
325
	{
326
		role = MASTER;
327
	}
328
	
329
	
330
	if(role == MASTER) {orb2_set_color(RED); set_desired_max_bom(30);}
331
	else orb2_set_color(BLUE);
332
	
333
	
334
	while(1)
335
	{
336
	
337
	
338
		bom_refresh(BOM_ALL);
339
		
340
		
341
		if(current_state != next_state) switch_state();
342
		
343
		
344
		switch(role)
345
		
346
		{
347
			case MASTER:
348
		
349

  
350
				switch(current_state)
351
				{	
352
					case INIT:
353
						next_state = ID;
354
						break;
355
					case ID:
356
						
357
						waitingCounter++;
358
	
359
					
360
						if(packet_data!=0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_ACK)
361
						{
362

  
363
							//only add to robots seen if you haven't gotten an ACK from this robot
364
							if(used[packet_data[1]]==0)
365
							{
366
								robotsRecieved++;
367
								used[packet_data[1]] = 1;
368

  
369
								usb_puts("Added: ");
370
								usb_puti(packet_data[1]);
371
								usb_puts("\r\n");
372
							}
373

  
374
							// NEW: sends a packet to each robot it receives telling them to be done.
375
							send2(CIRCLE_ACTION_GOTYOU,packet_data[1]);
376
						}
377
						if(waitingCounter >= 300){
378
							next_state = MAPPING;
379
						}
380
						break;
381
						
382
					case MAPPING:
383
					
384
						next_state = PLANNING;
385
						break;
386
						
387
					case PLANNING:
388
						plan3();
389
						break;
390
						
391
					case SENDING:
392
					
393
						if(sending_counter++>4)	// clock for switching the BOMs between the master and slave
394
						{
395
							next_state = RECIEVING;
396
							sending_counter = 0;
397
							send2(CIRCLE_ACTION_CHANGE,target_slave);
398
						}
399
						break;
400
						
401
					case RECIEVING:
402
					
403
						if(sending_counter++>4)	// clock for switching the BOMs between the master and slave
404
						{
405
							next_state = SENDING;
406
							sending_counter = 0;
407
							send2(CIRCLE_ACTION_CHANGE,target_slave);
408
						}
409
						
410
						max_bom = bom_get_max();
411
						//usb_puts("bom_get_max : ");
412
						//usb_puti(max_bom);
413
						//usb_puts("\n\r");
414
					
415
						if(max_bom == desired_max_bom)
416
						{
417
							bom_max_counter ++;
418
							if(bom_max_counter>2)                 // only stops the slave if two consecutive boms reading give the desired bom as the max one. Filters the noise.
419
							{
420
							send2(CIRCLE_ACTION_STOP,target_slave);
421
							next_state = PLANNING;
422
							bom_max_counter = 0;
423
							}
424
						
425
						}
426
						else bom_max_counter = 0;
427
						break;
428
					
429
				}
430
				
431
				break;
432
			
433
		
434
		
435
			case SLAVE:
436
			
437
				if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_STOP && packet_data[1] == robotid) next_state = FINISH;
438
				
439
	
440
			
441
				switch(current_state)
442
				{
443
					case INIT:
444
						next_state = ID;
445
						break;
446
						
447
					case ID:
448
						
449
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_EXIST)
450
						{
451
							centerid = packet_data[1];
452

  
453
							send2(CIRCLE_ACTION_ACK,robotid);
454

  
455
							next_state = MAPPING;
456
						
457
						}
458
						break;
459
						
460
					case MAPPING:
461
						
462
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_MAP && packet_data[1] == robotid)
463
						{
464
							bom_on();
465
						}
466
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_DONE && packet_data[1] == robotid)
467
						{
468
							bom_off();
469
							next_state = PLANNING;
470
						}
471
					
472
					case PLANNING:
473
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_MOVE && packet_data[1] == robotid)
474
						{
475
							next_state = RECIEVING;
476
						}
477
						break;
478
							
479
					case SENDING:
480
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_CHANGE && packet_data[1] == robotid)
481
							next_state = RECIEVING;	
482
						break;
483
						
484
					case RECIEVING:
485
					
486
						if(packet_data != 0 && data_length>=2 && packet_data[0]==CIRCLE_ACTION_CHANGE && packet_data[1] == robotid)
487
							next_state = SENDING;
488
						
489
						if(stop)
490
						{
491
						motor_l_set(FORWARD,0);
492
						motor_r_set(FORWARD,0);
493
						orb1_set_color(GREEN);
494
						}
495
						
496
						else
497
						{
498
							max_bom = bom_get_max();
499
							/*usb_puts("bom_get_max : ");
500
							usb_puti(max_bom);
501
							usb_puts("/n/r");*/
502
						
503
						
504
						   if(max_bom == 8)
505
						   {	
506
							orb2_set_color(BLUE);
507
							motor_r_set(FORWARD,180);
508
							motor_l_set(FORWARD,180);
509
							
510
						   }
511
						   else if(max_bom == 7 || max_bom == 6 || max_bom == 5)
512
						   {
513
							motor_l_set(FORWARD,180);
514
							motor_r_set(FORWARD,0);
515
							}
516
							else if(max_bom == -1);
517
						   else 
518
						   {
519
							orb2_set_color(GREEN);
520
							motor_l_set(FORWARD,0);
521
							motor_r_set(FORWARD,180);
522
							}
523
						}
524
						break;
525
		
526
				}
527
			
528
				break;
529
		}
530
		
531
		packet_data = wl_basic_do_default(&data_length);
532
		delay_ms(10);
533
	}
534
	
535
  
536
  return 0;
537
  
538
  
539
	
540
	
541
}
542

  
543

  
544

  
545

  
546

  
547

  
548

  
549

  
550

  
551

  
552

  
553

  
554

  
555

  
556

  
557

  
558

  
559

  
560

  
561

  
562

  
563

  
564

  
565

  
566

  
567

  
568

  
569

  
570

  
571

  
572

  
573

  
574

  
575

  
576
/*
577

  
578

  
579
//   Code working for a single slave orbiting around the master, with only one direction  (tested on 07.04.2010)
580

  
581

  
582
#include <dragonfly_lib.h>
583
#include <wl_basic.h>
584
#include<encoders.h>
585

  
586

  
6 587
int master = 0;
7 588
int sending = 0;
8 589
int stop = 0;
......
59 640
	
60 641
	int sending_counter = 0;
61 642
	
62
    /* Initialize dragonfly board */
643
   // Initialize dragonfly board 
63 644
	
64 645
    dragonfly_init(ALL_ON);
65 646
	xbee_init();
......
70 651
	char send_buffer[2];
71 652
	
72 653
	
654
	if(wheel()>100)
655
	{
656
		master = 1;
657
	}
658
	
659
	
73 660
	if(master) {orb1_set_color(RED); set_desired_max_bom(30);}
74 661
	else orb1_set_color(BLUE);
75 662
	
......
151 738
				else
152 739
				{
153 740
					int max_bom = bom_get_max();
154
					/*usb_puts("bom_get_max : ");
155
					usb_puti(max_bom);
156
					usb_puts("/n/r");*/
741
					
157 742
				
158 743
				
159 744
				   if(max_bom == 8)
......
197 782

  
198 783

  
199 784

  
785
*/
200 786

  
201

  
202

  
trunk/code/behaviors/formation_control/circle_spacing/Makefile
11 11
USE_WIRELESS = 1
12 12

  
13 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)
14
AVRDUDE_PORT = $(shell if uname -s |grep -i w32 >/dev/null; then echo 'COM4:'; else echo '/dev/ttyUSB0'; fi)
15 15

  
16 16
else
17 17
COLONYROOT := ../$(COLONYROOT)

Also available in: Unified diff