Project

General

Profile

Revision 60b98383

ID60b98383db2ff491312e634ed125fd32cea188c7

Added by Priya about 12 years ago

Committing some clean ups done in the linefollowing behaviours

View differences:

scout/libscout/src/behaviors/lineDrive.cpp
1 1
/**
2
 * @file lineDrive.cpp
2
 * @file line_drive.cpp
3 3
 *
4 4
 * Provides functions to implement line driving behavior.  This program extends
5 5
 * the behavior of the line-following program by following lines automatically
6
 * and implementing behaviors to deal with commands passed to lineDrive.
6
 * and implementing behaviors to deal with commands passed to line_drive.
7 7
 *
8 8
 * Specific implementation for the colony scout robots in a warehouse behaviour
9 9
 * setting.
......
13 13
 * @date 2-6-2012
14 14
 */
15 15

  
16
#include "lineDrive.h"
17

  
18
int state[5];       //! Stores a queue of sub-commands to be executed
19
int stateCounter;
20
int stateLength;
21

  
22
//! Whether lineDrive is currently paused. Set to 0 on initialization.
23
int stopped=1;
16
#include "line_drive.h"
24 17

  
18
line_drive::line_drive(String scoutname): Behavior(scoutname)
19
{
20
  line_drive_init();
21
  line_follow_init();
22
  return;
23
};
25 24

  
26 25
/**
27 26
 * Starts the line following procedure. Must be called before other
28 27
 * line-following functions will work.  This function essentially resets the
29 28
 * state of line-following.
30 29
 */
