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.animation.Blockable;
19 import org.opentrafficsim.road.gtu.animation.DesireBased;
20 import org.opentrafficsim.road.gtu.animation.Synchronizable;
21 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
22 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
23 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
24 import org.opentrafficsim.road.gtu.lane.perception.categories.DelayedNeighborsPerception;
25 import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
26 import org.opentrafficsim.road.gtu.lane.plan.operational.LaneChange;
27 import org.opentrafficsim.road.gtu.lane.plan.operational.LaneOperationalPlanBuilder;
28 import org.opentrafficsim.road.gtu.lane.plan.operational.SimpleOperationalPlan;
29 import org.opentrafficsim.road.gtu.lane.tactical.AbstractLaneBasedTacticalPlanner;
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
173 getPerception().perceive();
174 SpeedLimitProspect slp = getPerception().getPerceptionCategory(InfrastructurePerception.class)
175 .getSpeedLimitProspect(RelativeLane.CURRENT);
176 SpeedLimitInfo sli = slp.getSpeedLimitInfo(Length.ZERO);
177 Parameters params = getGtu().getParameters();
178
179
180 SimpleOperationalPlan simplePlan = LmrsUtil.determinePlan(getGtu(), startTime, getCarFollowingModel(), this.laneChange,
181 this.lmrsData, getPerception(), this.mandatoryIncentives, this.voluntaryIncentives);
182
183
184 Speed speed = getPerception().getPerceptionCategory(EgoPerception.class).getSpeed();
185 RelativeLane[] lanes;
186 double dLeft = params.getParameterOrNull(LmrsParameters.DLEFT);
187 double dRight = params.getParameterOrNull(LmrsParameters.DRIGHT);
188 double dSync = params.getParameterOrNull(LmrsParameters.DSYNC);
189 if (this.laneChange.isChangingLane())
190 {
191 lanes = new RelativeLane[] { RelativeLane.CURRENT, this.laneChange.getSecondLane(getGtu()) };
192 }
193 else if (dLeft >= dSync && dLeft >= dRight)
194 {
195 lanes = new RelativeLane[] { RelativeLane.CURRENT, RelativeLane.LEFT };
196 }
197 else if (dRight >= dSync)
198 {
199 lanes = new RelativeLane[] { RelativeLane.CURRENT, RelativeLane.RIGHT };
200 }
201 else
202 {
203 lanes = new RelativeLane[] { RelativeLane.CURRENT };
204 }
205 for (AccelerationIncentive incentive : this.accelerationIncentives)
206 {
207 for (RelativeLane lane : lanes)
208 {
209 incentive.accelerate(simplePlan, lane, getGtu(), getPerception(), getCarFollowingModel(), speed, params, sli);
210 }
211 }
212
213 if (simplePlan.isLaneChange())
214 {
215 this.laneChange.setDesiredLaneChangeDuration(getGtu().getParameters().getParameter(ParameterTypes.LCDUR));
216
217
218 if (getPerception().contains(DelayedNeighborsPerception.class))
219 {
220 getPerception().getPerceptionCategory(DelayedNeighborsPerception.class)
221 .changeLane(simplePlan.getLaneChangeDirection());
222 }
223 }
224
225
226 simplePlan.setTurnIndicator(getGtu());
227
228
229 return LaneOperationalPlanBuilder.buildPlanFromSimplePlan(getGtu(), startTime, simplePlan, this.laneChange);
230
231 }
232
233
234 @Override
235 public final Desire getLatestDesire(final Class<? extends Incentive> incentiveClass)
236 {
237 return this.lmrsData.getLatestDesire(incentiveClass);
238 }
239
240
241 @Override
242 public State getSynchronizationState()
243 {
244 return this.lmrsData.getSynchronizationState();
245 }
246
247
248 @Override
249 public boolean isBlocking()
250 {
251 for (AccelerationIncentive acc : this.accelerationIncentives)
252 {
253 if (acc instanceof AccelerationConflicts)
254 {
255 return ((AccelerationConflicts) acc).isBlocking();
256 }
257 }
258 return false;
259 }
260
261
262 @Override
263 public final String toString()
264 {
265 return "LMRS [mandatoryIncentives=" + this.mandatoryIncentives + ", voluntaryIncentives=" + this.voluntaryIncentives
266 + ", accelerationIncentives = " + this.accelerationIncentives + "]";
267 }
268
269 }