Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / linefollowing / lineFollow.c @ 1910

History | View | Annotate | Download (5.81 KB)

1
/**
2
 * @file lineFollow.c
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.c, which
8
 * extends this class to provide behavior functionality.
9
 *
10
 * @author Dan Jacobs
11
 * @date 11-1-2010
12
 */
13

    
14
#include "lineFollow.h"
15

    
16
//! The number of bits expected in a barcode
17
#define CODESIZE 5 
18

    
19
int countHi = 0;
20
int countLo = 0;
21
int maxAvg, avg;
22
int barCode[ CODESIZE ];
23
int barCodePosition=0;
24

    
25
int turnDistance=0;
26
//! Counts the number of full line readings before we determine an intersection
27
int intersectionFilter=0;
28
int disableBarCode=0;
29

    
30

    
31
/** 
32
 * Initializes line following. Must be called before other line-following
33
 * behavior will work.
34
 */
35
void lineFollow_init()
36
{
37
        analog_init(0);
38
        lost = 0;
39
        intersectionFilter=0;
40
        disableBarCode=0;
41
}
42

    
43

    
44
/** 
45
 * Follows a line at the given speed.
46
 * @param speed The speed with which to follow the line.
47
 */
48
int lineFollow(int speed)
49
{
50
        int colors[5];
51
        int position;
52
        
53

    
54
        updateLine(colors);
55
        position = lineLocate(colors);         
56
        
57
        //not on line
58
        if(position == NOLINE)
59
        {
60
                if(lost++ > 20)
61
                {
62
                        orb2_set_color(GREEN);
63
                        motors_off();
64
                        return LINELOST;
65
                }
66
        }
67
        else if(position == FULL_LINE)
68
        {
69
                if(intersectionFilter++ > 4)
70
                {
71
                        orb2_set_color(RED);
72
                        barCodePosition=0;
73
                        disableBarCode=50;
74
                }
75
        }
76
        //on line
77
        else
78
        {
79
                position*=30;
80
                orb2_set_color(ORB_OFF);
81
                motorLeft(min(speed+position, 255));
82
                motorRight(min(speed-position, 255));
83
                lost=0;
84
                intersectionFilter=0;
85
        }
86

    
87
        if(disableBarCode--)
88
        {
89
                if(disableBarCode)return NOBARCODE;
90
                return INTERSECTION;
91
        }
92
        updateBarCode();
93
        return getBarCode();
94
}
95

    
96

    
97
/**
98
 * Implements the left merge, assuming a line exists to the left.  Works by
99
 * turning off the line at an increasing angle and waiting to hit another line
100
 * on the left.
101
 */
102
int mergeLeft()
103
{
104
        motor_l_set(FORWARD, 200);
105
        if(turnDistance!=21)motor_r_set(FORWARD, 230);
106
        else motor_r_set(FORWARD, 210);
107
        int colors[5];
108
        updateLine(colors);
109
        int position = lineLocate(colors);
110
        if(position>3 || position<-3)turnDistance++;
111

    
112
        if(turnDistance>20)
113
        {
114
        turnDistance=21;
115
        
116
                if(position<3 && position>-3)
117
                {
118
                        turnDistance = 0;
119
                        return 0;
120
                }        
121
        }
122
        return 1;
123
}
124

    
125

    
126
/**
127
 * Implements the right merge, assuming a line exists to the right.  Works by
128
 * turning off the line at an increasing angle and waiting to hit another line
129
 * on the right.
130
 */
131
int mergeRight()
132
{
133
        motor_r_set(FORWARD, 200);
134
        if(turnDistance!=21)motor_l_set(FORWARD, 230);
135
        else motor_l_set(FORWARD, 210);
136
        int colors[5];
137
        updateLine(colors);
138
        int position = lineLocate(colors);
139
        if(position>3 || position<-3)turnDistance++;
140

    
141
        if(turnDistance>20)
142
        {
143
        turnDistance=21;
144

    
145
                if(position<3 && position>-3)
146
                {
147
                        turnDistance = 0;
148
                        return 0;
149
                } 
150
        }
151
        return 1;
152
}
153

    
154

    
155

    
156
/**
157
 * Turns left at a cross of two lines.  Assumes that we are at lines in a cross
158
 * pattern, and turns until it sets straight on the new line.
159
 * @return 0 if turn finishes otherwise return 1
160
 */
