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 DecelerationProfile
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 DecelerationProfile(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 setDecelerationFromSpeed(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 getDeceleration(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 getBrakeTime(final double initialSpeed, final double endSpeed)
113 {
114 if (!this.initialized)
115 initializeProfile();
116 return this.profile.getBrakeTime(initialSpeed, endSpeed);
117 }
118
119 /***
120 * @param initialSpeed
121 * @param endSpeed
122 * @return the distance to brake from the initialSpeed to the endSpeed
123 */
124 public double getBrakeDistance(final double initialSpeed,
125 final double endSpeed)
126 {
127 if (!this.initialized)
128 initializeProfile();
129 return this.profile.getBrakeDistance(initialSpeed, endSpeed);
130 }
131
132 /***
133 * Inner class to store the acc/dec points at certain speeds <br>
134 * (c) <br>
135 * (c) copyright 2003-2004 <a href="http://www.simulation.tudelft.nl">Delft
136 * University of Technology </a>, the Netherlands. <br>
137 * See for project information <a href="http://www.simulation.tudelft.nl">
138 * www.simulation.tudelft.nl </a> <br>
139 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General
140 * Public License (GPL) </a>, no warranty <br>
141 *
142 * @version Jul 5, 2004 <br>
143 * @author <a
144 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
145 * Verbraeck </a>
146 */
147 private class AccDecPoint
148 {
149 /*** the speed from which the acceleration/deceleration holds */
150 private double speed;
151
152 /*** the acceleration/deceleration */
153 private double accdec;
154
155 /***
156 * @param speed
157 * @param accdec
158 */
159 public AccDecPoint(final double speed, final double accdec)
160 {
161 this.speed = speed;
162 this.accdec = accdec;
163 }
164
165 /***
166 * @return Returns the acceleration/deceleration.
167 */
168 public double getAccDec()
169 {
170 return this.accdec;
171 }
172
173 /***
174 * @return Returns the speed.
175 */
176 public double getSpeed()
177 {
178 return this.speed;
179 }
180 }
181 /***
182 * Inner class to store the acceleration or deceleration profile based on
183 * the speed and the acceleration / decelation panel. The class uses a
184 * differential equation to make the calculations. <br>
185 * (c) copyright 2003-2004 <a href="http://www.simulation.tudelft.nl">Delft
186 * University of Technology </a>, the Netherlands. <br>
187 * See for project information <a href="http://www.simulation.tudelft.nl">
188 * www.simulation.tudelft.nl </a> <br>
189 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General
190 * Public License (GPL) </a>, no warranty <br>
191 *
192 * @version Jul 6, 2004 <br>
193 * @author <a
194 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
195 * Verbraeck </a>
196 */
197 private class Profile
198 {
199 /*** the acceleration / deceleration profile */
200 private DecelerationProfile owner;
201
202 /*** the list of speed to brake time */
203 private double[] brakeTime;
204
205 /*** the list of speed to brake distance */
206 private double[] brakeDistance;
207
208 /*** the resolution of the points */
209 private double resolution = 0.1;
210
211 /*** the maximum speed that we have in the arraylist */
212 private double maxSpeed = 0.0;
213
214 /*** the number of points in our profile */
215 private int points;
216
217 /***
218 * @param owner
219 * @param maxSpeed
220 */
221 public Profile(final DecelerationProfile owner, final double maxSpeed)
222 {
223 this.maxSpeed = maxSpeed;
224 this.points = (int) (this.maxSpeed / this.resolution) + 1;
225 this.owner = owner;
226 this.brakeTime = new double[this.points];
227 this.brakeDistance = new double[this.points];
228
229
230 Driving driving = new Driving(this.owner, 0.001,
231 NumericalIntegrator.RUNGEKUTTA4);
232 double speed = this.maxSpeed;
233 double x = 0.0;
234 double time = 0.0;
235 while (speed > 0)
236 {
237 driving.initialize(time, new double[]{speed, x});
238 time = time + 0.001;
239 double[] vx = driving.y(time);
240 speed = vx[0];
241 double dx = vx[1] - x;
242 x = vx[1];
243 int i = getPoint(speed);
244 this.brakeTime[i] += 0.001;
245 this.brakeDistance[i] += dx;
246 }
247 for (int i = 0; i < this.points - 1; i++)
248 {
249 this.brakeTime[i + 1] += this.brakeTime[i];
250 this.brakeDistance[i + 1] += this.brakeDistance[i];
251 }
252 if (DecelerationProfile.debug)
253 {
254 for (int i = 0; i < this.points; i++)
255 {
256 System.out.println("v=" + getSpeed(i) + ", [t,x]=["
257 + this.brakeTime[i] + "," + this.brakeDistance[i]
258 + "]");
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 brake from the initialSpeed to the endSpeed
286 */
287 public double getBrakeTime(final double initialSpeed,
288 final double endSpeed)
289 {
290 return this.brakeTime[getPoint(initialSpeed)]
291 - this.brakeTime[getPoint(endSpeed)];
292 }
293
294 /***
295 * @param initialSpeed
296 * @param endSpeed
297 * @return the distance to brake from the initialSpeed to the endSpeed
298 */
299 public double getBrakeDistance(final double initialSpeed,
300 final double endSpeed)
301 {
302 return this.brakeDistance[getPoint(initialSpeed)]
303 - this.brakeDistance[getPoint(endSpeed)];
304 }
305
306 /***
307 * The differential equation for braking <br>
308 * (c) copyright 2003-2004 <a
309 * href="http://www.simulation.tudelft.nl">Delft University of
310 * Technology </a>, the Netherlands. <br>
311 * See for project information <a
312 * href="http://www.simulation.tudelft.nl"> www.simulation.tudelft.nl
313 * </a> <br>
314 * License of use: <a
315 * href="http://www.gnu.org/copyleft/gpl.html">General Public License
316 * (GPL) </a>, no warranty <br>
317 *
318 * @version Jul 6, 2004 <br>
319 * @author <a
320 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
321 * Verbraeck </a>
322 */
323 private class Driving extends DifferentialEquation
324 {
325 /*** the acceleration / deceleration profile */
326 private DecelerationProfile owner;
327
328 /***
329 * @param owner
330 * @param timeStep
331 */
332 public Driving(final DecelerationProfile owner,
333 final double timeStep)
334 {
335 super(timeStep);
336 this.owner = owner;
337 }
338
339 /***
340 * @param owner
341 * @param timeStep
342 * @param integrator
343 */
344 public Driving(final DecelerationProfile owner,
345 final double timeStep, final NumericalIntegrator integrator)
346 {
347 super(timeStep, integrator);
348 this.owner = owner;
349 }
350
351 /***
352 * @param owner
353 * @param timeStep
354 * @param integrationMethod
355 */
356 public Driving(final DecelerationProfile owner,
357 final double timeStep, final short integrationMethod)
358 {
359 super(timeStep, integrationMethod);
360 this.owner = owner;
361 }
362
363 /***
364 * @see nl.tudelft.simulation.jstats.ode.DifferentialEquationInterface#dy(double,
365 * double[])
366 */
367 public double[] dy(double x, double[] y)
368 {
369
370 double[] dy = new double[2];
371 dy[0] = this.owner.getDeceleration(y[0]);
372 dy[1] = y[0];
373 return dy;
374 }
375
376 /***
377 * @see nl.tudelft.simulation.jstats.ode.DifferentialEquationInterface#y(double)
378 */
379 public double[] y(double x)
380 {
381 double[] y = super.y(x);
382 y[0] = Math.max(0.0, y[0]);
383 return y;
384 }
385 }
386 }
387
388 /***
389 * @param args
390 */
391 public static void main(String[] args)
392 {
393 try
394 {
395 DecelerationProfile dp = new DecelerationProfile(14.0);
396 dp.setDecelerationFromSpeed(0.0, -1.0);
397 dp.initializeProfile();
398 System.out.println("Brake distance from 14.0 to 0.0 = "
399 + dp.getBrakeDistance(14.0, 0.0));
400 System.out.println("Brake distance from 14.0 to 7.0 = "
401 + dp.getBrakeDistance(14.0, 7.0));
402 System.out.println("Brake distance from 7.0 to 0.0 = "
403 + dp.getBrakeDistance(7.0, 0.0));
404 System.out.println("Brake time from 14.0 to 0.0 = "
405 + dp.getBrakeTime(14.0, 0.0));
406 System.out.println("Brake time from 14.0 to 7.0 = "
407 + dp.getBrakeTime(14.0, 7.0));
408 System.out.println("Brake time from 7.0 to 0.0 = "
409 + dp.getBrakeTime(7.0, 0.0));
410 } catch (Exception e)
411 {
412 e.printStackTrace();
413 }
414 }
415 }