Project

General

Profile

Revision 1569

Added by John Sexton over 14 years ago

Cleaning up ir_branch to Make correctly.

View differences:

branches/ir_branch/behaviors/library_test/main.c
1
#include <dragonfly_lib.h>
2
//#include "smart_run_around_fsm.h"
3

  
4
// Martin "deffi" Herrmann Test
5

  
6
static void oset(uint8_t r,uint8_t g,uint8_t b)
7
{
8
    orbs_set(r,g,b,255-r,255-g,255-b);
9
}
10

  
11
static void color_circle (void)
12
{
13
    while(1)
14
    {
15
        for (uint8_t part=0; part<6; ++part)
16
        {
17
            for (uint8_t up=0; up<255; ++up)
18
            {
19
                uint8_t dn=255-up;
20
                uint8_t on=255;
21
                uint8_t of=0;
22

  
23
                if (1)
24
                {
25
                    // Maximum brightness mode
26
                    switch (part)
27
                    {
28
                        case 0: oset (on, up, of); break;
29
                        case 1: oset (dn, on, of); break;
30
                        case 2: oset (of, on, up); break;
31
                        case 3: oset (of, dn, on); break;
32
                        case 4: oset (up, of, on); break;
33
                        case 5: oset (on, of, dn); break;
34
                    }
35
                }
36
                else
37
                {
38
                    // Constant brightness mode (not very constant though)
39
                    switch (part%3)
40
                    {
41
                        case 0: oset (dn, up, of); break;
42
                        case 1: oset (of, dn, up); break;
43
                        case 2: oset (up, of, dn); break;
44
                    }
45
                }
46

  
47
                delay_ms (2);
48
            }
49
        }
50
    }
51
}
52

  
53
static void acl(void)
54
{
55
#define redval 255
56
#define greenval 150
57
#define interval 1300
58
#define flash 20
59
#define pause 200
60

  
61
#define def do { orb1_set(redval,0,0); orb2_set(0,greenval,0); } while (0)
62
#define wht do { orb_set(255,255,255); } while (0)
63

  
64
    while (1)
65
    {
66
        wht; delay_ms (flash);
67
        def; delay_ms (pause-flash);
68
        wht; delay_ms (flash);
69
        def; delay_ms (pause-flash);
70
        def; delay_ms (interval-2*pause-2*flash);
71
    }
72
}
73

  
74
int main(void) {
75
    //  dragonfly_init(ALL_ON);
76
    dragonfly_init(0);
77

  
78
    usb_init ();
79
    usb_puts ("Startup\r\n");
80

  
81

  
82
    //encoders_init ();
83

  
84
    //analog_init(ADC_START);
85
    //analog_init(0);
86

  
87
    //range_init();
88

  
89
    //DDRF=2;
90

  
91
    //motors_init ();
92
    //motor2_set (FORWARD, 64);
93

  
94
    //orb_init_binary ();
95
    orb_init_pwm ();
96

  
97
    if (false)
98
    {
99
        orbs_set (255, 0, 0, 0, 0, 0); delay_ms (500);
100
        orbs_set (0, 255, 0, 0, 0, 0); delay_ms (500);
101
        orbs_set (0, 0, 255, 0, 0, 0); delay_ms (500);
102
        orbs_set (0, 0, 0, 255, 0, 0); delay_ms (500);
103
        orbs_set (0, 0, 0, 0, 255, 0); delay_ms (500);
104
        orbs_set (0, 0, 0, 0, 0, 255); delay_ms (500);
105
    }
106

  
107
    if (false)
108
    {
109
        orb_set (1,1,1);
110
        while (1)
111
        {
112
            SYNC
113
            {
114
                for (uint8_t m=0; m<100; ++m)
115
                {
116
                    _delay_us(10);
117
                }
118
            }
119
        }
120
    }
121

  
122
    if (false)
123
    {
124
        while (1)
125
        {
126
            for (uint8_t x=0; x<255; ++x)
127
            {
128
                orbs_set (x, 1, 2, 3, 4, 5);
129

  
130
                for (uint8_t n=0; n<80; ++n)
131
                {
132
                    SYNC
133
                    { for (uint8_t m=0; m<1; ++m) _delay_us(50); }
134
                }
135
            }
136

  
137
            for (uint8_t x=255; x>0; --x)
138
            {
139
                orbs_set (x, 1, 1, 1, 1, 1);
140
                delay_ms (4);
141
            }
142
        }
143
    }
144

  
145
    if (false)
146
    {
147
        //orbs_set (2,4,6,8,10,12);
148
        //orbs_set (32, 64, 96, 128, 160, 192);
149
        orbs_set (128,128,128,128,128,128);
150
        while (1);
151
    }
152

  
153
    if (false)
154
    {
155
        if (!button2_read ())
156
        {
157
            orb_set_mode (orb_mode_pwm);
158
            orb_disable_timer ();
159

  
160
            while (1)
161
            {
162
                // Continuously call the sorting routine for timing test
163
                for (uint8_t i=0; i<200; ++i)
164
                {
165
                    orbs_set (10,20,30,40,50,60);
166
                    delay_ms (10);
167
                }
168

  
169
                for (uint8_t i=0; i<200; ++i)
170
                {
171
                    orbs_set (60,50,40,30,20,10);
172
                    delay_ms (10);
173
                }
174
            }
175
        }
176
        else
177
        {
178
            while (button2_read ());
179
            if (button1_read ())
180
            {
181
                color_circle ();
182
            }
183
            else
184
            {
185
                acl ();
186
            }
187
        }
188
    }
189

  
190

  
191

  
192
    // Do some lighting
193
    if (!button2_read ())
194
        color_circle ();
195
    else
196
        acl ();
197

  
198
}
199

  
branches/ir_branch/behaviors/library_test/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/ir_branch/behaviors/hunter_prey/ref/Makefile
1
CC = gcc
2
CFLAGS = -Wall -g
3

  
4
all: ref
5

  
6
ref: *.c ../../libwireless/lib/*.c 
7
	$(CC) $(CFLAGS) *.c -L../../libwireless/lib -o ref -DWL_DEBUG -lwireless -lpthread -ggdb
8

  
9
clean:
10
	rm -f *.o ref ../lib/*.o
11

  
branches/ir_branch/behaviors/hunter_prey/ref/main.c
1
#include <stdlib.h>
2
#include <stdio.h>
3
#include <time.h>
4
#include <unistd.h>
5
#include "../../libwireless/lib/wl_basic.h"
6
#include "../../libwireless/lib/wireless.h"
7
#include "../hunter_prey.h"
8

  
9
#define TYPE 42	// packet type for wireless communication
10

  
11
#define NUM_BOTS 17
12
#define TOTAL_GAME_TIME 600*5 //in 100 ms intervals
13

  
14
void packet_receive(char type, int source, unsigned char* packet, int length);
15

  
16
volatile unsigned int preyTime[20];
17
volatile int preyBot=-1;
18

  
19
void waitKey(void) {
20
  unsigned char buf[10];
21

  
22
  //read from stdin
23
   while(read(0, buf, 10)==10) {
24
     printf("!");
25
     fflush(stdout);
26
   }
27

  
28
  while(getchar()==-1);
29
}
30

  
31
void print_stats(void) {
32

  
33
  int i=0;
34

  
35
  for(i=0;i<NUM_BOTS;i++) {
36
    printf("%5d ", preyTime[i]);
37
  }
38

  
39
  printf("\n");
40

  
41
}
42

  
43
int main(int argc, char *argv[])
44
{
45
    char send_buffer[2];    // holds data to send
46
    int data_length;	// length of data received
47
    unsigned char *packet_data;	// data received
48
    int ret;
49
    int i;
50
    int winner, maxTime=0;
51

  
52
    unsigned int channel = 0xF;
53

  
54
    struct timespec delay, rem;
55

  
56
    delay.tv_sec = 0;
57
    delay.tv_nsec = 100000000;
58

  
59

  
60
    if(argc > 1) {
61
      channel = atoi(argv[1]);
62
    }
63

  
64
    printf("using wireless channel %d\n", channel);
65

  
66
    wl_set_com_port("/dev/ttyUSB0");
67
    // set up wireless
68
    ret = wl_basic_init(&packet_receive);
69

  
70
    if(ret) {
71
      printf("ERROR: wl_basic_init failed. %d\n", ret);
72
      return ret;
73
    }
74
    //wl_set_channel(channel);
75

  
76
    for(i=0;i<NUM_BOTS;i++) {
77
      preyTime[i]=0;
78
    }
79

  
80
    ret = 0;    
81
    i=0;
82

  
83
    printf("ready\n");
84

  
85
    //TODO: use rtc to make this more accurate
86
    while(i < TOTAL_GAME_TIME) {
87
      wl_do();
88

  
89
      if(ret==0) {
90
	ret = nanosleep(&delay, &rem);
91
      }
92
      else {
93
	ret = nanosleep(&rem, &rem);
94
      }
95

  
96
      //update counts when we have waited at least enough time
97
      if(ret == 0 && preyBot >= 0) {
98
	preyTime[preyBot]++;
99

  
100
	if(i==0) { //time starts on the first real tag
101
	  printf("\nThe race is on!\n");
102
	}
103
	i++;
104
      }
105

  
106
      if((TOTAL_GAME_TIME - i)%600 == 0) {
107
	printf("%d minutes remaining!\n", (TOTAL_GAME_TIME - i)/600);
108
      }
109

  
110
      if(i%10==0) {
111
	print_stats();
112
	if( TOTAL_GAME_TIME - i <= 100)
113
	  printf("%d...\n", (TOTAL_GAME_TIME - i)/10);
114
      }
115
    }
116

  
117

  
118
    for(i=1;i<NUM_BOTS;i++) {
119
      if(preyTime[i] > maxTime) {
120
	maxTime = preyTime[i];
121
	winner = i;
122
      }
123
    }
124

  
125
    printf("\n\GAME OVER!n\nAAAAAAAAAAND the winner is\nBOT %d!!!!\n", winner);
126

  
127
    return 0;
128
}
129

  
130
void packet_receive(char type, int source, unsigned char* packet, int length)
131
{
132

  
133
  if(type==42 && length>=2){
134
    if(packet[0] == HUNTER_PREY_ACTION_TAG) {
135
      //TODO: check tag
136

  
137
    }
138
    else if(packet[0] == HUNTER_PREY_ACTION_ACK) {
139

  
140
      preyBot = packet[1];
141
      printf("bot %d is prey!\n", preyBot);
142

  
143
    }
144
    else {
145
      printf("got invalid packet! %c%d\n", packet[0], packet[1]);
146
    }
147
  }
148
  else {
149
    printf("got unknown packet! type=%d, length=%d\n", type, length);
150
  }
151
}
152

  
branches/ir_branch/behaviors/hunter_prey/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/ir_branch/behaviors/hunter_prey/john/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/ir_branch/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 					15
18

  
19
#define BACK_THRESHOLD 			-5000
20
#define TURN_DIST						1024
21
#define IR_DIST_THRESHOLD		200
22

  
23
/* State Macros */
24

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

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

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

  
44

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

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

  
53
/*  Data buffer used to send packets */
54
char send_buffer[1];
55

  
56
int main(void)
57
{
58

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

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

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

  
70

  
71
    /* ****** CODE HERE ******* */
72

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

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

  
83
		while (1) {
84

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

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

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

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

  
109
					if (packet_data && data_length == 2
110
							&& packet_data[0] == HUNTER_PREY_ACTION_ACK) {
111
						/* If we've received an ACK, we need to wait */
112
						state = TOP_HUNTER_WAIT;
113
					} else {
114
						/* Record some sensor readings and check if we can TAG */
115
						bom_refresh(BOM_ALL);
116
						frontIR = range_read_distance(IR2);
117
						maxBOM = get_max_bom();
118
						if (hunter_prey_tagged(maxBOM, frontIR) || button1_read()) {
119
							state = TOP_HUNTER_TAG;
120
						} else {
121
							/* If we haven't tagged, then enter hunter FSM */
122
							hunter_state = hunter_FSM(hunter_state, maxBOM, frontIR);
123
						}
124
					}
125
					break;
126
				case TOP_HUNTER_TAG:
127
					orbs_set_color(RED, PURPLE);
128
					delay_ms(500);
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(5000);
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
			return PREY_BACKING;
250
			break;
251
		case PREY_BACKING:
252
			if (encoder_get_x(LEFT) < BACK_THRESHOLD) {
253
				motor_l_set(BACKWARD, 255);
254
				motor_r_set(FORWARD, 255);
255
				encoder_rst_dx(RIGHT);
256
				return PREY_TURN;
257
			} else {
258
				return PREY_BACKING;
259
			}
260
			break;
261
		case PREY_TURN:
262
			if (encoder_get_x(RIGHT) > TURN_DIST) {
263
				return PREY_AVOID;				
264
			} else {
265
				return PREY_TURN;
266
			}
267
			break;
268
		case PREY_AVOID:
269
			rangeVals[0] = range_read_distance(IR1);
270
			rangeVals[1] = range_read_distance(IR2);
271
			rangeVals[2] = range_read_distance(IR3);
272

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

  
296
	}
297
	
298
	return prey_state;
299

  
300
}
301

  
302

  
303
/*
304
 * hunter_FSM - Hunter finite state machine which defaults to spiraling
305
 * 		outwards until the BOM can locate the prey. Once the BOM locates
306
 * 		the prey, chase the prey as fast as possible.
307
 *
308
 * Arguments:
309
 * 	hunter_state - Current hunter state.
310
 * 	maxBOM - Current maximum BOM value.
311
 * 	frontIR - Current front IR rangefinder reading value.
312
 *
313
 * returns - The new state of the hunter state machine.
314
 */
