1 package org.opentrafficsim.road.gtu.generator;
2
3 import java.util.Set;
4 import java.util.SortedSet;
5
6 import org.djunits.value.vdouble.scalar.Duration;
7 import org.djunits.value.vdouble.scalar.Length;
8 import org.djunits.value.vdouble.scalar.Speed;
9 import org.djutils.exceptions.Throw;
10 import org.opentrafficsim.core.gtu.GtuException;
11 import org.opentrafficsim.core.network.NetworkException;
12 import org.opentrafficsim.road.gtu.generator.LaneBasedGtuGenerator.Placement;
13 import org.opentrafficsim.road.gtu.generator.LaneBasedGtuGenerator.RoomChecker;
14 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedGtuCharacteristics;
15 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGtu;
16 import org.opentrafficsim.road.network.lane.Lane;
17 import org.opentrafficsim.road.network.lane.LanePosition;
18
19
20
21
22
23
24
25
26
27
28
29
30
31 public class CfRoomChecker implements RoomChecker
32 {
33
34
35 @Override
36 public Placement canPlace(final SortedSet<HeadwayGtu> leaders, final LaneBasedGtuCharacteristics characteristics,
37 final Duration since, final LanePosition initialPosition) throws NetworkException, GtuException
38 {
39 Speed speedLimit = initialPosition.lane().getSpeedLimit(characteristics.getGtuType());
40 Throw.when(speedLimit == null, IllegalStateException.class, "No speed limit could be determined for GtuType %s.",
41 characteristics.getGtuType());
42 Speed desiredSpeed = characteristics.getStrategicalPlannerFactory().peekDesiredSpeed(characteristics.getGtuType(),
43 speedLimit, characteristics.getMaximumSpeed());
44 desiredSpeed = desiredSpeed != null ? desiredSpeed : speedLimit;
45 if (leaders.isEmpty())
46 {
47
48 return new Placement(desiredSpeed, initialPosition);
49 }
50 Length desiredHeadway =
51 characteristics.getStrategicalPlannerFactory().peekDesiredHeadway(characteristics.getGtuType(), desiredSpeed);
52 desiredHeadway = desiredHeadway != null ? desiredHeadway : desiredSpeed.times(Duration.instantiateSI(1.0));
53
54 Length move = Length.POSITIVE_INFINITY;
55 Speed generationSpeed = desiredSpeed;
56 for (HeadwayGtu leader : leaders)
57 {
58 Speed speed = Speed.min(desiredSpeed, leader.getSpeed());
59 Length headway =
60 characteristics.getStrategicalPlannerFactory().peekDesiredHeadway(characteristics.getGtuType(), speed);
61 headway = headway != null ? headway : speed.times(Duration.instantiateSI(1.0));
62 double f = this.headwayFactor(desiredSpeed, desiredHeadway, speed, headway, leader.getLength());
63 headway = headway.times(f);
64 if (leader.getDistance().lt(headway))
65 {
66
67 return Placement.NO;
68 }
69 Length moveToLeader = leader.getDistance().minus(headway);
70 if (moveToLeader.lt(move))
71 {
72 move = moveToLeader;
73 generationSpeed = speed;
74 }
75 }
76 move = Length.min(move, since.times(generationSpeed));
77
78 LanePosition generationPosition;
79 if (move.eq0())
80 {
81 generationPosition = initialPosition;
82 }
83 else
84 {
85 Lane lane = initialPosition.lane();
86 Length position = initialPosition.position();
87 Length canMove = lane.getLength().minus(position);
88 while (canMove.lt(move))
89 {
90 Set<Lane> down = lane.nextLanes(characteristics.getGtuType());
91 if (down.size() != 1)
92 {
93
94 return new Placement(generationSpeed, initialPosition);
95 }
96 else
97 {
98 move = move.minus(canMove);
99 lane = down.iterator().next();
100 position = Length.ZERO;
101 canMove = lane.getLength();
102 }
103 }
104 position = position.plus(move);
105 generationPosition = new LanePosition(lane, position);
106 }
107 return new Placement(generationSpeed, generationPosition);
108 }
109
110
111
112
113
114
115
116
117
118
119 protected double headwayFactor(final Speed desiredSpeed, final Length desiredHeadway, final Speed generationSpeed,
120 final Length generationHeadway, final Length leaderLength)
121 {
122 return 1.0;
123 }
124
125 }