-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVehicle2D.java
More file actions
executable file
·291 lines (272 loc) · 9.6 KB
/
Vehicle2D.java
File metadata and controls
executable file
·291 lines (272 loc) · 9.6 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
288
289
290
291
/*
* Vehicle2D.java
* 2D vehicle model.
* Vehicle will run based on specified speed and trajectory.
*
* Created on June 15, 2006, 1:36 PM
*/
/**
* @author Chen-Fu Liao
* Sr. Systems Engineer
* ITS Institute, ITS Laboratory
* Center For Transportation Studies
* University of Minnesota
* 200 Transportation and Safety Building
* 511 Washington Ave. SE
* Minneapolis, MN 55455
*/
import java.awt.* ;
import java.util.Random ;
public class Vehicle2D {
private int route_id ; // 0 - left turn, 1 - right turn, 2 & after - straight thru
private int dir_id ; // direction id, 0-EB, 1-WB, 2-NB, 3-SB
public int width = 12 ; // 6 ft
public int length = 30 ; // 15 ft
private float heading = 0f ; // vehicle heading in radians, 0-East
private Point pos = new Point(0, 0) ; // vehicle location
//private Point obstacle = new Point(-1, -1) ;
private Point[] boundary = new Point[4] ; // vehicle boundaries 4 points
private int[] xpoints = new int[4]; // transformed vehicle corners
private int[] ypoints = new int[4];
private Color myColor = Color.blue ; // default veh color
private routeDB myRoute ; // assigned route
private float speed = 0f ; // MPH, 1 MPH ~ 3 pixel/sec
public float speed_control = 1f ; // speed control factor 0-1
//private Runnable runThread0 = null ; // vehicle motion thread
//private Thread tMove ;
//private long tLast, tNow ; // last system clock time
public long tEnterNetwork ; // time vehicel enetered network
private float accuDist = 0f ; // acumulated distance vehicle will tarvel in next time period
private float accuDistf = 0f ; // forecasted accu dist
private int prev_route_index = 0 ;
// public float nearest_veh_dist = 9999f ;
//private boolean vehPaused = true ; // vehicle stopped initially
// public boolean finished = false ; // vehicle finished flag
// Random random = new Random(1) ; // a random class
private Point nextPos = new Point(0, 0) ; // next vehicle location
public boolean veh_stop_flag = false ;
/** Creates a new instance of Vehicle2D */
public Vehicle2D() {
}
public Vehicle2D(int _dir, int _route, routeDB _newRoute, float _spd) {
dir_id = _dir ;
route_id = _route ;
speed = _spd ;
myRoute = _newRoute ;
myRoute.setIndex(0) ;
pos = myRoute.getPosition(0) ; // init position
heading = myRoute.getHeading(0) ; // init heading
for (int i=0; i<4; i++) {
boundary[i] = new Point(0,0) ;
}
}
// public methods here
public void restorePrevRouteIndex() {
myRoute.setIndex(prev_route_index) ;
nextPos.x = pos.x ;
nextPos.y = pos.y ;
}
public void forecastNextPosition(float _dt) {
float distf, link_distf ;
if (!veh_stop_flag) {
if (route_id==0) { // left turn lane
distf = _dt * speed * speed_control ; //* 2.9f ; // pix/sec=pixel/ft * ft/sec
} else {
distf = _dt * speed * speed_control / 2.9f ; // pix/sec=pixel/ft * ft/sec
}
prev_route_index = myRoute.getIndex() ; // save a copy
link_distf = myRoute.dist2NextPt() ;
accuDistf = accuDist ;
accuDistf += distf ;
//System.out.println("accu_dist="+accuDist+", link_dist="+link_dist) ;
while (accuDistf>=link_distf) {
accuDistf -= link_distf ;
myRoute.nextIndex() ;
link_distf = myRoute.dist2NextPt() ;
if (myRoute.getIndex()==myRoute.getDataSize()-1) {
// end of animation
//vehPaused = true ;
//finished = true ;
break ;
//tMove.destroy() ;
} // end if
} // end while
nextPos = myRoute.getTargetPosition(accuDistf) ;
} // if stop_flag
// return forecasted position at next sim time step
//return nextPos ;
}
// get next forecasted vehicle position
public Point getNextForecastedPos() {
return nextPos ;
}
public String getNextForecastedPos2Str() {
String str = "("+nextPos.x + ", " + nextPos.y + ")" ;
return str ;
}
// update vehicle position
public void updatePos() {
pos.x = nextPos.x ;
pos.y = nextPos.y ;
accuDist = accuDistf ;
prev_route_index = myRoute.getIndex() ; // save a copy
updateBoundary() ;
}
public void vehPause() {
veh_stop_flag = true ;
}
public void vehResume() {
veh_stop_flag = false ;
speed_control = 1f ;
}
// vehicle color
//public void setColor(Color _c) {
// myColor = _c ;
//}
// generate random vehicle color
public void setColor(int r, int g, int b) {
if (colorNearBy(r, 123, 5) && colorNearBy(g, 123, 5) && colorNearBy(b, 123, 5)) {
myColor = Color.black ;
} else {
myColor = new Color(r, g, b) ;
}
}
public Color getVehColor() {
return myColor ;
}
private boolean colorNearBy(int v1, int v2, int dv) {
if (Math.abs(v1-v2) <= dv) {
return true ;
} else {
return false ;
}
}
// calculate vehicle boundary with corresponding heading
private void updateBoundary() {
//pos = _newPos ;
heading = myRoute.getCurrentHeading() ;
//System.out.println("heading="+heading);
Point vertex = new Point(0,0) ;
vertex.x = length/2 ;
vertex.y = width/2 ;
boundary[0] = transform(vertex) ;
vertex.x = -length/2 ;
vertex.y = width/2 ;
boundary[1] = transform(vertex) ;
vertex.x = -length/2 ;
vertex.y = -width/2 ;
boundary[2] = transform(vertex) ;
vertex.x = length/2 ;
vertex.y = -width/2 ;
boundary[3] = transform(vertex) ;
for (int i=0; i<4; i++) {
xpoints[i] = boundary[i].x ;
ypoints[i] = boundary[i].y ;
}
}
// 2D vector transform of current vehicle boundary point
private Point transform(Point pt1) {
Point pt2 = new Point(0,0) ;
pt2.x = pos.x + new Double(pt1.x*Math.cos(heading)+pt1.y*Math.sin(heading)).intValue() ;
pt2.y = pos.y + new Double(-pt1.x*Math.sin(heading)+pt1.y*Math.cos(heading)).intValue() ;
return pt2 ;
}
public int[] getXpoints() {
return xpoints ;
}
public int[] getYpoints() {
return ypoints ;
}
public String getPosition2Str() {
String str = "("+pos.x + ", " + pos.y + ")" ;
return str ;
}
public Point getPosition() {
return pos ;
}
public int getRouteID() {
return route_id ;
}
public int getRouteIndex() {
return myRoute.getIndex() ;
}
public int getVehAtLink() {
return myRoute.getLinkID() ;
}
public void slowdown() {
speed_control = .3f ;
}
public void slowdown(float sf) {
speed_control = sf ;
}
public void stop() {
speed_control = 0f ;
veh_stop_flag = true ;
}
public boolean isVehStopped() {
return veh_stop_flag ;
}
public Point getFrontBumperCenter() {
int fbcx = (boundary[0].x + boundary[3].x)/2 ;
int fbcy = (boundary[0].y + boundary[3].y)/2 ;
return new Point(fbcx, fbcy) ;
}
public String getFrontBumperCenter2Str() {
int fbcx = (boundary[0].x + boundary[3].x)/2 ;
int fbcy = (boundary[0].y + boundary[3].y)/2 ;
return "("+fbcx+", "+fbcy+")" ;
}
public Point getRearBumperCenter() {
int rbcx = (boundary[1].x + boundary[2].x)/2 ;
int rbcy = (boundary[1].y + boundary[2].y)/2 ;
return new Point(rbcx, rbcy) ;
}
public routeDB getRoute() {
return myRoute ;
}
public float getHeading() {
return heading ;
}
public mPointF headingVector() {
// vehicle heading vector
mPointF hVector = new mPointF(xpoints[0]-xpoints[1], ypoints[0]-ypoints[1]) ;
return hVector.unitVector() ;
}
// check if clicked point inside vehicle boundary
public boolean isClicked(int x, int y) {
boolean in_flag = false ;
int i ;
int j=0 ;
for (i=1; i<4; i++) {
j=i-1 ;
if ((((ypoints[i] <= y) && (y < ypoints[j])) || ((ypoints[j] <= y) && (y < ypoints[i])))
&& (x < (xpoints[j] - xpoints[i]) * (y - ypoints[i]) / (ypoints[j] - ypoints[i]) + xpoints[i])) {
in_flag = !in_flag ;
}
} // end for
return in_flag ;
//System.out.println("IN_FLAG="+in_flag+VIDStr(100)) ;
/*
int dx = x - pos.x ;
int dy = y - pos.y ;
double dist = Math.sqrt(dx*dx+dy*dy) ;
if (dist<=length) {
return true ;
} else {
return false ;
}
*/
}
public float getSpeed() {
return speed * speed_control * 2.933f ;
}
public float getSpeed_MPH() {
return speed ;
}
public float getAccuDist() {
return accuDist ;
}
public String VIDStr(int veh_index) {
return "("+dir_id+", "+veh_index+", "+route_id+")" ;
}
}