1 package org.opentrafficsim.road.gtu;
2
3 import static org.junit.jupiter.api.Assertions.assertEquals;
4 import static org.junit.jupiter.api.Assertions.assertTrue;
5
6 import java.util.ArrayList;
7 import java.util.LinkedHashSet;
8 import java.util.List;
9 import java.util.Set;
10
11 import org.djunits.unit.DurationUnit;
12 import org.djunits.unit.LengthUnit;
13 import org.djunits.unit.util.UNITS;
14 import org.djunits.value.vdouble.scalar.Acceleration;
15 import org.djunits.value.vdouble.scalar.Direction;
16 import org.djunits.value.vdouble.scalar.Duration;
17 import org.djunits.value.vdouble.scalar.Length;
18 import org.djunits.value.vdouble.scalar.Speed;
19 import org.djunits.value.vdouble.scalar.Time;
20 import org.djutils.draw.point.Point2d;
21 import org.junit.jupiter.api.Test;
22 import org.opentrafficsim.base.parameters.Parameters;
23 import org.opentrafficsim.core.definitions.DefaultsNl;
24 import org.opentrafficsim.core.dsol.AbstractOtsModel;
25 import org.opentrafficsim.core.dsol.OtsModelInterface;
26 import org.opentrafficsim.core.dsol.OtsSimulator;
27 import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
28 import org.opentrafficsim.core.gtu.GtuType;
29 import org.opentrafficsim.core.gtu.RelativePosition;
30 import org.opentrafficsim.core.network.Node;
31 import org.opentrafficsim.core.network.route.Route;
32 import org.opentrafficsim.core.perception.HistoryManagerDevs;
33 import org.opentrafficsim.road.DefaultTestParameters;
34 import org.opentrafficsim.road.FixedCarFollowing;
35 import org.opentrafficsim.road.definitions.DefaultsRoadNl;
36 import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
37 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.Lmrs;
38 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LmrsFactory;
39 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LmrsFactory.Setting;
40 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
41 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalRoutePlanner;
42 import org.opentrafficsim.road.network.RoadNetwork;
43 import org.opentrafficsim.road.network.factory.LaneFactory;
44 import org.opentrafficsim.road.network.lane.Lane;
45 import org.opentrafficsim.road.network.lane.LanePosition;
46 import org.opentrafficsim.road.network.lane.LaneType;
47
48 import nl.tudelft.simulation.dsol.SimRuntimeException;
49
50
51
52
53
54
55
56
57
58
59
60 public final class AbstractLaneBasedGtuTest implements UNITS
61 {
62
63
64 private AbstractLaneBasedGtuTest()
65 {
66
67 }
68
69
70
71
72
73 @Test
74 public void abstractLaneBasedGtuTest() throws Exception
75 {
76
77
78
79
80 OtsSimulatorInterface simulator = new OtsSimulator("abstractLaneBasedGtuTest");
81 RoadNetwork network = new RoadNetwork("lane base gtu test network", simulator);
82 OtsModelInterface model = new DummyModel(simulator);
83 simulator.initialize(Time.ZERO, Duration.ZERO, new Duration(1, DurationUnit.HOUR), model,
84 HistoryManagerDevs.noHistory(simulator));
85 Node nodeAFrom = new Node(network, "AFrom", new Point2d(0, 0), Direction.ZERO);
86 Node nodeATo = new Node(network, "ATo", new Point2d(1000, 0), Direction.ZERO);
87 GtuType gtuType = DefaultsNl.CAR;
88 LaneType laneType = DefaultsRoadNl.TWO_WAY_LANE;
89
90 Lane[] lanesGroupA = LaneFactory.makeMultiLane(network, "A", nodeAFrom, nodeATo, null, 3, laneType,
91 new Speed(100, KM_PER_HOUR), simulator, DefaultsNl.VEHICLE);
92
93
94
95
96
97 Set<LanePosition> initialLongitudinalPositions = new LinkedHashSet<>(2);
98
99 Length positionA = new Length(100, METER);
100 initialLongitudinalPositions.add(new LanePosition(lanesGroupA[1], positionA));
101
102
103
104 Acceleration acceleration = new Acceleration(2, METER_PER_SECOND_2);
105 Duration validFor = new Duration(0.5, SECOND);
106
107
108
109 Speed initialSpeed = new Speed(50, KM_PER_HOUR);
110
111 Length carLength = new Length(4, METER);
112
113 Length carWidth = new Length(1.8, METER);
114
115 Speed maximumSpeed = new Speed(200, KM_PER_HOUR);
116
117 String carID = "theCar";
118
119 List<Node> nodeList = new ArrayList<Node>();
120 nodeList.add(nodeAFrom);
121 nodeList.add(nodeATo);
122
123 Route route = new Route("Route", gtuType, nodeList);
124
125 Parameters parameters = DefaultTestParameters.create();
126
127
128
129 LaneBasedGtu car = new LaneBasedGtu(carID, gtuType, carLength, carWidth, maximumSpeed, carLength.times(0.5), network);
130 LaneBasedStrategicalPlanner strategicalPlanner = new LaneBasedStrategicalRoutePlanner(
131 new LmrsFactory<>(Lmrs::new)
132 .set(Setting.CAR_FOLLOWING_MODEL, (h, v) -> new FixedCarFollowing(acceleration).get()).create(car),
133 car);
134 car.setParameters(parameters);
135 car.init(strategicalPlanner, new LanePosition(lanesGroupA[1], positionA).getLocation(), initialSpeed);
136
137 assertEquals(carID, car.getId(), "ID of the car should be identical to the provided one");
138
139
140
141 assertEquals(carWidth, car.getWidth(), "Width should be identical to the provided width");
142 assertEquals(carLength, car.getLength(), "Length should be identical to the provided length");
143 assertEquals(gtuType, car.getType(), "GTU type should be identical to the provided one");
144 assertEquals(positionA.getSI(), car.getPosition(lanesGroupA[1], car.getReference()).getSI(), 0.0001,
145 "front in lanesGroupA[1] is positionA");
146
147
148 assertEquals(2.0, car.getAcceleration().getSI(), 0.00001, "acceleration is 2");
149 assertEquals(initialSpeed.getSI(), car.getSpeed().getSI(), 0.00001, "longitudinal speed is " + initialSpeed);
150 assertEquals(0, car.getOperationalPlan().getStartTime().getSI(), 0.00001, "lastEvaluation time is 0");
151
152
153
154
155
156
157
158
159
160
161
162 for (Lane[] laneGroup : new Lane[][] {lanesGroupA})
163 {
164 for (int laneIndex = 0; laneIndex < laneGroup.length; laneIndex++)
165 {
166 Lane lane = laneGroup[laneIndex];
167 for (RelativePosition relativePosition : new RelativePosition[] {car.getFront(), car.getReference(),
168 car.getRear()})
169 {
170
171
172 Length position = car.getPosition(lane, relativePosition);
173 Length expectedPosition = positionA;
174 expectedPosition = expectedPosition.plus(relativePosition.dx());
175
176
177 assertEquals(expectedPosition.getSI(), position.getSI(), 0.0001, "Position should match initial position");
178 }
179 }
180 }
181
182
183 assertEquals(0, car.getOperationalPlan().getStartTime().getSI(), 0.00001, "lastEvaluation time is 0");
184
185
186 assertEquals(0.5, car.getOperationalPlan().getEndTime().getSI(), 0.00001, "nextEvaluation time is 10");
187
188 double step = 0.01d;
189 for (int i = 0;; i++)
190 {
191 Duration stepTime = Duration.ofSI(i * step);
192 if (stepTime.getSI() > validFor.getSI())
193 {
194 break;
195 }
196 if (stepTime.getSI() > 0.5)
197 {
198 step = 0.1;
199 }
200
201 simulator.runUpTo(stepTime);
202 while (simulator.isStartingOrRunning())
203 {
204 try
205 {
206 Thread.sleep(1);
207 }
208 catch (InterruptedException ie)
209 {
210 ie = null;
211 }
212 }
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230 Speed longitudinalSpeed = car.getSpeed();
231 double expectedLongitudinalSpeed = initialSpeed.getSI() + stepTime.getSI() * acceleration.getSI();
232 assertEquals(expectedLongitudinalSpeed, longitudinalSpeed.getSI(), 0.00001,
233 "longitudinal speed is " + expectedLongitudinalSpeed);
234 for (RelativePosition relativePosition : new RelativePosition[] {car.getFront(), car.getRear()})
235 {
236 LanePosition pos = car.getPosition();
237
238 assertTrue(null != pos, "Car should be in lane 1 of lane group A");
239 assertEquals(pos.getFraction() + relativePosition.dx().si / lanesGroupA[1].getLength().si,
240 car.getPosition(lanesGroupA[1], relativePosition).si / lanesGroupA[1].getLength().si, 0.0000001,
241 "fractional position should be equal to result of fractionalPosition(lane, ...)");
242 }
243 for (Lane[] laneGroup : new Lane[][] {lanesGroupA})
244 {
245 for (int laneIndex = 0; laneIndex < laneGroup.length; laneIndex++)
246 {
247 Lane lane = laneGroup[laneIndex];
248 for (RelativePosition relativePosition : new RelativePosition[] {car.getFront(), car.getReference(),
249 car.getRear()})
250 {
251
252
253 Length position = car.getPosition(lane, relativePosition);
254 Length expectedPosition = positionA;
255 expectedPosition =
256 expectedPosition.plus(new Length(stepTime.getSI() * initialSpeed.getSI(), LengthUnit.SI));
257 expectedPosition = expectedPosition.plus(
258 new Length(0.5 * acceleration.getSI() * stepTime.getSI() * stepTime.getSI(), LengthUnit.SI));
259 expectedPosition = expectedPosition.plus(relativePosition.dx());
260
261
262 assertEquals(expectedPosition.getSI(), position.getSI(), 0.01,
263 "Position should match initial position");
264 double fractionalPosition = car.getPosition(lane, relativePosition).si / lane.getLength().si;
265 expectedPosition = positionA;
266 expectedPosition =
267 expectedPosition.plus(new Length(stepTime.getSI() * initialSpeed.getSI(), LengthUnit.SI));
268 expectedPosition = expectedPosition.plus(
269 new Length(0.5 * acceleration.getSI() * stepTime.getSI() * stepTime.getSI(), LengthUnit.SI));
270 expectedPosition = expectedPosition.plus(relativePosition.dx());
271
272
273 double expectedFractionalPosition = expectedPosition.getSI() / lane.getLength().getSI();
274 assertEquals(expectedFractionalPosition, fractionalPosition, 0.01,
275 "Position should match initial position");
276 }
277 }
278 }
279 }
280
281 Node nodeCFrom = new Node(network, "CFrom", new Point2d(10, 100), Direction.ZERO);
282 Node nodeCTo = new Node(network, "CTo", new Point2d(1000, 0), Direction.ZERO);
283 Lane[] lanesGroupC = LaneFactory.makeMultiLane(network, "C", nodeCFrom, nodeCTo, null, 3, laneType,
284 new Speed(100, KM_PER_HOUR), simulator, DefaultsNl.VEHICLE);
285 for (RelativePosition relativePosition : new RelativePosition[] {car.getFront(), car.getRear()})
286 {
287 LanePosition pos = car.getPosition();
288 assertTrue(null != pos, "Car should be in lane 1 of lane group A");
289 assertEquals(pos.getFraction() + relativePosition.dx().si / lanesGroupA[1].getLength().si,
290 car.getPosition(lanesGroupA[1], relativePosition).si / lanesGroupA[1].getLength().si, 0.0000001,
291 "fractional position should be equal to result of fractionalPosition(lane, ...)");
292 }
293
294
295 }
296 }
297
298
299
300
301
302
303
304
305
306 class DummyModel extends AbstractOtsModel
307 {
308
309
310
311
312 DummyModel(final OtsSimulatorInterface simulator)
313 {
314 super(simulator);
315 }
316
317 @Override
318 public final void constructModel() throws SimRuntimeException
319 {
320
321 }
322
323 @Override
324 public final RoadNetwork getNetwork()
325 {
326 return null;
327 }
328
329 }