-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathaxisInterface.java
More file actions
287 lines (197 loc) · 7.77 KB
/
axisInterface.java
File metadata and controls
287 lines (197 loc) · 7.77 KB
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
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
import java.util.ArrayList;
import lejos.hardware.Battery;
import lejos.hardware.Button;
import lejos.robotics.geometry.Point;
import lejos.robotics.navigation.Waypoint;
import lejos.robotics.pathfinding.Path;
public class axisInterface{
private axisController xAxis;
private axisController zAxis;
private penController Pen;
private ArrayList<String> functionCalls = new ArrayList<String>();
public axisInterface(axisController xAxis, axisController zAxis, penController Pen) {
// takes in all needed controllers for the robot to move and function
this.xAxis = xAxis;
this.zAxis = zAxis;
this.Pen = Pen;
for(int i = 0; i < 6; i++) {
this.functionCalls.add("None");
}
// this is called after the axis controllers are calibrated
System.out.println("Boundrys");
System.out.println(this.xAxis.getAxisLength());
System.out.println(this.zAxis.getAxisLength());
}
// Due to issues with how the motors affect each other while moving, they have to move seperately
// Therefore they cannot by synced or be moving at the same time
public void moveToPoint(Waypoint point, boolean Interpolate) {
// takes in a waypoint and a bool to create a new path between the current point and given waypoint
// if the ShouldInterpolate function returns true and our bool is true, we generate a new path between the points
// the generated path is then passed to FollowGenPath which functions different to FollowPath so certain things dont happen
// like pen movement and regeneration interpolated paths
double currentX = this.xAxis.getCurrentLocation();
double currentZ = this.zAxis.getCurrentLocation();
Waypoint currentLocal = new Waypoint(currentX, currentZ);
shouldEnd();
if(this.shouldInterpolate(currentLocal, point) && Interpolate) {
shouldEnd();
Path interpolatedPoints = this.generateInterpolatedPath(currentLocal, point);
this.followGenPath(interpolatedPoints, false);
}
else {
// If we dont interpolate, we find the distance between the given point
// and pass that into each axis Controller
shouldEnd();
int moveDistanceX = (int) (point.getX() - currentX);
System.out.println("Moving " + moveDistanceX + "*");
this.xAxis.goDegrees(moveDistanceX);
shouldEnd();
int moveDistanceZ = (int) (point.getY() - currentZ);
System.out.println("Moving " + moveDistanceZ + "*");
this.zAxis.goDegrees(moveDistanceZ);
}
}
private void followGenPath(Path path, boolean shouldCalibrate) {
// The same fundimentals as followPath with certain behavious removed
// It will not use the putPenUp or putPenDown functions
// and it purely calls to moveToPoint with no interpolating
int pathSize = path.size();
shouldEnd();
for(int i = 0; i < pathSize; i++) {
Waypoint nextPoint = path.get(i);
shouldEnd();
this.moveToPoint(nextPoint, false);
if(shouldCalibrate && i % 5 == 0) {
this.Recalibrate();
}
}
}
// Follow Path
public void followPath(Path path, boolean shouldCalibrate) {
// has more behvious within this function to start a followPath correctly
// It will move to the starting point first then use putPenDown
// then call to moveToPoint for each waypoint
// Once complete it will call putPenUp ensuring its ready to draw another path
// Move to start of Path
if(!this.isValidPath(path)) { // if the path is invalid, we return and dont run the path
return;
}
//if(this.isBatteryLow()) { // if battery low returns true, we return and don't run the path
// return;
//}
shouldEnd();
Waypoint startLocal = path.get(0);
this.moveToPoint(startLocal, false);
// Pen Down
this.Pen.putPenDown();
// Run Path
int pathSize = path.size();
for(int i = 1; i < pathSize; i++) {
Waypoint nextPoint = path.get(i);
System.out.println("Turn " + i);
System.out.println("Going to " + nextPoint.x + ", " + nextPoint.y);
shouldEnd();
this.moveToPoint(nextPoint, true);
if(shouldCalibrate && i % 5 == 0) {
this.Recalibrate();
}
}
// Pen Up
this.Pen.putPenUp();
}
private boolean isValidPath(Path path) {
// Goes over every point within a path and make sure that
// every point is within the boundries
// if it isnt then the whole path is deemed invalid and won't run
int xMax = this.xAxis.getAxisLength();
int zMax = this.zAxis.getAxisLength();
shouldEnd();
for(int i = 0; i < path.size(); i++) {
Waypoint point = path.get(i);
if(point.getX() > xMax || point.getY() > zMax || point.getX() < 0 || point.getY() < 0)
return false;
}
return true;
}
public boolean shouldInterpolate(Waypoint p1, Waypoint p2) {
// looks at the 2 points given and desides based
// on distance and angle whether we should interpolate
// making sure that if a line is basically straight it wont create extra points slowing the robot down
// and if the points are basically next to each other it'll just work normally and not make more points
double distance = p1.distance(p2.getX(), p2.getY());
double gradient = Math.toDegrees(Math.asin(( p2.getX() - p1.getX() ) / ( p2.getY() - p1.getY() )));
shouldEnd();
if(distance <= this.xAxis.getAxisLength() * 0.05 || gradient % 90.0 <= 3.0 || gradient % 90 >= 86.0 ) {
return false;
}
return true;
}
// Generate Interpolated Path
private Path generateInterpolatedPath(Waypoint p1, Waypoint p2) {
Path returnPath = new Path();
// will use the Two given waypoints and an interpolation value to generate new points between them
// our interpolation value changes the size between each value and how many new points there will be
// out loop goes through using the "float counter" as a percentage of how far between the Two points we are
// using the counter variable we generate a new point between the two points using the counter as a %
// of how far from the first one we are
shouldEnd();
float interpolationValue = 10f;
double distance = p1.distance(p2.getX(), p2.getY());
float counter = 0.0F;
float x0 = (float) p1.getX();
float y0 = (float) p1.getY();
float x1 = (float) p2.getX();
float y1 = (float) p2.getY();
for(int i = 0; i < interpolationValue; i++) {
float dt = (float) (distance * counter);
float tRatio = (float) (dt / distance);
shouldEnd();
float xt = ((1-tRatio) * x0 + tRatio *x1);
float yt = ((1-tRatio) * y0 + tRatio *y1);
Waypoint newPoint = new Waypoint(xt,yt);
returnPath.add(newPoint);
counter += (interpolationValue)/100f;
}
return returnPath;
}
private boolean isBatteryLow() {
double lowBatteryThreshhold = 0.2;
return (Battery.getVoltage() / 9.0) > lowBatteryThreshhold;
}
private void shouldEnd() {
if(Button.ENTER.isDown()) {
System.exit(0);
}
}
// Recalibrate
private void Recalibrate() {
//penUp
//goToOrigin
//goToPreviousLocation
//penDown
}
public double getXScalar() {
// returns 1 or a number to make a point line up square on each axis
double xLen = this.xAxis.getAxisLength();
double yLen = this.zAxis.getAxisLength();
if(xLen > yLen) {
return xLen / yLen;
}
return 1;
}
public double getXLength() {
return this.xAxis.getAxisLength();
}
public double getYScalar() {
// returns 1 or a number to make a point line up square on each axis
double xLen = this.xAxis.getAxisLength();
double yLen = this.zAxis.getAxisLength();
if(yLen > xLen) {
return yLen / xLen;
}
return 1;
}
public double getYLength() {
return this.zAxis.getAxisLength();
}
}