Project

General

Profile

Revision 1841

Added by Dan Jacobs over 13 years ago

Added line following

View differences:

trunk/code/projects/linefollowing/lineFollow.h
1
#include <dragonfly_lib.h>
2

  
3
 #ifndef _LINEFOLLOW_H_
4
 #define _LINEFOLLOW_H_
5

  
6
#define WHITE			0
7
#define GREY			1
8
#define BLACK	 		2
9
#define CENTER			3
10
#define NOLINE			-42
11
#define SPEED			200
12
#define LINELOST		-1
13

  
14
/* 	lineFollow_init
15
	Must call before lineFollow
16
	Turns analog loop off
17
*/ 
18
void lineFollow_init();
19

  
20
/*	lineFollow
21
	Must call lineFollow first
22
	Must be called inside a loop
23
*/
24
int lineFollow();
25

  
26
/*	assignColor
27
	Converts an analog color to WHITE or BLACK
28
*/
29
int assignColor(int port, int analog);
30

  
31
/*	updateIR
32
	Gets the value of the nth line sensor
33
*/
34
int updateIR(int n);
35

  
36
/*	updateLine
37
	Fills the given array with WHITE
38
	or BLACK representing the line
39
*/
40
void updateLine(int* values); 
41

  
42
/*	lineLocate
43
	Finds the location of the line
44
	Outputs positive for right side
45
	Negative for left, or NOLINE if a line is not found
46
*/
47
int lineLocate(int* colors);
48

  
49
//Not implemented yet, returns ???
50
int updateBarCode();
51

  
52
/*	min
53
	returns the minimum of two values
54
*/
55
int min(int x, int y);
56

  
57
/*	motorLeft
58
	Commands the left motor
59
	Cannot be used to stop
60
	0-126 are backward
61
	127-255 are forward
62
*/
63
void motorLeft(int speed);
64

  
65
/*	motorRight
66
	Commands the right motor
67
	Cannot be used to stop
68
	0-126 are backward
69
	127-255 are forward
70
*/
71
void motorRight(int speed);
72

  
73
/*	lost
74
	Internal counter to detect if the line was lost
75
*/
76
int lost;
77

  
78
#endif
trunk/code/projects/linefollowing/main.c
1 1
#include <dragonfly_lib.h>
2
#include <lineFollow.h>
2 3

  
3
#define WHITE			0
4
#define GREY			1
5
#define BLACK	 		2
6
#define COLOR_BUFFER	10
7
#define CENTER			3
8
#define NOLINE			-42
9 4

  
10
int assignColor(int port, int analog);
11
int updateIR(int n);
12
void updateLine(int* values); 
13
int lineLocate(int* colors);
14
int straightLineFollow();
15 5

  
16

  
17

  
18 6
int main(void)
19 7
{
20 8

  
21 9
	/* initialize components, set wireless channel */
22 10
	dragonfly_init(ALL_ON);
23
	
24
	straightLineFollow();
11
	lineFollow_init();
12
	while(1)
13
		lineFollow();
25 14

  
26 15
	return 0;
27 16
}
28

  
29

  
30

  
31
//Converts an analog color to the ternary black, grey, white system.
32
//If the value is between two codes, the port is read again and the function is called again
33
int assignColor(int port, int analog)
34
{
35
	int color;
36
	
37
		if(analog < 341-COLOR_BUFFER)
38
			color = WHITE;
39
		else if (analog < 341+COLOR_BUFFER)
40
			color = assignColor(port, updateIR(port));
41
		else if (analog < 682-COLOR_BUFFER)
42
			color = GREY; 
43
		else if (analog < 682+COLOR_BUFFER)
44
			color = assignColor(port, updateIR(port));
45
		else
46
			color = BLACK;
47
			
48
		return color;
49

  
50
}
51

  
52
//Gets the value of the nth IR sensor
53
int updateIR(int n)
54
{
55
	//maps the sensors to the analog input ports
56
	int ports[5] = {13, 12, 3, 2, 9};
57

  
58
	return analog10(ports[n]);
59
}
60

  
61
//Gets the value of the nth IR sensor
62
int updateBarCode()
63
{
64
	//maps the sensors to the analog input ports
65
	int ports[2] = {8,1};
66
	
67
	return analog10(ports[1]) | analog10(ports[2]);
68
}
69

  
70
// updates all of the values, and assigns them new colors
71
void updateLine(int* values)
72
{	
73
	int i;
74

  
75
	for(i = 0; i<5; i++)
76
		values[i] = assignColor(i, updateIR(i)); 
77
}
78

  
79
// given an array of ints this function will take the arrays weighted average. High numbers indicate that a left turn is needed. Low numberes indicate that a right turn is needed.
80
int lineLocate(int* colors)
81
{
82
	int i;
83
	int wsum = 0;
84
	int count=0;
85

  
86
	for(i = 0; i<5; i++)
87
	{
88
		count+=(colors[i]+1)/2;
89
		wsum += (i)*colors[i];
90
	}
91
	if(count==0)
92
			return NOLINE;	
93
		
94
	return (wsum/count)-4;
95
}
96

  
97
//The robot will follow a line until it is interrupted by a barcode.
98
int straightLineFollow()
99
{
100
	int colors[6];
101
	int location = 0;
102
	
103

  
104
	while(1)
105
	{	
106
		updateLine(colors);
107
		location = lineLocate(colors); 	
108
		
109
		//not on line
110
		if(location == NOLINE)
111
		{
112
			orb1_set_color(GREEN);
113
			orb2_set_color(GREEN);
114
			motors_off();
115
		}
116
		//turn left
117
		else if(location > 0)
118
		{
119
			orb1_set_color(GREEN);
120
			orb2_set_color(ORB_OFF);
121
			motor_l_set(FORWARD, 150);
122
			motor_r_set(FORWARD, 200);
123
		}
124
		//turn right
125
		else if(location < 0)
126
		{
127
			orb1_set_color(ORB_OFF);
128
			orb2_set_color(GREEN);
129
			motor_l_set(FORWARD, 200);
130
			motor_r_set(FORWARD, 150);
131
		}
132
		else
133
		{
134
			orb1_set_color(ORB_OFF);
135
			orb2_set_color(ORB_OFF);
136
			motor_l_set(FORWARD, 200);
137
			motor_r_set(FORWARD, 200);
138
		}
139
	}
140
	
141
	return 0;
142
}
trunk/code/projects/linefollowing/lineFollow.c
1
#include "lineFollow.h"
2

  
3

  
4

  
5
void lineFollow_init()
6
{
7
	analog_init(0);
8
	lost = 0;
9
}
10

  
11

  
12

  
13
int lineFollow()
14
{
15
	int colors[6];
16
	int position;
17
	
18

  
19
	updateLine(colors);
20
	position = lineLocate(colors); 	
21
	
22
	//not on line
23
	if(position == NOLINE)
24
	{
25
		if(lost++>20)
26
		{
27
			orb1_set_color(GREEN);
28
			orb2_set_color(GREEN);
29
			motors_off();
30
			return LINELOST;
31
		}
32
	}
33
	//on line
34
	else
35
	{
36
		position*=30;
37
		orb1_set_color(GREEN);
38
		orb2_set_color(ORB_OFF);
39
		motorLeft(min(SPEED+position, 255));
40
		motorRight(min(SPEED-position, 255));
41
		lost=0;
42
	}
43
	return 0;
44
}
45

  
46

  
47

  
48

  
49
void updateLine(int* values)
50
{	
51
	for(int i = 0; i<5; i++)
52
		values[i] = assignColor(i, updateIR(i));
53
}
54

  
55

  
56
int updateIR(int n)
57
{
58
	//maps the sensors to the analog input ports
59
	int ports[5] = {13, 12, 3, 2, 9};
60

  
61
	return analog_get10(ports[n]);
62
}
63

  
64

  
65

  
66
int assignColor(int port, int analog)
67
{
68
	if (analog < 150)
69
		return  WHITE;
70
	else
71
		return  BLACK;
72
}
73

  
74

  
75
int lineLocate(int* colors)
76
{
77
	int i;
78
	int wsum = 0;
79
	int count=0;
80

  
81
	for(i = 0; i<5; i++)
82
	{
83
		count+=(colors[i]+1)/2;
84
		wsum += (i)*colors[i];
85
	}
86
	if(count==0)
87
			return NOLINE;	
88
		
89
	return (wsum/count)-4;
90
}
91

  
92

  
93
int updateBarCode()
94
{
95
	//maps the sensors to the analog input ports
96
	int ports[2] = {8,1};
97
	
98
	return analog_get10(ports[1]) | analog10(ports[2]);
99
}
100

  
101

  
102
int min(int x, int y){return x>y ? y : x;}
103

  
104
void motorLeft(int speed){
105
	speed-=127;
106
	if(speed>=0)motor_l_set(FORWARD, 160+speed*95/128);
107
	else motor_l_set(BACKWARD, 160-speed*95/127);
108
}
109

  
110
void motorRight(int speed){
111
        speed-=127;
112
        if(speed>=0)motor_r_set(FORWARD, 160+speed*95/128);
113
        else motor_r_set(BACKWARD, 160-speed*95/127);
114
}
115

  
trunk/code/projects/linefollowing/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 'COM4:'; else echo '/dev/tty.usbserial-*'; 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