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