1
2
3
4
5
6
7
8
9
10
11 package nl.tudelft.simulation.traffic.vehicle;
12
13 import java.util.ArrayList;
14
15 import nl.tudelft.simulation.jstats.ode.DifferentialEquation;
16 import nl.tudelft.simulation.jstats.ode.integrators.NumericalIntegrator;
17
18 /***
19 * <br>
20 * (c) copyright 2003-2004 <a href="http://www.simulation.tudelft.nl">Delft
21 * University of Technology </a>, the Netherlands. <br>
22 * See for project information <a href="http://www.simulation.tudelft.nl">
23 * www.simulation.tudelft.nl </a> <br>
24 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General
25 * Public License (GPL) </a>, no warranty <br>
26 *
27 * @version Jul 5, 2004 <br>
28 * @author <a
29 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
30 * Verbraeck </a>
31 */
32 public class AccelerationProfile
33 {
34 /*** the speed dependent acceleration / deceleration parameters */
35 private ArrayList accdecList = new ArrayList();
36
37 /*** the maximum speed that we have in the arraylist */
38 private double maxSpeed = 0.0;
39
40 /*** the dirty bit */
41 private boolean initialized;
42
43 /*** the profile */
44 private Profile profile;
45
46 /*** print table for debugging */
47 protected static boolean debug = false;
48
49 /***
50 * create a new acceleration / deceleration profile
51 *
52 * @param maxSpeed
53 */
54 public AccelerationProfile(final double maxSpeed)
55 {
56 super();
57 this.initialized = false;
58 this.maxSpeed = maxSpeed;
59 }
60
61 /***
62 * Set the acceleration / deceleration for current speed HIGHER than speed.
63 * Add the points in increasing speed. Sorting is not (yet) done
64 * automatically.
65 *
66 * @param speed the speed above which accdec is used
67 * @param accdec the acceleration (positive) or deceleration (negative)
68 */
69 public void setAccelerationFromSpeed(final double speed, final double accdec)
70 {
71 this.accdecList.add(new AccDecPoint(speed, accdec));
72 this.initialized = false;
73 }
74
75 /***
76 * Gets the acceleration / deceleration for a given speed
77 *
78 * @param speed
79 * @return
80 */
81 public double getAcceleration(final double speed)
82 {
83 double accdec = 0.0;
84 for (int i = 0; i < this.accdecList.size(); i++)
85 {
86 double adspeed = ((AccDecPoint) this.accdecList.get(i)).getSpeed();
87 if (speed >= adspeed)
88 {
89 accdec = ((AccDecPoint) this.accdecList.get(i)).getAccDec();
90 } else
91 {
92 return accdec;
93 }
94 }
95 return accdec;
96 }
97
98 /***
99 *
100 */
101 public void initializeProfile()
102 {
103 this.profile = new Profile(this, this.maxSpeed);
104 this.initialized = true;
105 }
106
107 /***
108 * @param initialSpeed
109 * @param endSpeed
110 * @return the time to brake from the initialSpeed to the endSpeed
111 */
112 public double getAccelerationTime(final double initialSpeed,
113 final double endSpeed)
114 {
115 if (!this.initialized)
116 initializeProfile();
117 return this.profile.getAccelerationTime(initialSpeed, endSpeed);
118 }
119
120 /***
121 * @param initialSpeed
122 * @param endSpeed
123 * @return the distance to brake from the initialSpeed to the endSpeed
124 */
125 public double getAccelerationDistance(final double initialSpeed,
126 final double endSpeed)
127 {
128 if (!this.initialized)
129 initializeProfile();
130 return this.profile.getAccelerationDistance(initialSpeed, endSpeed);
131 }
132
133 /***
134 * Inner class to store the acc/dec points at certain speeds <br>
135 * (c) <br>
136 * (c) copyright 2003-2004 <a href="http://www.simulation.tudelft.nl">Delft
137 * University of Technology </a>, the Netherlands. <br>
138 * See for project information <a href="http://www.simulation.tudelft.nl">
139 * www.simulation.tudelft.nl </a> <br>
140 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General
141 * Public License (GPL) </a>, no warranty <br>
142 *
143 * @version Jul 5, 2004 <br>
144 * @author <a
145 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
146 * Verbraeck </a>
147 */
148 private class AccDecPoint
149 {
150 /*** the speed from which the acceleration/deceleration holds */
151 private double speed;
152
153 /*** the acceleration/deceleration */
154 private double accdec;
155
156 /***
157 * @param speed
158 * @param accdec
159 */
160 public AccDecPoint(final double speed, final double accdec)
161 {
162 this.speed = speed;
163 this.accdec = accdec;
164 }
165
166 /***
167 * @return Returns the acceleration/deceleration.
168 */
169 public double getAccDec()
170 {
171 return this.accdec;
172 }
173
174 /***
175 * @return Returns the speed.
176 */
177 public double getSpeed()
178 {
179 return this.speed;
180 }
181 }
182 /***
183 * Inner class to store the acceleration or deceleration profile based on
184 * the speed and the acceleration / decelation panel. The class uses a
185 * differential equation to make the calculations. <br>
186 * (c) copyright 2003-2004 <a href="http://www.simulation.tudelft.nl">Delft
187 * University of Technology </a>, the Netherlands. <br>
188 * See for project information <a href="http://www.simulation.tudelft.nl">
189 * www.simulation.tudelft.nl </a> <br>
190 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General
191 * Public License (GPL) </a>, no warranty <br>
192 *
193 * @version Jul 6, 2004 <br>
194 * @author <a
195 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
196 * Verbraeck </a>
197 */
198 private class Profile
199 {
200 /*** the acceleration / deceleration profile */
201 private AccelerationProfile owner;
202
203 /*** the list of speed to brake time */
204 private double[] accTime;
205
206 /*** the list of speed to brake distance */
207 private double[] accDistance;
208
209 /*** the resolution of the points */
210 private double resolution = 0.1;
211
212 /*** the maximum speed that we have in the arraylist */
213 private double maxSpeed = 0.0;
214
215 /*** the number of points in our profile */
216 private int points;
217
218 /***
219 * @param owner
220 * @param maxSpeed
221 */
222 public Profile(final AccelerationProfile owner, final double maxSpeed)
223 {
224 this.maxSpeed = maxSpeed;
225 this.points = (int) (this.maxSpeed / this.resolution) + 1;
226 this.owner = owner;
227 this.accTime = new double[this.points];
228 this.accDistance = new double[this.points];
229
230
231 Driving driving = new Driving(this.owner, 0.001,
232 NumericalIntegrator.RUNGEKUTTA4);
233 double speed = 0.0;
234 double x = 0.0;
235 double time = 0.0;
236 while (speed <= this.maxSpeed)
237 {
238 driving.initialize(time, new double[]{speed, x});
239 time = time + 0.001;
240 double[] vx = driving.y(time);
241 speed = vx[0];
242 double dx = vx[1] - x;
243 x = vx[1];
244 int i = getPoint(speed);
245 this.accTime[i] += 0.001;
246 this.accDistance[i] += dx;
247 }
248 for (int i = 0; i < this.points - 1; i++)
249 {
250 this.accTime[i + 1] += this.accTime[i];
251 this.accDistance[i + 1] += this.accDistance[i];
252 }
253 if (AccelerationProfile.debug)
254 {
255 for (int i = 0; i < this.points; i++)
256 {
257 System.out.println("v=" + getSpeed(i) + ", [t,x]=["
258 + this.accTime[i] + "," + this.accDistance[i] + "]");
259 }
260 }
261 }
262
263 /***
264 * @param speed
265 * @return
266 */
267 private int getPoint(final double speed)
268 {
269 int point = (int) ((speed / this.maxSpeed) * this.points);
270 return Math.min(this.points - 1, Math.max(point, 0));
271 }
272
273 /***
274 * @param point
275 * @return
276 */
277 private double getSpeed(final int point)
278 {
279 return this.resolution * point;
280 }
281
282 /***
283 * @param initialSpeed
284 * @param endSpeed
285 * @return the time to accelerate from the initialSpeed to the endSpeed
286 */
287 public double getAccelerationTime(final double initialSpeed,
288 final double endSpeed)
289 {
290 return this.accTime[getPoint(endSpeed)]
291 - this.accTime[getPoint(initialSpeed)];
292 }
293
294 /***
295 * @param initialSpeed
296 * @param endSpeed
297 * @return the distance to accelerate from the initialSpeed to the
298 * endSpeed
299 */
300 public double getAccelerationDistance(final double initialSpeed,
301 final double endSpeed)
302 {
303 return this.accDistance[getPoint(endSpeed)]
304 - this.accDistance[getPoint(initialSpeed)];
305 }
306
307 /***
308 * The differential equation for braking <br>
309 * (c) copyright 2003-2004 <a
310 * href="http://www.simulation.tudelft.nl">Delft University of
311 * Technology </a>, the Netherlands. <br>
312 * See for project information <a
313 * href="http://www.simulation.tudelft.nl"> www.simulation.tudelft.nl
314 * </a> <br>
315 * License of use: <a
316 * href="http://www.gnu.org/copyleft/gpl.html">General Public License
317 * (GPL) </a>, no warranty <br>
318 *
319 * @version Jul 6, 2004 <br>
320 * @author <a
321 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
322 * Verbraeck </a>
323 */
324 private class Driving extends DifferentialEquation
325 {
326 /*** the acceleration / deceleration profile */
327 private AccelerationProfile owner;
328
329 /***
330 * @param owner
331 * @param timeStep
332 */
333 public Driving(final AccelerationProfile owner,
334 final double timeStep)
335 {
336 super(timeStep);
337 this.owner = owner;
338 }
339
340 /***
341 * @param owner
342 * @param timeStep
343 * @param integrator
344 */
345 public Driving(final AccelerationProfile owner,
346 final double timeStep, final NumericalIntegrator integrator)
347 {
348 super(timeStep, integrator);
349 this.owner = owner;
350 }
351
352 /***
353 * @param owner
354 * @param timeStep
355 * @param integrationMethod
356 */
357 public Driving(final AccelerationProfile owner,
358 final double timeStep, final short integrationMethod)
359 {
360 super(timeStep, integrationMethod);
361 this.owner = owner;
362 }
363
364 /***
365 * @see nl.tudelft.simulation.jstats.ode.DifferentialEquationInterface#dy(double,
366 * double[])
367 */
368 public double[] dy(double x, double[] y)
369 {
370
371 double[] dy = new double[2];
372 dy[0] = this.owner.getAcceleration(y[0]);
373 dy[1] = y[0];
374 return dy;
375 }
376 }
377 }
378
379 /***
380 * @param args
381 */
382 public static void main(String[] args)
383 {
384 try
385 {
386 AccelerationProfile dp = new AccelerationProfile(14.0);
387 dp.setAccelerationFromSpeed(0.0, 1.0);
388 dp.initializeProfile();
389 System.out.println("Acceleration distance from 0.0 to 14.0 = "
390 + dp.getAccelerationDistance(0.0, 14.0));
391 System.out.println("Acceleration distance from 7.0 to 14.0 = "
392 + dp.getAccelerationDistance(7.0, 14.0));
393 System.out.println("Acceleration distance from 0.0 to 7.0 = "
394 + dp.getAccelerationDistance(0.0, 7.0));
395 System.out.println("Acceleration time from 0.0 to 14.0 = "
396 + dp.getAccelerationTime(0.0, 14.0));
397 System.out.println("Acceleration time from 7.0 to 14.0 = "
398 + dp.getAccelerationTime(7.0, 14.0));
399 System.out.println("Acceleration time from 0.0 to 7.0 = "
400 + dp.getAccelerationTime(0.0, 7.0));
401 } catch (Exception e)
402 {
403 e.printStackTrace();
404 }
405 }
406 }