forked from Elsie4ever/DpmTeam2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Odometer.java
269 lines (242 loc) · 6.59 KB
/
Odometer.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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
* File: Odometer.java
* Written by: Sean Lawlor
* ECSE 211 - Design Principles and Methods, Head TA
* Fall 2011
* Ported to EV3 by: Francois Ouellet Delorme
* Fall 2015
*
* Class which controls the odometer for the robot
*
* Odometer defines coordinate system as such...
*
* 90Deg:pos y-axis
* |
* |
* |
* |
* 180Deg:neg x-axis------------------0Deg:pos x-axis
* |
* |
* |
* |
* 270Deg:neg y-axis
*
* The odometer is initalized to 90 degrees, assuming the robot is facing up the positive y-axis
*
*/
package trotty02;
import lejos.utility.Timer;
import lejos.utility.TimerListener;
import lejos.hardware.motor.EV3LargeRegulatedMotor;
public class Odometer implements TimerListener {
private Timer timer;
private EV3LargeRegulatedMotor leftMotor, rightMotor;
private final int DEFAULT_TIMEOUT_PERIOD = 20;
private double leftRadius, rightRadius, width;
private double x, y, theta;
private double[] oldDH, dDH;
private UltrasonicPoller usPoller;
private LightPoller lsPoller;
// constructor
/**
* Constructor for the odometer class
* @param leftMotor the left motor of the robot
* @param rightMotor the right motor of the robot
* @param INTERVAL the length at which it parses the information read
* @param autostart boolean value of whether the odometer should start on its own
* @param usPoller an ultrasonic poller
* @param lsPoller a light poller
*/
public Odometer (EV3LargeRegulatedMotor leftMotor, EV3LargeRegulatedMotor rightMotor, int INTERVAL, boolean autostart,
UltrasonicPoller usPoller, LightPoller lsPoller) {
this.lsPoller = lsPoller;
this.usPoller = usPoller;
this.leftMotor = leftMotor;
this.rightMotor = rightMotor;
this.rightRadius = 2.1;
this.leftRadius = 2.1;
this.width = 13.5;
this.x = 0.0;
this.y = 0.0;
this.theta = 90;
this.oldDH = new double[2];
this.dDH = new double[2];
if (autostart) {
// if the timeout interval is given as <= 0, default to 20ms timeout
this.timer = new Timer((INTERVAL <= 0) ? INTERVAL : DEFAULT_TIMEOUT_PERIOD, this);
this.timer.start();
} else
this.timer = null;
}
/**
* functions to start/stop the timerlistener
*/
public void stop() {
if (this.timer != null)
this.timer.stop();
}
public void start() {
if (this.timer != null)
this.timer.start();
}
/**
* Calculates displacement and heading as title suggests
*
* @param data the array containing information of the distance forwards and the current heading
*/
private void getDisplacementAndHeading(double[] data) {
int leftTacho, rightTacho;
leftTacho = leftMotor.getTachoCount();
rightTacho = rightMotor.getTachoCount();
data[0] = (leftTacho * leftRadius + rightTacho * rightRadius) * Math.PI / 360.0;
data[1] = (rightTacho * rightRadius - leftTacho * leftRadius) / width;
}
/**
* Recompute the odometer values using the displacement and heading changes
*/
public void timedOut() {
this.getDisplacementAndHeading(dDH);
dDH[0] -= oldDH[0];
dDH[1] -= oldDH[1];
// update the position in a critical region
synchronized (this) {
theta += dDH[1];
theta = fixDegAngle(theta);
x += dDH[0] * Math.cos(Math.toRadians(theta));
y += dDH[0] * Math.sin(Math.toRadians(theta));
}
oldDH[0] += dDH[0];
oldDH[1] += dDH[1];
}
/**
* return the X value
* @return the x value determined by the odometer
*/
public double getX() {
synchronized (this) {
return x;
}
}
/**
* return the Y value
* @return the y value determined by the odometer
*/
public double getY() {
synchronized (this) {
return y;
}
}
/**
* return the theta value
* @return the theta value determined by the odometer
*/
public double getAng() {
synchronized (this) {
return theta;
}
}
/**
* set the X, Y and theta values
* @param position an array that contains the X value, the Y value and the theta
* @param update boolean array that states whether each corresponding value should be updated
*/
public void setPosition(double[] position, boolean[] update) {
synchronized (this) {
if (update[0])
x = position[0];
if (update[1])
y = position[1];
if (update[2])
theta = position[2];
}
}
// return x,y,theta
/**
* returns nothing, stores X, Y and theta data into input array
* @param position the array in which X, Y and theta are stored
*/
public void getPosition(double[] position) {
synchronized (this) {
position[0] = x;
position[1] = y;
position[2] = theta;
}
}
/**
* returns a double array containing X, Y and theta
* @return the x, y and theta values
*/
public double[] getPosition() {
synchronized (this) {
return new double[] { x, y, theta };
}
}
// accessors to motors
/**
* gives the wheel motors
* @return the left and right motors
*/
public EV3LargeRegulatedMotor [] getMotors() {
return new EV3LargeRegulatedMotor[] {this.leftMotor, this.rightMotor};
}
/**
* gives just the left motor
* @return just the left motor
*/
public EV3LargeRegulatedMotor getLeftMotor() {
return this.leftMotor;
}
/**
* gives just the left motor
* @return just the left motor
*/
public EV3LargeRegulatedMotor getRightMotor() {
return this.rightMotor;
}
// static 'helper' methods
/**
* gives the principle angle
* @param angle if greater than 360 or less than 0, it returns an equivalant angle between 0 and 360
* @return the corrected angle
*/
public static double fixDegAngle(double angle) {
if (angle < 0.0)
angle = 360.0 + (angle % 360.0);
return angle % 360.0;
}
/**
* gives the principle angle between two other angles
* @param a the starting angle
* @param b the ending angle
* @return the minimum angle between b and a
*/
public static double minimumAngleFromTo(double a, double b) {
double d = fixDegAngle(b - a);
if (d < 180.0)
return d;
else
return d - 360.0;
}
/**
* gives the current heading
* @return returns the heading of the bot
*/
public double getTheta() {
return theta;
}
/**
* says if it sees an object on the front usSensor
* @return does the bot see something
*/
public boolean seesSomething(){
return this.usPoller.seesSomething();
}
/**
* says if it sees a blue block on the light sensor
* @return true if there is a blue block, otherwise false
*/
public boolean seesBlock() {
return this.lsPoller.seesBlock();
}
}