-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcanyon.h
143 lines (126 loc) · 3.74 KB
/
canyon.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#ifndef CANYON_H
#define CANYON_H
#include "xc.h"
#include "drive.h"
#include "math.h"
#define VCC 3.3
#define MAX_RANGE 118.11 // Inches
#define FRONT_SONAR ADC1BUF11
#define RIGHT_SONAR ADC1BUF12
#define TILE_LENGTH 23 //inches
#define MAX_WALL_DISTANCE 8
#define SLOW_DOWN_DISTANCE 15
#define OPEN_DISTANCE 20
#define STRAIGHT_DISTANCE 1 // Inches
#define DISTANCE_FROM_SONAR_TO_CENTER 3.5 // inches
#define HYSTERESIS_DISTANCE 15
#define CANYON_SPEED_MODIFIER 1.2
/**
* Turns the voltage form the sonar into a distance in inches
* @param voltage the raw voltage from the sonar
* @return The distance in inches
*/
double getDistance(double voltage) {
voltage = (voltage/4095.0)*VCC;
double distance = MAX_RANGE * (voltage / VCC);
return distance;
}
/**
* Turns the robot and drive forward to not interfere with the sensors
*/
void makeLeftCanyonTurn() {
stopRobot();
drive_completed = false;
turnRobot(90, COUNTERCLOCKWISE);
while (!drive_completed) {}
slow_down_flag = false;
drive_completed = false;
driveStraight(TILE_LENGTH/2, FORWARD);
while (!drive_completed) {
driveStraight(TILE_LENGTH/2, FORWARD);
}
has_turned = true;
}
/**
* Turns the robot and drive forward to not interfere with the sensors
*/
void makeRightCanyonTurn() {
stopRobot();
drive_completed = false;
turnRobot (90, CLOCKWISE);
while (!drive_completed) {}
slow_down_flag = false;
drive_completed = false;
driveStraight(TILE_LENGTH/2, FORWARD);
while (!drive_completed) {
driveStraight(TILE_LENGTH/2, FORWARD);
}
has_turned = true;
}
/**
* Logic to navigate the canyon
* Turns the robot once the front end gets too close to a wall
*/
void navigateCanyon(void) {
if (getDistance(FRONT_SONAR) < SLOW_DOWN_DISTANCE) {
slow_down_flag = true;
} else {
slow_down_flag = false;
}
if (getDistance(FRONT_SONAR) < MAX_WALL_DISTANCE) {
if (getDistance(RIGHT_SONAR) > OPEN_DISTANCE) {
makeLeftCanyonTurn();
}
else {
makeRightCanyonTurn();
}
} else {
driveStraight(STRAIGHT_DISTANCE, FORWARD);
}
// State transition logic
if (LEFT_QRD <= QRD_THRESHOLD || RIGHT_QRD <= QRD_THRESHOLD) {
if (has_turned) {
getBackOnLine();
}
}
}
/**
* These are the preprogrammed coordinates to get the robot back to the line following state
*/
void getBackOnLine(void) {
while (current_state == NAVIGATE_CANYON) {
OC1RS = 39999; // Period
OC1R = servo_frequency; // Duty cycle
if (LEFT_QRD <= QRD_THRESHOLD && RIGHT_QRD >= QRD_THRESHOLD) {
stopRobot();
driveMotor(MOTOR_PWM_2, PWM_FREQUENCY, MOTOR_DIR_2, FORWARD);
}
else if (LEFT_QRD >= QRD_THRESHOLD && RIGHT_QRD <= QRD_THRESHOLD) {
stopRobot();
driveMotor(MOTOR_PWM_1, PWM_FREQUENCY, MOTOR_DIR_1, FORWARD);
}
else if (LEFT_QRD <= QRD_THRESHOLD && RIGHT_QRD <= QRD_THRESHOLD) {
drive_completed = false;
driveStraight(5, FORWARD);
while(!drive_completed) {
if (chosen_frequency > 400) {
chosen_frequency = chosen_frequency - 4;
}
driveStraight(5, FORWARD);
}
drive_completed = false;
if (getDistance(RIGHT_SONAR) < OPEN_DISTANCE) {
turnRobot(90, CLOCKWISE);
} else {
turnRobot(90, COUNTERCLOCKWISE);
}
while(!drive_completed) {}
stripe_steps = 0;
stripe_count = 0;
stripe_flag = false;
current_state = FOLLOW_LINE;
_AD1IE = 1;
}
}
}
#endif /* CANYON_H */