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.Break;
19  import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
20  import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
21  import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
22  import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
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         Break.on(getGtu(), "WWP.LANE:4", 41, true);
172         
173         
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 
219         
220         simplePlan.setTurnIndicator(getGtu());
221 
222         
223         return LaneOperationalPlanBuilder.buildPlanFromSimplePlan(getGtu(), startTime, simplePlan, this.laneChange);
224 
225     }
226 
227     
228     @Override
229     public final Desire getLatestDesire(final Class<? extends Incentive> incentiveClass)
230     {
231         return this.lmrsData.getLatestDesire(incentiveClass);
232     }
233 
234     
235     @Override
236     public Synchronizable.State getSynchronizationState()
237     {
238         return this.lmrsData.getSynchronizationState();
239     }
240 
241     
242     @Override
243     public boolean isBlocking()
244     {
245         for (AccelerationIncentive acc : this.accelerationIncentives)
246         {
247             if (acc instanceof AccelerationConflicts)
248             {
249                 return ((AccelerationConflicts) acc).isBlocking();
250             }
251         }
252         return false;
253     }
254 
255     
256     @Override
257     public final String toString()
258     {
259         return "LMRS [mandatoryIncentives=" + this.mandatoryIncentives + ", voluntaryIncentives=" + this.voluntaryIncentives
260                 + ", accelerationIncentives = " + this.accelerationIncentives + "]";
261     }
262 
263 }