315

  
316
int hunter_FSM(int hunter_state, int maxBOM, int frontIR) {
317

  
318
	switch(hunter_state) {
319

  
320
		case HUNTER_SPIRAL:
321
			if (maxBOM != -1) {
322
				return HUNTER_CHASE;
323
			} else {
324
				motor_l_set(FORWARD, 170);
325
				motor_r_set(FORWARD, 190);
326
				return HUNTER_SPIRAL;
327
			}
328
			break;
329
		case HUNTER_CHASE:
330
			
331
			/* A large look-up table to set the speed of the motors based on
332
			 * where the prey robot is. */
333
			if (maxBOM == -1) {
334
				return HUNTER_CHASE;
335
			} else if (maxBOM == 4) {
336
				motor_l_set(FORWARD, 255);
337
				motor_r_set(FORWARD, 255);
338
				return HUNTER_CHASE;
339
			} else if (maxBOM == 3) {
340
				motor_l_set(FORWARD, 255);
341
				motor_r_set(FORWARD, 240);
342
				return HUNTER_CHASE;
343
			} else if (maxBOM == 5) {
344
				motor_l_set(FORWARD, 240);
345
				motor_r_set(FORWARD, 255);
346
				return HUNTER_CHASE;
347
			} else if (maxBOM < 3) {
348
				motor_l_set(FORWARD, 255);
349
				motor_r_set(FORWARD, 170);
350
				return HUNTER_CHASE;
351
			} else if (maxBOM > 5 && maxBOM <= 8) {
352
				motor_l_set(FORWARD, 170);
353
				motor_r_set(FORWARD, 255);
354
				return HUNTER_CHASE;
355
			} else if (maxBOM > 8 && maxBOM < 12) {
356
				motor_l_set(BACKWARD, 255);
357
				motor_r_set(FORWARD, 255);
358
				return HUNTER_CHASE;
359
			} else {
360
				motor_l_set(FORWARD, 255);
361
				motor_r_set(BACKWARD, 255);
362
				return HUNTER_CHASE;
363
			}
364
			break;
365
		default:
366
			return HUNTER_SPIRAL;
367
			break;
368

  
369
	}
370

  
371
	return hunter_state;
372

  
373
}
branches/ir_branch/behaviors/hunter_prey/john/hunter_prey.c
1
#include "hunter_prey.h"
2
#include <dragonfly_lib.h>
3

  
4
#define TAG_TIME 3
5
#define TAG_RANGE 200
6

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

  
9

  
10
/*
11
 * The criteria for tagging are the following:
12
 *   * The max bom is betweed 1 and 7
13
 *   * The front rangefinder reads less than TAG_RANGE
14
 *   * -1 values from the rangefinder are ignored
15
 *   * These conditions are met across TAG_TIME calls to this function
16
 */