31
void lineDrive_init()
30
void line_drive_init()
32 31
{
33 32
	lineFollow_init();
34 33
	for(int i=0; i<5; i++)state[i]=0;
scout/libscout/src/behaviors/lineDrive.h
1
#ifndef _LINE_DRIVE_
2
#define _LINE_DRIVE_
1
#ifndef _LINE_DRIVE_H_
2
#define _LINE_DRIVE_H_
3 3

  
4 4
#include "../Behavior.h"
5 5
#include "lineFollow.h"
......
24 24
#define LOST		-3
25 25
#define ERROR		-4
26 26

  
27
class lineDrive : Behavior{
28
	lineDrive (String scoutname): Behavior(scoutname){};
27
class line_drive : Behavior{
28
	line_drive(String scoutname);
29 29
	run();
30 30

  
31
	void lineDrive_init(void);
31
	void line_drive_init(void);
32 32

  
33 33
	int doDrive(int speed);
34 34

  
......
36 36
	void stop(void);
37 37

  
38 38

  
39
	int turn(int type, int dir);
39
	int turn(int type, iint dir);
40

  
41
  private:
42
  int state[5];       //! Stores a queue of sub-commands to be executed
43
  int stateCounter;
44
  int stateLength;
45

  
46
  //! Whether line_drive is currently paused. Set to 0 on initialization.
47
  int stopped=1;
48

  
49
};
40 50

  
41
}
42 51
#endif
scout/libscout/src/behaviors/lineFollow.cpp
1
/**
2
 * @file lineFollow.cpp
3
 * @defgroup lineFollwing Line Following
4
 *
5
 * Takes care of following a line. Running this program is done by calling the
6
 * init() function and then the lineFollow(speed) command.  However, direct use
7
 * of this class is discouraged as its behavior is used by lineDrive.cpp, which
8
 * extends this class to provide behavior functionality.
9
 *
10
 * @author Dan Jacobs and the Colony Project
11
 * @date 11-1-2010
12
 */
13

  
14
#include "lineFollow.h"
15

  
16
/**
17
 * Helps with debugging.
18
 * 0 - no debug output.
19
 * 1 - print out buckets
20
 * 2 - print out line sensor readings
21
 */
22
#define DBG_LINEFOLLOW 2
23

  
24
//! Anything lower than this value is white
25
int GREY_THRESHOLD = 300;
26
//! Anything higher than this value is black
27
int BLACK_THRESHOLD = 750;
28

  
29
int countHi = 0;
30
int countLo = 0;
31
int maxAvg, avg;
32

  
33
int duration[2] = {0};
34
int lastColor[2] = {0};
35
char isReset[2] = {1};
36
int lastReadings[2][ NUM_READINGS ] = {{0}};
37
int lastReadingsPtr[2] = {0};
38
int numLast[2][4] = { {0, 0, 0, NUM_READINGS}, {0, 0, 0, NUM_READINGS} };
39
int bitColor[2] = {0};
40

  
41
int turnDistance=0;
42
//! Counts the number of full line readings before we determine an intersection
43
int intersectionFilter=0;
44

  
45
//! Keeps track of where the encoder of one motor started, for use in turns.
46
int encoderStart = -1;
47
int encoderReset = 0;   // 0 if encoderStart has no value set
48

  
49

  
50
void lineFollow::init()
51
{
52
    int i, j, curReading;
53
    int lowGrey = 1000, highGrey = 0, lowBlack = 1000,
54
        highBlack = 0;
55

  
56
	analog_init(0);
57
    encoders_init();
58
	lost = 0;
59
	intersectionFilter=0;
60

  
61
    for(i=0; i<2; i++)
62
    {
63
        for(j=0; j<NUM_READINGS; j++)
64
        {
65
            lastReadings[i][j] = BAD_READING;
66
        }
67
        isReset[i] = 1;
68
    }
69
    
70
    // Calibrate thresholds
71
    orb_set_color(YELLOW);
72
    delay_ms(2000);
73

  
74
    orb_set_color(BLUE);
75

  
76
    for(i=0; i<100; i++)
77
    {
78
        curReading = read_line(LEFT_SENSOR + 6);
79
        if(curReading < lowGrey)
80
            lowGrey = curReading;
81
        if(curReading > highGrey)
82
            highGrey = curReading;
83

  
84
        delay_ms(20);
85
    }
86

  
87
    orb_set_color(YELLOW);
88
    delay_ms(2000);
89

  
90
    orb_set_color(GREEN);
91

  
92
    for(i=0; i<100; i++)
93
    {
94
        curReading = read_line(LEFT_SENSOR + 6);
95
        if(curReading < lowBlack)
96
            lowBlack = curReading;
97
        if(curReading > highBlack)
98
            highBlack = curReading;
99

  
100
        delay_ms(20);
101
    }
102

  
103
    orbs_set(0,0,0,0,0,0);
104

  
105
    GREY_THRESHOLD = lowGrey / 2;
106
    BLACK_THRESHOLD = (highGrey + lowBlack) / 2;
107

  
108
    usb_puts("Grey: ");
109
    usb_puti(lowGrey);
110
    usb_puts(", ");
111
    usb_puti(highGrey);
112
    usb_puts("\nBlack: ");
113
    usb_puti(lowBlack);
114
    usb_puts(", ");
115
    usb_puti(highBlack);
116
    usb_puts("\nThresholds: ");
117
    usb_puti(GREY_THRESHOLD);
118
    usb_puts(", ");
119
    usb_puti(BLACK_THRESHOLD);
120
    usb_puts("\n\n");
121

  
122
    delay_ms(1500);
123
}
124

  
125

  
126
/** 
127
 * Follows a line at the given speed.
128
 * @param speed The speed with which to follow the line.
129
 */
130
int lineFollow(int speed)
131
{
132
	int colors[5];
133
	int position;
134
	
135

  
136
	updateLine(colors);
137
	position = lineLocate(colors); 	
138
	
139
	//not on line
140
	if(position == NOLINE)
141
	{
142
		if(lost++ > 20)
143
		{
144
			orb2_set_color(GREEN);
145
			motors_off();
146
			return LINELOST;
147
		}
148
	}
149
	else if(position == FULL_LINE)
150
	{
151
		if(intersectionFilter++ > 4)
152
		{
153
			orb2_set_color(RED);
154
			barCodePosition[0]=0;
155
            barCodePosition[1]=0;
156
			disableBarCode=50;
157
		}
158
	}
159
	//on line
160
	else
161
	{
162
		position*=30;
163
		orb2_set_color(ORB_OFF);
164
		motorLeft(min(speed+position, 255));
165
		motorRight(min(speed-position, 255));
166
		lost=0;
167
		intersectionFilter=0;
168
	}
169
}
170

  
171

  
172
/**
173
 * Turns left at a cross of two lines.  Assumes that we are at lines in a cross
174
 * pattern, and turns until it sets straight on the new line.
175
 * @return 0 if turn finishes otherwise return 1
176
 */
177
int turnLeft()
178
{
179
        motors->set_sides(-20, 20, MOTOR_ABSOLUTE);
180
		
181
        if(!encoderReset)
182
        {
183
            encoderStart = encoder_get_x(RIGHT);
184
            encoderReset = 1;
185
        }
186

  
187
        if(encoder_get_x(RIGHT) < encoderStart)
188
        {
189
            encoderStart = 0;
190
            motors->set_sides(0, 0, MOTOR_ABSOLUTE);
191
            delay_ms(2000);
192
        }
193

  
194
        if(encoder_get_x(RIGHT) - encoderStart > 300)
195
        {
196
            encoderReset = 0;
197
            return 0;
198
        }
199
        return 1;
200
}
201

  
202

  
203

  
204
/**
205
 * Turns right at a cross of two lines.  Assumes that we are at lines in a cross
206
 * pattern, and turns until it sets straight on the new line.
207
 * @return 0 if the turn finishes otherwise return 1
208
 */
209
int lineFollow::turnRight()
210
{
211
	/// Set motors using new motors functions
212
	/// motor_r_set(BACKWARD, 200);
213
	/// motor_l_set(FORWARD, 200);
214
        
215
	int colors[5];
216
	updateLine(colors);
217
    int position = lineLocate(colors);
218
    if(position>2 || position<-2)
219
		turnDistance++;
220

  
221
    if(turnDistance>1) 
222
	{
223
		if(position<3 && position>-3)
224
		{
225
			turnDistance = 0;
226
			 return 0;
227
		}
228
	}
229
	return 1;
230
}
231

  
232

  
233
void updateLine(int* values)
234
{	
235
	for(int i = 0; i<5; i++)
236
		values[i] = (read_line(4-i) < LINE_COLOR ? LWHITE : LBLACK);
237
}
238

  
239

  
240
int lineLocate(int* colors)
241
{
242
	int i;
243
	int wsum = 0;
244
	int count=0;
245

  
246
	for(i = 0; i<5; i++)
247
	{
248
		count += colors[i]/2;
249
		wsum += (i)*colors[i];
250
	}
251
	if(count==0)
252
		return NOLINE;	
253
	if(count==5)
254
		return FULL_LINE;
255
	return (wsum/count)-4; /// Subtract 4 to center the index around the center.
256
}
257

  
258
void printBuckets(int i)
259
{
260
    int j;
261

  
262
    usb_puts("LP[");
263
    usb_puti(i);
264
    usb_puts("]: ");
265
    usb_puti(lastReadingsPtr[i]);
266
    usb_puts(", Totals: ");
267

  
268
    for(int j=0; j<=3; j++)
269
    {
270
        usb_puts("[");
271
        usb_puti(j);
272
        usb_puts("]: ");
273
        usb_puti(numLast[i][j]);
274
        usb_puts(" ");
275
    }
276
    usb_puts("\t ");
277
    usb_puts("\n");
278
}
279

  
280
void addToBuckets(int curColor, int i)
281
{
282
    int oldest = lastReadings[i][lastReadingsPtr[i]];
283
    numLast[i][oldest]--;
284
    lastReadings[i][lastReadingsPtr[i]] = curColor;
285
    lastReadingsPtr[i] = (lastReadingsPtr[i]+1) % NUM_READINGS;
286
    numLast[i][curColor]++;
287

  
288
    if(DBG_LINEFOLLOW == 1)
289
    {
290
        printBuckets(i);
291
    }
292
}
293

  
294

  
295
int min(int x, int y){return x>y ? y : x;}
296
int max(int x, int y){return x<y ? y : x;}
297

  
298
void motorLeft(int speed)
299
{
300
	int tempspeed = 0;
301
	if ((speed-=127)>=0)
302
	{	
303
		tempspeed = 160+speed*95/128;
304
		motors->set_sides(tempspeed, 0, MOTOR_ABSOLUTE);
305
	}
306
	else
307
	{
308
		tempspeed = 160+speed*95/128;
309
		motors->set_sides(-tempspeed, 0, MOTOR_ABSOLUTE);
310
	}
311
}
312

  
313
void motorRight(int speed)
314
{
315
	int tempspeed = 0;
316
	if ((speed-=127)>=0)
317
	{	
318
		tempspeed = 160+speed*95/128;
319
		motors->set_sides(0, tempspeed, MOTOR_ABSOLUTE);
320
	}
321
	else
322
	{
323
		tempspeed = 160+speed*95/128;
324
		motors->set_sides(0, -tempspeed, MOTOR_ABSOLUTE);
325
	}
326
}
327
	
scout/libscout/src/behaviors/lineFollow.h
1

  
2
#ifndef _LINEFOLLOW_H_
3
#define _LINEFOLLOW_H_
4

  
5
#include "../Behavior.h"
6

  
7
#define LWHITE			0
8
#define LGREY			1
9
#define LBLACK	 		2
10
#define BAD_READING     3
11
#define CENTER			3
12
#define LINELOST		-1
13

  
14
#define INTERSECTION 	-25
15

  
16
#define NOLINE			-50
17
#define FULL_LINE 		-51
18

  
19
#define NUM_READINGS 20
20

  
21
#define LEFT_SENSOR     1
22
#define RIGHT_SENSOR    0
23

  
24
class lineFollow : Behavior
25
{
26
	public:
27
		lineFollow(std::string scoutname) : Behavior(scoutname) {};
28
        /** Actually executes the behavior. */
29
		void init();
30
};
31

  
32
/**	lineFollow
33
 *	Must call lineFollow_init first
34
 *	Must be called inside a loop
35
 */
36
int lineFollow(int speed);
37

  
38
/**	turnLeft turnRight
39
 *	Must be called inside a loop
40
 *	returns 0 when complete
41
 */
42
int turnLeft(void);
43
int turnRight(void);
44

  
45
void addToBuckets(int curColor, int i);
46
void printBuckets();
47

  
48
/**
49
 * @brief Updates the values stored in the array to white or black based on
50
 * current sensor readings.
51
 *
52
 * @param values The array of five integers to be updated. 
53
 */
54
void updateLine(int* values); 
55

  
56
/**
57
 * @brief Returns an index of the middle of the line based on line readings.
58
 *
59
 * Two special return values are possible:
60
 *   NOLINE if none of the sensors holds a black value, and
61
 *   FULL_LINE if all of the sensors see black.
62
 *
63
 * Otherwise, returns a value from -4 (farthest left) to 4 (farthest right), with
64
 * 0 the line being centered in the middle.
65
 *
66
 * @param colors The array of 5 readings from the line sensor.  Must be either
67
 *    LWHITE or LBLACK.
68
 * @return Either a special value or an index from -4 to 4.
69
 *
70
 */
71
int lineLocate(int* colors);
72

  
73

  
74
//! A simple function to return the minimum of two integers.
75
int min(int x, int y);
76
//! A simple function to return the maximum of two integers.
77
int max(int x, int y);
78

  
79
/** @todo Alex: I hate these functions, but I'm keeping them so code will still work. But we should delete them sometime. */
80

  
81
/**	motorLeft
82
 *	Commands the left motor
83
 *	Cannot be used to stop
84
 *	0-126 are backward
85
 *	127-255 are forward
86
 */
87
void motorLeft(int speed);
88

  
89
/**	motorRight
90
 *	Commands the right motor
91
 *	Cannot be used to stop
92
 *	0-126 are backward
93
 *	127-255 are forward
94
 */
95
void motorRight(int speed);
96

  
97
/**	lost
98
 *	Internal counter to detect if the line was lost
99
 */
100
int lost;
101

  
102
int onLine(void);
103

  
104
#endif
scout/libscout/src/behaviors/line_follow.cpp
1
/**
2
 * @file line_follow.cpp
3
 * @defgroup lineFollwing Line Following
4
 *
5
 * Takes care of following a line. Running this program is done by calling the
6
 * init() function and then the line_follow(speed) command.  However, direct use
7
 * of this class is discouraged as its behavior is used by lineDrive.cpp, which
8
 * extends this class to provide behavior functionality.
9
 *
10
 * @author Dan Jacobs and the Colony Project
11
 * @date 11-1-2010
12
 */
13

  
14
#include "line_follow.h"
15

  
16
//! Anything lower than this value is white
17
int GREY_THRESHOLD = 300;
18
//! Anything higher than this value is black
19
int BLACK_THRESHOLD = 750;
20

  
21
int countHi = 0;
22
int countLo = 0;
23
int maxAvg, avg;
24

  
25
int duration[2] = {0};
26
int lastColor[2] = {0};
27
char isReset[2] = {1};
28
int lastReadings[2][ NUM_READINGS ] = {{0}};
29
int lastReadingsPtr[2] = {0};
30
int numLast[2][4] = { {0, 0, 0, NUM_READINGS}, {0, 0, 0, NUM_READINGS} };
31
int bitColor[2] = {0};
32

  
33
int turnDistance=0;
34
//! Counts the number of full line readings before we determine an intersection
35
int intersectionFilter=0;
36

  
37
//! Keeps track of where the encoder of one motor started, for use in turns.
38
int encoderStart = -1;
39
int encoderReset = 0;   // 0 if encoderStart has no value set
40

  
41
int min(int x, int y){return x>y ? y : x;}
42
int max(int x, int y){return x<y ? y : x;}
43

  
44

  
45
void line_follow::init()
46
{
47
  int i, j, curReading;
48
  int lowGrey = 1000, highGrey = 0, lowBlack = 1000,
49
      highBlack = 0;
50

  
51
  analog_init(0);
52
  encoders_init();
53
  lost = 0;
54
  intersectionFilter=0;
55

  
56
  for(i=0; i<2; i++)
57
  {
58
    for(j=0; j<NUM_READINGS; j++)
59
    {
60
      lastReadings[i][j] = BAD_READING;
61
    }
62
    isReset[i] = 1;
63
  }
64

  
65
  // Calibrate thresholds
66
  orb_set_color(YELLOW);
67
  delay_ms(2000);
68

  
69
  orb_set_color(BLUE);
70

  
71
  for(i=0; i<100; i++)
72
  {
73
    curReading = read_line(LEFT_SENSOR + 6);
74
    if(curReading < lowGrey)
75
      lowGrey = curReading;
76
    if(curReading > highGrey)
77
      highGrey = curReading;
78

  
79
    delay_ms(20);
80
  }
81

  
82
  orb_set_color(YELLOW);
83
  delay_ms(2000);
84

  
85
  orb_set_color(GREEN);
86

  
87
  for(i=0; i<100; i++)
88
  {
89
    curReading = read_line(LEFT_SENSOR + 6);
90
    if(curReading < lowBlack)
91
      lowBlack = curReading;
92
    if(curReading > highBlack)
93
      highBlack = curReading;
94

  
95
    delay_ms(20);
96
  }
97

  
98
  orbs_set(0,0,0,0,0,0);
99

  
100
  GREY_THRESHOLD = lowGrey / 2;
101
  BLACK_THRESHOLD = (highGrey + lowBlack) / 2;
102

  
103
  usb_puts("Grey: ");
104
  usb_puti(lowGrey);
105
  usb_puts(", ");
106
  usb_puti(highGrey);
107
  usb_puts("\nBlack: ");
108
  usb_puti(lowBlack);
109
  usb_puts(", ");
110
  usb_puti(highBlack);
111
  usb_puts("\nThresholds: ");
112
  usb_puti(GREY_THRESHOLD);
113
  usb_puts(", ");
114
  usb_puti(BLACK_THRESHOLD);
115
  usb_puts("\n\n");
116

  
117
  delay_ms(1500);
118
}
119

  
120

  
121
/** 
122
 * Follows a line at the given speed.
123
 * @param speed The speed with which to follow the line.
124
 */
125
int line_follow::follow_line(int speed)
126
{
127
	int colors[5];
128
	int position;
129
	
130

  
131
	updateLine(colors);
132
	position = lineLocate(colors); 	
133
	
134
	//not on line
135
	if(position == NOLINE)
136
	{
137
		if(lost++ > 20)
138
		{
139
			orb2_set_color(GREEN);
140
			motors_off();
141
			return LINELOST;
142
		}
143
	}
144
	else if(position == FULL_LINE)
145
	{
146
		if(intersectionFilter++ > 4)
147
		{
148
			orb2_set_color(RED);
149
			barCodePosition[0]=0;
150
            barCodePosition[1]=0;
151
			disableBarCode=50;
152
		}
153
	}
154
	//on line
155
	else
156
	{
157
		position*=30;
158
		orb2_set_color(ORB_OFF);
159
		motorLeft(min(speed+position, 255));
160
		motorRight(min(speed-position, 255));
161
		lost=0;
162
		intersectionFilter=0;
163
	}
164
}
165

  
166

  
167
/**
168
 * Turns left at a cross of two lines.  Assumes that we are at lines in a cross
169
 * pattern, and turns until it sets straight on the new line.
170
 * @return 0 if turn finishes otherwise return 1
171
 */
172
int line_follow::turnLeft()
173
{
174
        motors->set_sides(-20, 20, MOTOR_ABSOLUTE);
175
		
176
        if(!encoderReset)
177
        {
178
            encoderStart = encoder_get_x(RIGHT);
179
            encoderReset = 1;
180
        }
181

  
182
        if(encoder_get_x(RIGHT) < encoderStart)
183
        {
184
            encoderStart = 0;
185
            motors->set_sides(0, 0, MOTOR_ABSOLUTE);
186
            delay_ms(2000);
187
        }
188

  
189
        if(encoder_get_x(RIGHT) - encoderStart > 300)
190
        {
191
            encoderReset = 0;
192
            return 0;
193
        }
194
        return 1;
195
}
196

  
197

  
198

  
199
/**
200
 * Turns right at a cross of two lines.  Assumes that we are at lines in a cross
201
 * pattern, and turns until it sets straight on the new line.
202
 * @return 0 if the turn finishes otherwise return 1
203
 */
204
int line_follow::turnRight()
205
{
206
  /// Set motors using new motors functions
207
  motors->set_sides(20, -20, MOTOR_ABSOLUTE);
208

  
209
  int colors[5];
210
  updateLine(colors);
211
  int position = lineLocate(colors);
212
  if(position>2 || position<-2)
213
    turnDistance++;
214

  
215
  if(turnDistance>1) 
216
  {
217
    if(position<3 && position>-3)
218
    {
219
      turnDistance = 0;
220
      return 0;
221
    }
222
  }
223
  return 1;
224
}
225

  
226

  
227
void line_follow::updateLine(int* values)
228
{	
229
	for(int i = 0; i<5; i++)
230
		values[i] = (read_line(4-i) < LINE_COLOR ? LWHITE : LBLACK);
231
}
232

  
233

  
234
int line_follow::lineLocate(int* colors)
235
{
236
	int i;
237
	int wsum = 0;
238
	int count=0;
239

  
240
	for(i = 0; i<5; i++)
241
	{
242
		count += colors[i]/2;
243
		wsum += (i)*colors[i];
244
	}
245
	if(count==0)
246
		return NOLINE;	
247
	if(count==5)
248
		return FULL_LINE;
249
	return (wsum/count)-4; /// Subtract 4 to center the index around the center.
250
}
251

  
252
void line_follow::motorLeft(int speed)
253
{
254
	int tempspeed = 0;
255
	if ((speed-=127)>=0)
256
	{	
257
		tempspeed = 160+speed*95/128;
258
		motors->set(MOTOR_LEFT, tempspeed, MOTOR_ABSOLUTE);
259
	}
260
	else
261
	{
262
		tempspeed = 160+speed*95/128;
263
		motors->set(MOTOR_LEFT, -tempspeed, MOTOR_ABSOLUTE);
264
	}
265
}
266

  
267
void line_follow::motorRight(int speed)
268
{
269
	int tempspeed = 0;
270
	if ((speed-=127)>=0)
271
	{	
272
		tempspeed = 160+speed*95/128;
273
		motors->set(MOTOR_RIGHT, tempspeed, MOTOR_ABSOLUTE);
274
	}
275
	else
276
	{
277
		tempspeed = 160+speed*95/128;
278
		motors->set(MOTOR_RIGHT, -tempspeed, MOTOR_ABSOLUTE);
279
	}
280
}
281
	
scout/libscout/src/behaviors/line_follow.h
1

  
2
#ifndef _LINE_FOLLOW_H_
3
#define _LINE_FOLLOW_H_
4

  
5
#include "../Behavior.h"
6

  
7
#define LWHITE			0
8
#define LGREY			1
9
#define LBLACK	 		2
10
#define BAD_READING     3
11
#define CENTER			3
12
#define LINELOST		-1
13

  
14
#define INTERSECTION 	-25
15

  
16
#define NOLINE			-50
17
#define FULL_LINE 		-51
18

  
19
#define NUM_READINGS 20
20

  
21
#define LEFT_SENSOR     1
22
#define RIGHT_SENSOR    0
23

  
24
/**
25
 * Helps with debugging.
26
 * 0 - no debug output.
27
 * 1 - print out buckets
28
 * 2 - print out line sensor readings
29
 */
30
#define DBG_LINEFOLLOW 2
31

  
32

  
33
//! A simple function to return the minimum of two integers.
34
int min(int x, int y);
35
//! A simple function to return the maximum of two integers.
36
int max(int x, int y);
37

  
38

  
39
class line_follow 
40
{
41
	public:
42
    /** Actually executes the behavior. */
43
		void init();
44

  
45
    /**	line_follow
46
     *	Must call line_follow_init first
47
     *	Must be called inside a loop
48
     */
49
    int follow_line(int speed);
50

  
51
    /**	turnLeft turnRight
52
     *	Must be called inside a loop
53
     *	returns 0 when complete
54
     */
55
    int turnLeft(void);
56
    int turnRight(void);
57

  
58
    /**
59
     * @brief Updates the values stored in the array to white or black based on
60
     * current sensor readings.
61
     *
62
     * @param values The array of five integers to be updated. 
63
     */
64
    void updateLine(int* values); 
65

  
66
    /**
67
     * @brief Returns an index of the middle of the line based on line readings.
68
     *
69
     * Two special return values are possible:
70
     *   NOLINE if none of the sensors holds a black value, and
71
     *   FULL_LINE if all of the sensors see black.
72
     *
73
     * Otherwise, returns a value from -4 (farthest left) to 4 (farthest right), with
74
     * 0 the line being centered in the middle.
75
     *
76
     * @param colors The array of 5 readings from the line sensor.  Must be either
77
     *    LWHITE or LBLACK.
78
     * @return Either a special value or an index from -4 to 4.
79
     *
80
     */
81
    int lineLocate(int* colors);
82

  
83
    /** @todo Alex: I hate these functions, but I'm keeping them so code will still work. But we should delete them sometime. */
84

  
85
    /**	motorLeft
86
     *	Commands the left motor
87
     *	Cannot be used to stop
88
     *	0-126 are backward
89
     *	127-255 are forward
90
     */
91
    void motorLeft(int speed);
92

  
93
    /**	motorRight
94
     *	Commands the right motor
95
     *	Cannot be used to stop
96
     *	0-126 are backward
97
     *	127-255 are forward
98
     */
99
    void motorRight(int speed);
100

  
101
    private:
102
    /**	lost
103
     *	Internal counter to detect if the line was lost
104
     */
105
    int lost;
106
};
107
#endif

Also available in: Unified diff