-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTourGuide.java
205 lines (178 loc) · 4.63 KB
/
TourGuide.java
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
import lejos.nxt.*;
// Tour Guide Lego Mindstorms prototype.
// Follows and remembers a path drawn by a black line in a white font.
// Then it is capable of repeating the same path without the drawn path.
// Specifications:
// Sensors ports should correspond to sensor position:
// SensorPort.S2 -> Right Sensor
// SensorPort.S3 -> Left Sensor
// Motors should correspond to motor position:
// Motor.A -> Right Motor
// Motor.B -> Left Motor
public class TourGuide {
int blackAndWhiteThreshold = 400;
int outerWheelTurningSpeed = 100;
int innerWheelTurningSpeed = 50;
int straightLineSpeed = 180;
int straightLineTime = 20;
int turningTime = 20;
boolean black = false;
boolean white = true;
boolean left = white;
boolean right = white;
LightSensor leftSensor = new LightSensor(SensorPort.S3);
LightSensor rightSensor = new LightSensor(SensorPort.S2);
public void executeMove(byte move){
switch(move){
case 0:
Motor.A.setSpeed(straightLineSpeed);
Motor.B.setSpeed(straightLineSpeed);
Motor.A.forward();
Motor.B.forward();
try{
Thread.sleep(straightLineTime);
} catch (Exception e){
}
case 1:
Motor.A.setSpeed(outerWheelTurningSpeed);
Motor.B.setSpeed(innerWheelTurningSpeed);
Motor.A.forward();
Motor.B.backward();
try{
Thread.sleep(turningTime);
} catch (Exception e){
}
case 2:
Motor.A.setSpeed(innerWheelTurningSpeed);
Motor.B.setSpeed(outerWheelTurningSpeed);
Motor.A.backward();
Motor.B.forward();
try{
Thread.sleep(turningTime);
} catch (Exception e){
}
default: // or case 3
Motor.A.stop();
Motor.B.stop();
}
}
public void run(){
int leftIntensity;
int rightIntensity;
int whiteIntensity;
int blackIntensity;
byte move;
Stack Record = new Stack();
// Read with both sensors as the first reading always fails
leftSensor.readNormalizedValue();
rightSensor.readNormalizedValue();
Button.ENTER.waitForPress();
// Calibration
System.out.println("Calibrate White Color. Set both sensors over White Color.");
Button.ENTER.waitForPress();
leftIntensity = leftSensor.readNormalizedValue();
rightIntensity = rightSensor.readNormalizedValue();
whiteIntensity = (leftIntensity + rightIntensity)/2;
System.out.println("Calibrate Black Color. Set both sensors over Black Color.");
Button.ENTER.waitForPress();
leftIntensity = leftSensor.readNormalizedValue();
rightIntensity = rightSensor.readNormalizedValue();
blackIntensity = (leftIntensity + rightIntensity)/2;
this.blackAndWhiteThreshold = (whiteIntensity + blackIntensity)/2;
System.out.println("Set Tour Guide on starting position.");
Button.ENTER.waitForPress();
Motor.A.setSpeed(straightLineSpeed);
Motor.B.setSpeed(straightLineSpeed);
Motor.A.forward();
Motor.B.forward();
// Path recognition
while(!Button.ESCAPE.isPressed()){
while(left==white && right==white){
move = 0;
Record.push(move);
this.executeMove(move);
this.measure();
}
while(left==black && right==white){
move = 1;
Record.push(move);
this.executeMove(move);
this.measure();
}
while(left==white && right==black){
move = 2;
Record.push(move);
this.executeMove(move);
this.measure();
}
if(left==black && right==black){
move = 3;
Record.push(move);
this.executeMove(move);
break;
}
}
// Path replication
Record.reverse();
System.out.println("Set Tour Guide on replication position.");
Button.ENTER.waitForPress();
while(!Record.isEmpty()){
move = Record.pop();
this.executeMove(move);
}
Button.ENTER.waitForPress();
}
public boolean isWhite(int intensity){
return intensity > blackAndWhiteThreshold;
}
// Updates the light intensity of both sensors.
public void measure(){
int leftIntensity = leftSensor.readNormalizedValue();
int rightIntensity = rightSensor.readNormalizedValue();
left = this.isWhite(leftIntensity);
right = this.isWhite(rightIntensity);
}
public static void main (String[] args){
new TourGuide().run();
}
}
class List{
byte header;
byte value;
List next;
public List(){
value = header;
next = null;
}
public List(byte val){
value = val;
next = null;
}
}
class Stack{
List L;
public Stack(){
L = new List();
}
public void push(byte val){
List pointer = new List(val);
pointer.next = L.next;
L.next = pointer;
}
public byte pop(){
byte val = L.next.value;
L.next = L.next.next;
return val;
}
public boolean isEmpty(){
return L.next == null;
}
public void reverse(){
Stack reversed = new Stack();
while(!this.isEmpty()){
byte val = this.pop();
reversed.push(val);
}
L = reversed.L;
}
}