17

  
18
unsigned char hunter_prey_tagged(int max_bom, int frontRange) {
19

  
20
  static int onTarget = 0;
21

  
22
  if(max_bom < 7 && max_bom > 1 && frontRange > 0 && frontRange < TAG_RANGE) {
23
    if(onTarget == 0) {
24
      onTarget = TAG_TIME;
25
      usb_puts("On target!\n");
26
    }
27
    else {
28
      if(--onTarget <= 0) {
29
	onTarget = 0;
30
	usb_puts("TAG!\n");
31
	return 1;
32
      }
33
    }
34
  }
35
  else{
36
    //don't reset onTarget because the robot got too close
37
    if(frontRange > 0)
38
      onTarget = 0;
39
  }
40

  
41
  return 0;
42

  
43
}
branches/ir_branch/behaviors/hunter_prey/john/hunter_prey.h
1
#ifndef _HUNTER_PREY_H
2
#define _HUNTER_PREY_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 HUNTER_PREY_ACTION_TAG 'T'
15
#define HUNTER_PREY_ACTION_ACK 'A'
16

  
17
unsigned char hunter_prey_tagged(int max_bom, int front_rangefinder);
18

  
19
#endif
branches/ir_branch/behaviors/hunter_prey/testbench/main.c
1
/* testbench for Lab 2 first checkpoint
2
 * determine whether robot under test complies with communication standard
3
 * to be conducted using XBee USB dongle
4
 */
