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