1 package org.opentrafficsim.road.gtu;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertTrue;
5 import static org.junit.Assert.fail;
6
7 import java.util.ArrayList;
8 import java.util.LinkedHashSet;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.Set;
12
13 import org.djunits.unit.DurationUnit;
14 import org.djunits.unit.LengthUnit;
15 import org.djunits.unit.TimeUnit;
16 import org.djunits.unit.util.UNITS;
17 import org.djunits.value.vdouble.scalar.Acceleration;
18 import org.djunits.value.vdouble.scalar.Direction;
19 import org.djunits.value.vdouble.scalar.Duration;
20 import org.djunits.value.vdouble.scalar.Length;
21 import org.djunits.value.vdouble.scalar.Speed;
22 import org.djunits.value.vdouble.scalar.Time;
23 import org.junit.Test;
24 import org.opentrafficsim.base.parameters.Parameters;
25 import org.opentrafficsim.core.definitions.DefaultsNl;
26 import org.opentrafficsim.core.dsol.AbstractOtsModel;
27 import org.opentrafficsim.core.dsol.OtsModelInterface;
28 import org.opentrafficsim.core.dsol.OtsSimulator;
29 import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
30 import org.opentrafficsim.core.geometry.OtsPoint3d;
31 import org.opentrafficsim.core.gtu.GtuException;
32 import org.opentrafficsim.core.gtu.GtuType;
33 import org.opentrafficsim.core.gtu.RelativePosition;
34 import org.opentrafficsim.core.network.Node;
35 import org.opentrafficsim.core.network.route.Route;
36 import org.opentrafficsim.road.DefaultTestParameters;
37 import org.opentrafficsim.road.definitions.DefaultsRoadNl;
38 import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
39 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedCfLcTacticalPlanner;
40 import org.opentrafficsim.road.gtu.lane.tactical.following.FixedAccelerationModel;
41 import org.opentrafficsim.road.gtu.lane.tactical.following.GtuFollowingModelOld;
42 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.FixedLaneChangeModel;
43 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.LaneChangeModel;
44 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
45 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalRoutePlanner;
46 import org.opentrafficsim.road.network.RoadNetwork;
47 import org.opentrafficsim.road.network.factory.LaneFactory;
48 import org.opentrafficsim.road.network.lane.Lane;
49 import org.opentrafficsim.road.network.lane.LanePosition;
50 import org.opentrafficsim.road.network.lane.LaneType;
51
52 import nl.tudelft.simulation.dsol.SimRuntimeException;
53
54
55
56
57
58
59
60
61
62
63
64 public class AbstractLaneBasedGtuTest implements UNITS
65 {
66
67
68
69
70 @Test
71 public final void abstractLaneBasedGtuTest() throws Exception
72 {
73
74
75
76
77 OtsSimulatorInterface simulator = new OtsSimulator("abstractLaneBasedGtuTest");
78 RoadNetwork network = new RoadNetwork("lane base gtu test network", simulator);
79 OtsModelInterface model = new DummyModel(simulator);
80 simulator.initialize(Time.ZERO, Duration.ZERO, new Duration(1, DurationUnit.HOUR), model);
81 Node nodeAFrom = new Node(network, "AFrom", new OtsPoint3d(0, 0, 0), Direction.ZERO);
82 Node nodeATo = new Node(network, "ATo", new OtsPoint3d(1000, 0, 0), Direction.ZERO);
83 GtuType gtuType = DefaultsNl.CAR;
84 LaneType laneType = DefaultsRoadNl.TWO_WAY_LANE;
85
86 Lane[] lanesGroupA = LaneFactory.makeMultiLane(network, "A", nodeAFrom, nodeATo, null, 3, laneType,
87 new Speed(100, KM_PER_HOUR), simulator, DefaultsNl.VEHICLE);
88
89 Node nodeBFrom = new Node(network, "BFrom", new OtsPoint3d(10, 0, 0), Direction.ZERO);
90 Node nodeBTo = new Node(network, "BTo", new OtsPoint3d(1000, 0, 0), Direction.ZERO);
91 Lane[] lanesGroupB = LaneFactory.makeMultiLane(network, "B", nodeBFrom, nodeBTo, null, 3, laneType,
92 new Speed(100, KM_PER_HOUR), simulator, DefaultsNl.VEHICLE);
93 Set<LanePosition> initialLongitudinalPositions = new LinkedHashSet<>(2);
94
95 Length positionA = new Length(100, METER);
96 initialLongitudinalPositions.add(new LanePosition(lanesGroupA[1], positionA));
97 Length positionB = new Length(90, METER);
98 initialLongitudinalPositions.add(new LanePosition(lanesGroupB[1], positionB));
99
100 Acceleration acceleration = new Acceleration(2, METER_PER_SECOND_2);
101 Duration validFor = new Duration(10, SECOND);
102 GtuFollowingModelOld gfm = new FixedAccelerationModel(acceleration, validFor);
103
104
105 LaneChangeModel laneChangeModel = new FixedLaneChangeModel(null);
106
107 Speed initialSpeed = new Speed(50, KM_PER_HOUR);
108
109 Length carLength = new Length(4, METER);
110
111 Length carWidth = new Length(1.8, METER);
112
113 Speed maximumSpeed = new Speed(200, KM_PER_HOUR);
114
115 String carID = "theCar";
116
117 List<Node> nodeList = new ArrayList<Node>();
118 nodeList.add(nodeAFrom);
119 nodeList.add(nodeATo);
120
121 Route route = new Route("Route", gtuType, nodeList);
122
123 Parameters parameters = DefaultTestParameters.create();
124
125
126
127 LaneBasedGtu car = new LaneBasedGtu(carID, gtuType, carLength, carWidth, maximumSpeed, carLength.times(0.5), network);
128 LaneBasedStrategicalPlanner strategicalPlanner =
129 new LaneBasedStrategicalRoutePlanner(new LaneBasedCfLcTacticalPlanner(gfm, laneChangeModel, car), car);
130 car.setParameters(parameters);
131 car.init(strategicalPlanner, initialLongitudinalPositions, initialSpeed);
132
133 assertEquals("ID of the car should be identical to the provided one", carID, car.getId());
134
135
136
137 assertEquals("Width should be identical to the provided width", carWidth, car.getWidth());
138 assertEquals("Length should be identical to the provided length", carLength, car.getLength());
139 assertEquals("GTU type should be identical to the provided one", gtuType, car.getType());
140 assertEquals("front in lanesGroupA[1] is positionA", positionA.getSI(),
141 car.position(lanesGroupA[1], car.getReference()).getSI(), 0.0001);
142 assertEquals("front in lanesGroupB[1] is positionB", positionB.getSI(),
143 car.position(lanesGroupB[1], car.getReference()).getSI(), 0.0001);
144
145
146 assertEquals("acceleration is 2", 2.0, car.getAcceleration().getSI(), 0.00001);
147 assertEquals("longitudinal speed is " + initialSpeed, initialSpeed.getSI(), car.getSpeed().getSI(), 0.00001);
148 assertEquals("lastEvaluation time is 0", 0, car.getOperationalPlan().getStartTime().getSI(), 0.00001);
149
150
151
152
153
154
155
156
157
158
159
160 for (Lane[] laneGroup : new Lane[][] {lanesGroupA, lanesGroupB})
161 {
162 for (int laneIndex = 0; laneIndex < laneGroup.length; laneIndex++)
163 {
164 Lane lane = laneGroup[laneIndex];
165 boolean expectException = 1 != laneIndex;
166 for (RelativePosition relativePosition : new RelativePosition[] {car.getFront(), car.getReference(),
167 car.getRear()})
168 {
169
170
171 try
172 {
173 Length position = car.position(lane, relativePosition);
174 if (expectException)
175 {
176
177 fail("Calling position on lane that the car is NOT on should have thrown a NetworkException");
178 }
179 else
180 {
181 Length expectedPosition = laneGroup == lanesGroupA ? positionA : positionB;
182 expectedPosition = expectedPosition.plus(relativePosition.getDx());
183
184
185 assertEquals("Position should match initial position", expectedPosition.getSI(), position.getSI(),
186 0.0001);
187 }
188 }
189 catch (GtuException ne)
190 {
191 if (!expectException)
192 {
193 System.out.println(ne);
194 fail("Calling position on lane that the car is on should NOT have thrown a NetworkException");
195 }
196 }
197 }
198 }
199 }
200
201
202 assertEquals("lastEvaluation time is 0", 0, car.getOperationalPlan().getStartTime().getSI(), 0.00001);
203
204
205 assertEquals("nextEvaluation time is 10", 10.0, car.getOperationalPlan().getEndTime().getSI(), 0.00001);
206
207 double step = 0.01d;
208 for (int i = 0;; i++)
209 {
210 Time stepTime = new Time(i * step, TimeUnit.BASE_SECOND);
211 if (stepTime.getSI() > validFor.getSI())
212 {
213 break;
214 }
215 if (stepTime.getSI() > 0.5)
216 {
217 step = 0.1;
218 }
219
220 simulator.runUpTo(stepTime);
221 while (simulator.isStartingOrRunning())
222 {
223 try
224 {
225 Thread.sleep(1);
226 }
227 catch (InterruptedException ie)
228 {
229 ie = null;
230 }
231 }
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249 Speed longitudinalSpeed = car.getSpeed();
250 double expectedLongitudinalSpeed = initialSpeed.getSI() + stepTime.getSI() * acceleration.getSI();
251 assertEquals("longitudinal speed is " + expectedLongitudinalSpeed, expectedLongitudinalSpeed,
252 longitudinalSpeed.getSI(), 0.00001);
253 for (RelativePosition relativePosition : new RelativePosition[] {car.getFront(), car.getRear()})
254 {
255 Map<Lane, Double> positions = car.fractionalPositions(relativePosition);
256 assertEquals("Car should be in two lanes", 2, positions.size());
257 Double pos = positions.get(lanesGroupA[1]);
258
259 assertTrue("Car should be in lane 1 of lane group A", null != pos);
260 assertEquals("fractional position should be equal to result of fractionalPosition(lane, ...)", pos,
261 car.fractionalPosition(lanesGroupA[1], relativePosition), 0.0000001);
262 pos = positions.get(lanesGroupB[1]);
263 assertTrue("Car should be in lane 1 of lane group B", null != pos);
264 assertEquals("fractional position should be equal to result of fractionalPosition(lane, ...)", pos,
265 car.fractionalPosition(lanesGroupB[1], relativePosition), 0.0000001);
266 }
267 for (Lane[] laneGroup : new Lane[][] {lanesGroupA, lanesGroupB})
268 {
269 for (int laneIndex = 0; laneIndex < laneGroup.length; laneIndex++)
270 {
271 Lane lane = laneGroup[laneIndex];
272 boolean expectException = 1 != laneIndex;
273 for (RelativePosition relativePosition : new RelativePosition[] {car.getFront(), car.getReference(),
274 car.getRear()})
275 {
276
277
278 try
279 {
280 Length position = car.position(lane, relativePosition);
281 if (expectException)
282 {
283
284 fail("Calling position on lane that the car is NOT on should have thrown a "
285 + "NetworkException");
286 }
287 else
288 {
289 Length expectedPosition = laneGroup == lanesGroupA ? positionA : positionB;
290 expectedPosition = expectedPosition
291 .plus(new Length(stepTime.getSI() * initialSpeed.getSI(), LengthUnit.SI));
292 expectedPosition = expectedPosition.plus(new Length(
293 0.5 * acceleration.getSI() * stepTime.getSI() * stepTime.getSI(), LengthUnit.SI));
294 expectedPosition = expectedPosition.plus(relativePosition.getDx());
295
296
297 assertEquals("Position should match initial position", expectedPosition.getSI(),
298 position.getSI(), 0.0001);
299 }
300 }
301 catch (GtuException ne)
302 {
303 if (!expectException)
304 {
305 System.out.println(ne);
306 fail("Calling position on lane that the car is on should NOT have thrown a NetworkException");
307 }
308 }
309 try
310 {
311 double fractionalPosition = car.fractionalPosition(lane, relativePosition);
312 if (expectException)
313 {
314
315 fail("Calling position on lane that the car is NOT on should have thrown a NetworkException");
316 }
317 else
318 {
319 Length expectedPosition = laneGroup == lanesGroupA ? positionA : positionB;
320 expectedPosition = expectedPosition
321 .plus(new Length(stepTime.getSI() * initialSpeed.getSI(), LengthUnit.SI));
322 expectedPosition = expectedPosition.plus(new Length(
323 0.5 * acceleration.getSI() * stepTime.getSI() * stepTime.getSI(), LengthUnit.SI));
324 expectedPosition = expectedPosition.plus(relativePosition.getDx());
325
326
327 double expectedFractionalPosition = expectedPosition.getSI() / lane.getLength().getSI();
328 assertEquals("Position should match initial position", expectedFractionalPosition,
329 fractionalPosition, 0.000001);
330 }
331 }
332 catch (GtuException ne)
333 {
334 if (!expectException)
335 {
336 System.out.println(ne);
337 fail("Calling fractionalPosition on lane that the car is on should NOT have thrown a "
338 + "NetworkException");
339 }
340 }
341 }
342 }
343 }
344 }
345
346 Node nodeCFrom = new Node(network, "CFrom", new OtsPoint3d(10, 100, 0), Direction.ZERO);
347 Node nodeCTo = new Node(network, "CTo", new OtsPoint3d(1000, 0, 0), Direction.ZERO);
348 Lane[] lanesGroupC = LaneFactory.makeMultiLane(network, "C", nodeCFrom, nodeCTo, null, 3, laneType,
349 new Speed(100, KM_PER_HOUR), simulator, DefaultsNl.VEHICLE);
350 for (RelativePosition relativePosition : new RelativePosition[] {car.getFront(), car.getRear()})
351 {
352 Map<Lane, Double> positions = car.fractionalPositions(relativePosition);
353
354 Double pos = positions.get(lanesGroupA[1]);
355 assertTrue("Car should be in lane 1 of lane group A", null != pos);
356 assertEquals("fractional position should be equal to result of fractionalPosition(lane, ...)", pos,
357 car.fractionalPosition(lanesGroupA[1], relativePosition), 0.0000001);
358 pos = positions.get(lanesGroupB[1]);
359 assertTrue("Car should be in lane 1 of lane group B", null != pos);
360 assertEquals("fractional position should be equal to result of fractionalPosition(lane, ...)", pos,
361 car.fractionalPosition(lanesGroupB[1], relativePosition), 0.0000001);
362 pos = positions.get(lanesGroupC[0]);
363 }
364
365 for (RelativePosition relativePosition : new RelativePosition[] {car.getFront(), car.getRear()})
366 {
367 Map<Lane, Double> positions = car.fractionalPositions(relativePosition);
368 assertEquals("Car should be in two lanes", 2, positions.size());
369 Double pos = positions.get(lanesGroupB[1]);
370 assertTrue("Car should be in lane 1 of lane group B", null != pos);
371 assertEquals("fractional position should be equal to result of fractionalPosition(lane, ...)", pos,
372 car.fractionalPosition(lanesGroupB[1], relativePosition), 0.0000001);
373 pos = positions.get(lanesGroupC[0]);
374
375
376
377
378
379
380
381 }
382
383
384 }
385 }
386
387
388
389
390
391
392
393
394
395 class DummyModel extends AbstractOtsModel
396 {
397
398 private static final long serialVersionUID = 20150114L;
399
400
401
402
403 DummyModel(final OtsSimulatorInterface simulator)
404 {
405 super(simulator);
406 }
407
408
409 @Override
410 public final void constructModel() throws SimRuntimeException
411 {
412
413 }
414
415
416 @Override
417 public final RoadNetwork getNetwork()
418 {
419 return null;
420 }
421
422 }