5

  
6
/* The tests shall be as follows
7
 * 1. Receive a TAG, send an ACK
8
 * - Robot passes if it sends a tag and changes to prey state
9
 * 2. Send a TAG, receive an ACK
10
 * - Pass if sends ACK, changes to wait state, then hunter state
11
 * 3. Receive TAG, send slightly delayed (< 1s) ACK
12
 * - Pass if sends one and only one TAG packet (and changes state appropriately)
13
 * 4. Receive TAG, do not send ACK
14
 * - Pass if sends one and only one TAG packet (and does not change state)
15
 * 5. Receive TAG, send ACK to incorrect robot
16
 * - Pass if goes to wait state, then back to hunter state
17
 * 6. Simulate TAG from robot A to B, ACK from B to A
18
 * - Pass if ignores TAG, goes to wait then hunter in response to ACK
19
 */
20

  
21
#include <stdlib.h>
22
#include <stdio.h>
23
#include <unistd.h>
24
#include "../../libwireless/lib/wl_basic.h"
25
#include "../../libwireless/lib/wireless.h"
26
#include "hunter_prey.h"
27
#include <time.h>
28

  
29
#define TYPE 42	// packet type for wireless communication
30
#define ROBOTID 255 // make up a robot id because the PC doesn't have one
31

  
32

  
33
void waitKey() {
34
  unsigned char buf[10];
35

  
36
  //read from stdin
37
   while(read(0, buf, 10)==10) {
38
     printf("!");
39
     fflush(stdout);
40
   }
41

  
42
  while(getchar()==-1);
43
}
44

  
45
int main(int argc, char *argv[])
46
{
47
    char send_buffer[2];    // holds data to send
48
    int data_length;	// length of data received
49
    unsigned char *packet_data;	// data received
50
    int ret;
51

  
52
    unsigned int channel = 0xF;
53

  
54
    struct timespec delay8, rem;
55

  
56
    if(argc > 1) {
57
      channel = atoi(argv[1]);
58
    }
59

  
60
    printf("using wireless channel %d\n", channel);
61

  
62
    delay8.tv_sec = 2;
63
    delay8.tv_nsec = 800000000;
64

  
65
    wl_set_com_port("/dev/ttyUSB0");
66
    // set up wireless
67
    ret = wl_basic_init_default();
68

  
69
    if(ret) {
70
      printf("ERROR: wl_basic_init_default returned %d\n", ret);
71
      return ret;
72
    }
73

  
74
    ret = wl_set_channel(channel);
75

  
76
    if(ret) {
77
      printf("ERROR: set channel failed! %d\n", ret);
78
      return ret;
79
    }
80

  
81
    printf("Testing communications\n\n");
82

  
83
    // Receive TAG, send ACK
84
    printf("Receive TAG, send ACK... ");
85
    fflush(stdout);
86
    // Wait until we receive a packet
87
    while (!(packet_data = wl_basic_do_default(&data_length)));
88

  
89
    printf("got packet, validating and sending ack...");
90
    fflush(stdout);
91

  
92
    if (data_length > 2)
93
    {
94
	printf("Excessive TAG packet length... ");
95
	fflush(stdout);
96
    }
97

  
98
    if (data_length >= 2 && packet_data[0] == HUNTER_PREY_ACTION_TAG)
99
    {
100
	// send back an ACK
101
	send_buffer[0] = HUNTER_PREY_ACTION_ACK;
102
	send_buffer[1] = packet_data[1];
103
	printf("sending ack intended for robot %d\n", packet_data[1]);
104
	fflush(stdout);
105
	wl_basic_send_global_packet(TYPE, send_buffer, 2);
106

  
107
	printf("PASSED\n");
108
    }
109
    else
110
	printf("FAILED\n");
111

  
112
    printf("robot should be prey\nPress enter to continue...\n");
113
    waitKey();
114

  
115
    // Send a TAG, receive an ACK
116
    printf("Send TAG, wait for ACK... ");
117
    fflush(stdout);
118

  
119
    send_buffer[0] = HUNTER_PREY_ACTION_TAG;
120
    send_buffer[1] = ROBOTID;
121
    // robot number stays the same
122
    wl_basic_send_global_packet(TYPE, send_buffer, 2);
123

  
124
    // Wait for an ACK
125
    ret = nanosleep(&delay8, &rem);  // wait for 800 ms before sending ACK
126

  
127
    while(ret) {
128
      //      printf("nanosleep not done, needs to wait %ld more\n", rem.tv_nsec);
129
      ret = nanosleep(&rem, &rem);
130
    }
131

  
132
    data_length = -1;
133
    packet_data = wl_basic_do_default(&data_length);
134

  
135
    // Check ACK for presence and correctness
136
    if (!packet_data || data_length < 2 ||
137
	    packet_data[0] != HUNTER_PREY_ACTION_ACK ||
138
        packet_data[1] != ROBOTID) {
139
      printf("FAILED, packet=%p, len=%d\n", packet_data, data_length);
140
      if(data_length >= 2) {
141
	printf("\tpacket = [%c, %d]\n",packet_data[0], packet_data[1]);
142
      }
143
    }
144
    else
145
	printf("PASSED\n");
146

  
147
    printf("Robot should be Hunter\nPress enter to continue...\n");
148

  
149
    waitKey();
150

  
151
    // Receive a TAG, send a delayed ACK
152
    printf("Receive a TAG, send a delayed ACK... ");
153
    fflush(stdout);
154

  
155
    while (!(packet_data = wl_basic_do_default(&data_length)));
156

  
157
    if (data_length >= 2 && packet_data[0] == HUNTER_PREY_ACTION_TAG)
158
    {
159
        printf("got TAG, waiting...");
160
	fflush(stdout);
161
	// wait before sending ACK back
162
	//usleep(900000);
163
        delay8.tv_sec = 0;
164
        ret = nanosleep(&delay8, &rem);  // wait for 800 ms before sending ACK
165

  
166
	while(ret) {
167
	  printf(".");
168
	  fflush(stdout);//      printf("nanosleep not done, needs to wait %ld more\n", rem.tv_nsec);
169
	  ret = nanosleep(&rem, &rem);
170
	}
171

  
172

  
173
	if (wl_basic_do_default(&data_length))
174
	    printf("FAILED, got another TAG too soon\n");
175
	else
176
	{
177
	    // send packet
178
	    send_buffer[0] = HUNTER_PREY_ACTION_ACK;
179
	    send_buffer[1] = packet_data[1];
180
	    wl_basic_send_global_packet(TYPE, send_buffer, 2);
181

  
182
	    printf("PASSED\n");
183
	}
184
    }
185

  
186
    else
187
	printf("FAILED\n");
188

  
189

  
190
    printf("robot should be prey.\n Press Enter...\n");
191
    waitKey();
192

  
193
    printf("sending courtesy tag...");
194
    fflush(stdout);
195
    send_buffer[0] = HUNTER_PREY_ACTION_TAG;
196
    send_buffer[1] = ROBOTID;
197
    // robot number stays the same
198
    wl_basic_send_global_packet(TYPE, send_buffer, 2);
199
    printf("done.\nwaiting for ack...");
200
    fflush(stdout);
201

  
202
    while (!(packet_data = wl_basic_do_default(&data_length)));
203

  
204
    if (!packet_data || data_length < 2 ||
205
	    packet_data[0] != HUNTER_PREY_ACTION_ACK ||
206
	    packet_data[1] != ROBOTID)
207
      printf("FAILED, packet=%p, len=%d\n", packet_data, data_length);
208
    else
209
	printf("done\n");
210

  
211

  
212
    // Receive a TAG, never send an ACK
213
    printf("Receive TAG, never send ACK... ");
214
    fflush(stdout);
215

  
216
    while (!(packet_data = wl_basic_do_default(&data_length)));
217

  
218
    if (data_length >= 2 && packet_data[0] == HUNTER_PREY_ACTION_TAG)
219
    {
220

  
221
        printf("got TAG, monitoring for 5 seconds\n");
222
	fflush(stdout);
223
	delay8.tv_sec = 5;
224
	delay8.tv_nsec = 0;
225

  
226
	ret = nanosleep(&delay8, &rem);  // wait for 5 secs
227
	while(ret) {
228
	  //      printf("nanosleep not done, needs to wait %ld more\n", rem.tv_nsec);
229
	  ret = nanosleep(&rem, &rem);
230
	}
231

  
232
	if (wl_basic_do_default(&data_length))
233
	    printf("FAILED, robot is spamming\n");
234
	else
235
	    printf("PASSED\n");
236
    }
237

  
238
    else
239
	printf("FAILED\n");
240

  
241
    printf("robot should be hunter.\nPress enter...\n");
242

  
243
    waitKey();
244

  
245
    // Receive TAG, send ACK to incorrect robot
246
    printf("Receive TAG, send ACK to incorrect robot... ");
247
    fflush(stdout);
248

  
249
    // Wait until we receive a packet
250
    while (!(packet_data = wl_basic_do_default(&data_length)));
251

  
252
    if (data_length >= 2 && packet_data[0] == HUNTER_PREY_ACTION_TAG)
253
    {
254
	// send back an ACK
255
	send_buffer[0] = HUNTER_PREY_ACTION_ACK;
256
	send_buffer[1] = packet_data[1] + 1;
257
	wl_basic_send_global_packet(TYPE, send_buffer, 2);
258

  
259
	printf("PASSED\n");
260
    }
261
    else
262
	printf("FAILED\n");
263

  
264

  
265
    printf("robot should wait and then still be hunter.\nPress Enter...\n");
266
    waitKey();
267

  
268
    // Simulate TAG from robot A to B, ACK from robot B to A
269
    printf("Send TAG from robot A to B, ACK from B to A... ");
270
    fflush(stdout);
271

  
272
    // TAG
273
    send_buffer[0] = HUNTER_PREY_ACTION_TAG;
274
    send_buffer[1] = packet_data[1] - 1;    // robot other than testee
275
    wl_basic_send_global_packet(TYPE, send_buffer, 2);
276

  
277
    // ACK
278
    send_buffer[0] = HUNTER_PREY_ACTION_ACK;
279
    // send_buffer[1] stays the same
280
    wl_basic_send_global_packet(TYPE, send_buffer, 2);
281

  
282
    if (wl_basic_do_default(&data_length))
283
	printf("FAILED\n");
284
    else
285
	printf("PASSED\n");
286

  
287
    printf("robot should be waiting\n");
288

  
289
    return 0;
290
}
291

  
branches/ir_branch/behaviors/hunter_prey/testbench/hunter_prey.h
1
#ifndef _HUNTER_PREY_H
2
#define _HUNTER_PREY_H
3

  
4
#include <inttypes.h>
5

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

  
12
#define HUNTER_PREY_ACTION_TAG 'T'
13
#define HUNTER_PREY_ACTION_ACK 'A'
14

  
15
uint8_t hunter_prey_tagged(int max_bom, int front_rangefinder);
16

  
17
#endif
branches/ir_branch/behaviors/hunter_prey/testbench/Makefile
1
CC = gcc
2
CFLAGS = -Wall -g
3

  
4
all: testbench
5

  
6
testbench: *.c ../../libwireless/lib/*.c 
7
	$(CC) $(CFLAGS) *.c -L../../libwireless/lib -o testbench -DWL_DEBUG -lwireless -lpthread -ggdb
8

  
9
clean:
10
	rm -f *.o testbench ../lib/*.o
11

  
branches/ir_branch/behaviors/hunter_prey/abenico/smart_run_around_fsm.c
1
#include <dragonfly_lib.h>
2
#include "smart_run_around_fsm.h"
3

  
4
void run_around_init(void)
5
{
6
  //range_init();
7
  //orb_init();
8
 
9
  state = SRA_FORWARD;  // start out moving forward
10
  // initialize rangefinder values to 0
11
  d1 = 0, d2 = 0, d3 = 0, d4 = 0, d5 = 0;
12
}
13

  
14
/* evaluate rangefinder input and update state
15
 * call this function as often as possible to avoid collisions
16
 */
