Project

General

Profile

Revision 58371433

ID5837143311f6de5068f1724a2d1dc8377610237d

Added by Priya almost 12 years ago

Renaming to line follow and getting rid of old linefollowing files.

View differences:

scout/libscout/src/behaviors/line_follow.cpp
1 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
2
 * Copyright (c) 2011 Colony Project
3
 * 
4
 * Permission is hereby granted, free of charge, to any person
5
 * obtaining a copy of this software and associated documentation
6
 * files (the "Software"), to deal in the Software without
7
 * restriction, including without limitation the rights to use,
8
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following
11
 * conditions:
12
 * 
13
 * The above copyright notice and this permission notice shall be
14
 * included in all copies or substantial portions of the Software.
15
 * 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
12 24
 */
13 25

  
14 26
#include "line_follow.h"
15 27

  
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;
28
using namespace std;
20 29

  
21
int countHi = 0;
22
int countLo = 0;
23
int maxAvg, avg;
30
static int motor_l;
31
static int motor_r;
24 32

  
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;
33
void line_follow::follow_line()
34
{
35
    while(!linesensor->fullline())
36
    {
37
        double line_loc = linesensor->readline();
36 38

  
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
39
        cout << "line_loc: " << line_loc << endl;
40 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;}
41
        motor_l = -MOTOR_BASE + SCALE * line_loc;
42
        motor_r = -MOTOR_BASE - SCALE * line_loc;
43 43

  
44
        motors->set_sides(motor_l, motor_r, MOTOR_ABSOLUTE);
45
    }
46
    halt();
47
}
44 48

  
45
void line_follow::init()
49
void line_follow::turn_left()
46 50
{
47
  int i, j, curReading;
48
  int lowGrey = 1000, highGrey = 0, lowBlack = 1000,
49
      highBlack = 0;
51
  bool first = true;
52
  do
53
  {
54
    motor_l = -MOTOR_BASE;
55
    motor_r = MOTOR_BASE/8;
50 56

  
51
  analog_init(0);
52
  encoders_init();
53
  lost = 0;
54
  intersectionFilter=0;
57
    motors->set_sides(motor_l, motor_r, MOTOR_ABSOLUTE);
55 58

  
56
  for(i=0; i<2; i++)
57
  {
58
    for(j=0; j<NUM_READINGS; j++)
59
    double line_loc = linesensor->readline();
60
    cout << "line_loc: " << line_loc << endl;
61
    if(first)
59 62
    {
60
      lastReadings[i][j] = BAD_READING;
63
        loop_rate->sleep();
64
        loop_rate->sleep();
65
        loop_rate->sleep();
66
        first = false;
61 67
    }
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 68
  }
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);
69
  while(linesensor->readline());
118 70
}
119 71

  
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)
72
void line_follow::halt()
126 73
{
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
	}
74
    motors->set_sides(0, 0, MOTOR_ABSOLUTE);
164 75
}
165 76

  
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()
77
void line_follow::turn_right()
173 78
{
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);
79
  bool first = true;
80
  do
81
  {
82
    motor_l = MOTOR_BASE/8;
83
    motor_r = -MOTOR_BASE;
208 84

  
209
  int colors[5];
210
  updateLine(colors);
211
  int position = lineLocate(colors);
212
  if(position>2 || position<-2)
213
    turnDistance++;
85
    motors->set_sides(motor_l, motor_r, MOTOR_ABSOLUTE);
214 86

  
215
  if(turnDistance>1) 
216
  {
217
    if(position<3 && position>-3)
87
    double line_loc = linesensor->readline();
88
    cout << "line_loc: " << line_loc << endl;
89
    if(first)
218 90
    {
219
      turnDistance = 0;
220
      return 0;
91
        loop_rate->sleep();
92
        loop_rate->sleep();
93
        loop_rate->sleep();
94
        first = false;
221 95
    }
222 96
  }
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
	}
97
  while(linesensor->readline());
265 98
}
266 99

  
267
void line_follow::motorRight(int speed)
100
void line_follow::run()
268 101
{
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
	}
102
  follow_line();
103
  turn_right();
104
  follow_line();
105
  turn_left();
106
  follow_line();
107
  turn_right();
108
  follow_line();
280 109
}
281
	

Also available in: Unified diff