1 package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2
3 import java.util.LinkedHashSet;
4
5 import org.djunits.value.vdouble.scalar.Length;
6 import org.djunits.value.vdouble.scalar.Speed;
7 import org.djunits.value.vdouble.scalar.Time;
8 import org.opentrafficsim.base.parameters.ParameterException;
9 import org.opentrafficsim.base.parameters.ParameterTypeClassList;
10 import org.opentrafficsim.base.parameters.ParameterTypes;
11 import org.opentrafficsim.base.parameters.Parameters;
12 import org.opentrafficsim.base.parameters.constraint.ClassCollectionConstraint;
13 import org.opentrafficsim.core.gtu.GTUException;
14 import org.opentrafficsim.core.gtu.perception.EgoPerception;
15 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan;
16 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
17 import org.opentrafficsim.core.network.NetworkException;
18 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
19 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
20 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
21 import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
22 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.DelayedNeighborsPerception;
23 import org.opentrafficsim.road.gtu.lane.plan.operational.LaneChange;
24 import org.opentrafficsim.road.gtu.lane.plan.operational.LaneOperationalPlanBuilder;
25 import org.opentrafficsim.road.gtu.lane.plan.operational.SimpleOperationalPlan;
26 import org.opentrafficsim.road.gtu.lane.tactical.AbstractLaneBasedTacticalPlanner;
27 import org.opentrafficsim.road.gtu.lane.tactical.Blockable;
28 import org.opentrafficsim.road.gtu.lane.tactical.DesireBased;
29 import org.opentrafficsim.road.gtu.lane.tactical.Synchronizable;
30 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
31 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
32 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
33 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance;
34 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Incentive;
35 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsData;
36 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
37 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsUtil;
38 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.MandatoryIncentive;
39 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
40 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
41 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
42 import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
43 import org.opentrafficsim.road.network.speed.SpeedLimitProspect;
44
45 import nl.tudelft.simulation.language.d3.DirectedPoint;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public class LMRS extends AbstractLaneBasedTacticalPlanner implements DesireBased, Synchronizable, Blockable
62 {
63
64
65 public static final ParameterTypeClassList<MandatoryIncentive> MANDATORY = new ParameterTypeClassList<>("man.incent.",
66 "Mandatory lane-change incentives.", ParameterTypeClassList.getValueClass(MandatoryIncentive.class));
67
68
69 public static final ParameterTypeClassList<VoluntaryIncentive> VOLUNTARY = new ParameterTypeClassList<>("vol.incent.",
70 "Voluntary lane-change incentives.", ParameterTypeClassList.getValueClass(VoluntaryIncentive.class));
71
72
73 public static final ParameterTypeClassList<AccelerationIncentive> ACCELERATION = new ParameterTypeClassList<>("acc.incent.",
74 "Acceleration incentives.", ParameterTypeClassList.getValueClass(AccelerationIncentive.class),
75 ClassCollectionConstraint.newInstance(AccelerationBusStop.class));
76
77
78 private static final long serialVersionUID = 20160300L;
79
80
81 private final LaneChange laneChange = new LaneChange();
82
83
84 private final LmrsData lmrsData;
85
86
87 private final LinkedHashSet<MandatoryIncentive> mandatoryIncentives = new LinkedHashSet<>();
88
89
90 private final LinkedHashSet<VoluntaryIncentive> voluntaryIncentives = new LinkedHashSet<>();
91
92
93 private final LinkedHashSet<AccelerationIncentive> accelerationIncentives = new LinkedHashSet<>();
94
95
96
97
98
99
100
101
102
103
104
105 public LMRS(final CarFollowingModel carFollowingModel, final LaneBasedGTU gtu, final LanePerception lanePerception,
106 final Synchronization synchronization, final Cooperation cooperation, final GapAcceptance gapAcceptance,
107 final Tailgating tailGating)
108 {
109 super(carFollowingModel, gtu, lanePerception);
110 this.lmrsData = new LmrsData(synchronization, cooperation, gapAcceptance, tailGating);
111 }
112
113
114
115
116
117 public final void addMandatoryIncentive(final MandatoryIncentive incentive)
118 {
119 if (incentive != null)
120 {
121 this.mandatoryIncentives.add(incentive);
122 }
123 }
124
125
126
127
128
129 public final void addVoluntaryIncentive(final VoluntaryIncentive incentive)
130 {
131 if (incentive != null)
132 {
133 this.voluntaryIncentives.add(incentive);
134 }
135 }
136
137
138
139
140
141 public final void addAccelerationIncentive(final AccelerationIncentive incentive)
142 {
143 if (incentive != null)
144 {
145 this.accelerationIncentives.add(incentive);
146 }
147 }
148
149
150
151
152 public final void setDefaultIncentives()
153 {
154 this.mandatoryIncentives.clear();
155 this.voluntaryIncentives.clear();
156 this.accelerationIncentives.clear();
157 this.mandatoryIncentives.add(new IncentiveRoute());
158
159 this.voluntaryIncentives.add(new IncentiveSpeedWithCourtesy());
160 this.voluntaryIncentives.add(new IncentiveKeep());
161 this.accelerationIncentives.add(new AccelerationSpeedLimitTransition());
162 this.accelerationIncentives.add(new AccelerationTrafficLights());
163 this.accelerationIncentives.add(new AccelerationConflicts());
164 }
165
166
167 @Override
168 public final OperationalPlan generateOperationalPlan(final Time startTime, final DirectedPoint locationAtStartTime)
169 throws OperationalPlanException, GTUException, NetworkException, ParameterException
170 {
171
172 getPerception().perceive();
173 SpeedLimitProspect slp = getPerception().getPerceptionCategory(InfrastructurePerception.class)
174 .getSpeedLimitProspect(RelativeLane.CURRENT);
175 SpeedLimitInfo sli = slp.getSpeedLimitInfo(Length.ZERO);
176 Parameters params = getGtu().getParameters();
177
178
179 SimpleOperationalPlan simplePlan = LmrsUtil.determinePlan(getGtu(), startTime, getCarFollowingModel(), this.laneChange,
180 this.lmrsData, getPerception(), this.mandatoryIncentives, this.voluntaryIncentives);
181
182
183 Speed speed = getPerception().getPerceptionCategory(EgoPerception.class).getSpeed();
184 RelativeLane[] lanes;
185 double dLeft = params.getParameterOrNull(LmrsParameters.DLEFT);
186 double dRight = params.getParameterOrNull(LmrsParameters.DRIGHT);
187 double dSync = params.getParameterOrNull(LmrsParameters.DSYNC);
188 if (this.laneChange.isChangingLane())
189 {
190 lanes = new RelativeLane[] { RelativeLane.CURRENT, this.laneChange.getSecondLane(getGtu()) };
191 }
192 else if (dLeft >= dSync && dLeft >= dRight)
193 {
194 lanes = new RelativeLane[] { RelativeLane.CURRENT, RelativeLane.LEFT };
195 }
196 else if (dRight >= dSync)
197 {
198 lanes = new RelativeLane[] { RelativeLane.CURRENT, RelativeLane.RIGHT };
199 }
200 else
201 {
202 lanes = new RelativeLane[] { RelativeLane.CURRENT };
203 }
204 for (AccelerationIncentive incentive : this.accelerationIncentives)
205 {
206 for (RelativeLane lane : lanes)
207 {
208 incentive.accelerate(simplePlan, lane, getGtu(), getPerception(), getCarFollowingModel(), speed, params, sli);
209 }
210 }
211
212 if (simplePlan.isLaneChange())
213 {
214 this.laneChange.setDesiredLaneChangeDuration(getGtu().getParameters().getParameter(ParameterTypes.LCDUR));
215
216
217 if (getPerception().contains(DelayedNeighborsPerception.class))
218 {
219 getPerception().getPerceptionCategory(DelayedNeighborsPerception.class)
220 .changeLane(simplePlan.getLaneChangeDirection());
221 }
222 }
223
224
225 simplePlan.setTurnIndicator(getGtu());
226
227
228 return LaneOperationalPlanBuilder.buildPlanFromSimplePlan(getGtu(), startTime, simplePlan, this.laneChange);
229
230 }
231
232
233 @Override
234 public final Desire getLatestDesire(final Class<? extends Incentive> incentiveClass)
235 {
236 return this.lmrsData.getLatestDesire(incentiveClass);
237 }
238
239
240 @Override
241 public Synchronizable.State getSynchronizationState()
242 {
243 return this.lmrsData.getSynchronizationState();
244 }
245
246
247 @Override
248 public boolean isBlocking()
249 {
250 for (AccelerationIncentive acc : this.accelerationIncentives)
251 {
252 if (acc instanceof AccelerationConflicts)
253 {
254 return ((AccelerationConflicts) acc).isBlocking();
255 }
256 }
257 return false;
258 }
259
260
261 @Override
262 public final String toString()
263 {
264 return "LMRS [mandatoryIncentives=" + this.mandatoryIncentives + ", voluntaryIncentives=" + this.voluntaryIncentives
265 + ", accelerationIncentives = " + this.accelerationIncentives + "]";
266 }
267
268 }