17
void run_around_FSM(void)
18
{
19
    /* TODO: find a better way to handle rangefinder input
20
     * robot should deal with -1s (obstacles too close or too far to detect)
21
     * in a way that keeps it from crashing or driving in circles
22
     */
23
    // do not update distances when rangefinders return -1
24
    // otherwise update distances with new rangefinder values
25
    int16_t temp;
26

  
27
    temp = range_read_distance(IR1);
28
    d1 = (temp == -1) ? d1 : temp;
29

  
30
    temp = range_read_distance(IR2);
31
    d2 = (temp == -1) ? d2 : temp;
32

  
33
    temp = range_read_distance(IR3);
34
    d3 = (temp == -1) ? d3 : temp;
35

  
36
    temp = range_read_distance(IR4);
37
    d4 = (temp == -1) ? d4 : temp;
38

  
39
    temp = range_read_distance(IR5);
40
    d5 = (temp == -1) ? d5 : temp;
41

  
42
    // update state based on rangefinder input
43
    if (d2 < IR2_DANGER)    // avoid frontal collision by turning in place
44
	state = SRA_SPIN;
45
    /* nowhere to turn, so don't
46
     * will probably need to turn around soon, but not yet
47
     */
48
    else if (d1 < IR13_DANGER && d3 < IR13_DANGER)
49
	state = SRA_FORWARD;
50
    // avoid left-side collision by turning right
51
    else if (d1 < IR13_DANGER || d5 < IR45_DANGER)
52
	state = SRA_RIGHT;
53
    // avoid right-side collision by turning left
54
    else if (d3 < IR13_DANGER || d4 < IR45_DANGER)
55
	state = SRA_LEFT;
56
    else if (d2 < IR2_INTEREST)	// should turn to avoid obstacle up ahead
57
    {
58
	if (d3 >= d1)	// more room on right
59
	    state = SRA_RIGHT;
60
	else	// more room on left
61
	    state = SRA_LEFT;
62
    }
63
    else    // no obstacles close by, so keep going straight
64
	state = SRA_FORWARD;
65

  
66
    /* Debugging via USB output */
67
/*     usb_puts("IR1: "); */
68
/*     usb_puti(d1); */
69
/*     usb_puts(" IR2: "); */
70
/*     usb_puti(d2); */
71
/*     usb_puts(" IR3: "); */
72
/*     usb_puti(d3); */
73
/*     usb_puts(" IR4: "); */
74
/*     usb_puti(d4); */
75
/*     usb_puts(" IR5: "); */
76
/*     usb_puti(d5); */
77
/*     usb_puts("\n\r"); */
78

  
79
    evaluate_state();	// take action on updated state
80
}
81

  
82
// behave according to current state
83
// TODO: adjust speeds after testing
84
void evaluate_state(void)
85
{
86
    switch (state)
87
    {
88
	case SRA_FORWARD:
89
	    //orb_set_color(GREEN);
90
	    move(220, 0);	// drive straight forward
91
	    break;
92
	case SRA_LEFT:
93
	    //orbs_set_color(GREEN, YELLOW);  // green on left side
94
	    move(HALF_SPD, NRML_TURN);	// drive forward and to the left
95
	    break;
96
	case SRA_RIGHT:
97
	    //orbs_set_color(YELLOW, GREEN);  // green on right side
98
	    move(HALF_SPD, -NRML_TURN);	// drive forward and to the right
99
	    break;
100
	case SRA_SPIN:
101
	    //orb_set_color(RED);
102
	    move(0, NRML_TURN);	// spin CCW without traveling
103
	    break;
104
	default:    // should never reach this
105
	    //orb_set_color(PURPLE);
106
	    move(0, 0);	// stop completely
107
    }
108
}
109

  
branches/ir_branch/behaviors/hunter_prey/abenico/hunter_prey.h
1
#ifndef _HUNTER_PREY_H
2
#define _HUNTER_PREY_H
3

  
4
#include <inttypes.h>
5

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

  
12
#define HUNTER_PREY_ACTION_TAG 'T'
13
#define HUNTER_PREY_ACTION_ACK 'A'
14

  
15
uint8_t hunter_prey_tagged(int max_bom, int front_rangefinder);
16

  
17
#endif
branches/ir_branch/behaviors/hunter_prey/abenico/smart_run_around_fsm.h
1
// smart_run_around_fsm.h
2
// required to run Smart Run Around functions
3
// declare functions and global variables
4

  
5
#ifndef _RUN_AROUND_FSM_H_
6
#define _RUN_AROUND_FSM_H_
7

  
8
// states (robot shall never move in reverse)
9
// these constants may be changed (but can't overlap) without effect
10
#define SRA_FORWARD 0   // drive straight forward
11
#define SRA_LEFT 1	// drive forward and to the left
12
#define SRA_RIGHT 2	// drive forward and to the right
13
#define SRA_SPIN 3	// turn without traveling (last resort if otherwise stuck)
14

  
15
/* conditions on rangefinders (in mm) informing state changes
16
 * distances are 50 greater than in real life, cannot be smaller than 100
17
 * naming format: SENSOR_URGENCY
18
 * changing these constants affects robot operation
19
 */