161
int turnLeft()
162
{
163
        motor_l_set(BACKWARD, 200);
164
        motor_r_set(FORWARD, 200);
165
        int colors[5];
166
        updateLine(colors);
167
        int position = lineLocate(colors);
168
        if(position>2 || position<-2)turnDistance++;
169
        if(turnDistance>1)
170
        {
171
                if(position<3 && position>-3)
172
                {
173
                        turnDistance = 0;
174
                         return 0;
175
                }
176
        }
177
        return 1;
178
}
179

    
180

    
181

    
182
/**
183
 * Turns right at a cross of two lines.  Assumes that we are at lines in a cross
184
 * pattern, and turns until it sets straight on the new line.
185
 * @return 0 if the turn finishes otherwise return 1
186
 */
187
int turnRight()
188
{
189
        motor_r_set(BACKWARD, 200);
190
        motor_l_set(FORWARD, 200);
191
        int colors[5];
192
        updateLine(colors);
193
        int position = lineLocate(colors);
194
        if(position>2 || position<-2)turnDistance++;
195
        if(turnDistance>1) 
196
        {
197
                if(position<3 && position>-3)
198
                {
199
                        turnDistance = 0;
200
                         return 0;
201
                }
202
        }
203
        return 1;
204
}
205

    
206

    
207

    
208
int getBarCode()
209
{
210
        if(barCodePosition!=CODESIZE) return NOBARCODE ;
211
        int temp = 0;
212
        for(int i=0; i<CODESIZE; i++)
213
                temp += (barCode[i] << i);
214
        barCodePosition = 0;
215
        return temp;
216
}
217

    
218

    
219

    
220
void updateLine(int* values)
221
{        
222
        int ports[5] = {13, 12, 3, 2, 9};
223
        for(int i = 0; i<5; i++)
224
                values[i] = analog_get10(ports[i])<150 ? LWHITE : LBLACK;
225
}
226

    
227

    
228

    
229
int lineLocate(int* colors)
230
{
231
        int i;
232
        int wsum = 0;
233
        int count=0;
234

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

    
247

    
248
void updateBarCode()
249
{
250
        //! Note: currently only uses one of the barcode sensors.
251

    
252
        //maps the sensors to the analog input ports
253
        int ports[2] = {8,1};
254
        int current[2];
255
//        current[0] = analog_get10(ports[0]);
256
        current[1] = analog_get10(ports[1]);
257

    
258
        if(current[1]>500)
259
        {
260
                if(countHi++==0) 
261
                {
262
                        avg = 500;
263
                        maxAvg = 500;
264
                }
265
                else
266
                {
267
                        avg = 3*avg + current[1];
268
                        avg/=4;
269
                        maxAvg = max(maxAvg, avg);
270
                }
271
        }
272
        else if(countHi>5)
273
        {
274
                if(countLo++>15)
275
                {
276
                        countHi=countLo=0;
277
                        if(maxAvg>825)orb1_set_color(RED);
278
                        else orb1_set_color(BLUE);
279
                        barCode[barCodePosition++] = maxAvg > 825 ? 1:0;
280
                }
281
        }
282
        else countHi/=2;
283
        if(countHi==0)countLo=0; 
284
}
285

    
286

    
287
int min(int x, int y){return x>y ? y : x;}
288
int max(int x, int y){return x<y ? y : x;}
289

    
290
void motorLeft(int speed){
291
        ((speed-=127)>=0)?motor_l_set(FORWARD, 160+speed*95/128):motor_l_set(BACKWARD, 160-speed*95/127);
292
}
293

    
294
void motorRight(int speed){
295
        ((speed-=127)>=0)?motor_r_set(FORWARD, 160+speed*95/128):motor_r_set(BACKWARD, 160-speed*95/127);
296
}