20
#define IR2_DANGER 150	// 10 cm: dangerously close to front
21
#define IR13_DANGER 200 // 15 cm: dangerously close to sides (looking ahead)
22
#define IR2_INTEREST 300    // 25 cm: notably close to front
23
#define IR45_DANGER 150	// dangerously close to side (looking sideways)
24

  
25
uint8_t state;	// current state of FSM: SRA_FORWARD, SRA_LEFT, SRA_RIGHT, SRA_SPIN
26
int16_t d1, d2, d3, d4, d5; // values returned by rangefinders
27

  
28
// initialize rangefinders and global variables
29
void run_around_init(void);
30

  
31
/* evaluate rangefinder input and update state
32
 * call this function as often as possible to avoid collisions
33
 */
34
void run_around_FSM(void);
35

  
36
// behave according to current state
37
void evaluate_state(void);
38

  
39
#endif
40

  
branches/ir_branch/behaviors/hunter_prey/abenico/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/ir_branch/behaviors/hunter_prey/abenico/main.c
1
#include <dragonfly_lib.h>
2
#include <wireless.h>
3
#include <wl_basic.h>
4
#include "smart_run_around_fsm.h"
5
#include "hunter_prey.h"
6

  
7
#define CHAN 0xC
8
#define ACK_PAUSE 5000
9

  
10
#define ROBOT_HUNTER 0
11
#define ROBOT_PREY 1
12
#define ROBOT_TAGGED 2
13
#define ROBOT_IDLE 3
14

  
15
void packet_receive(unsigned char* packet, int length);
16

  
17
volatile uint8_t robotState; // current state
18
volatile uint8_t tagger;    // id of tagging robot
19
uint8_t id; // my robot's id
20

  
21
void test_bom(void) {
22
  int i;
23
  int val;
24

  
25
  while(1) {
26
    bom_refresh(BOM_ALL);
27

  
28
    for(i=0; i<16; i++) {
29
      val = bom_get(i);
30
      usb_puti(val);
31
      usb_putc(' ');
32
    }
33

  
34
    usb_puts("| ");
35

  
36
    usb_puti(range_read_distance (IR1));
37
    usb_putc(' ');
38
    usb_puti(range_read_distance (IR2));
39
    usb_putc(' ');
40
    usb_puti(range_read_distance (IR3));
41
    usb_putc(' ');
42
    usb_puti(range_read_distance (IR4));
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff