View Javadoc
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   * Implementation of the LMRS (Lane change Model with Relaxation and Synchronization). See Schakel, W.J., Knoop, V.L., and Van
48   * Arem, B. (2012), <a href="http://victorknoop.eu/research/papers/TRB2012_LMRS_reviewed.pdf">LMRS: Integrated Lane Change Model
49   * with Relaxation and Synchronization</a>, Transportation Research Records: Journal of the Transportation Research Board, No.
50   * 2316, pp. 47-57. Note in the official versions of TRB and TRR some errors appeared due to the typesetting of the papers (not
51   * in the preprint provided here). A list of errata for the official versions is found
52   * <a href="http://victorknoop.eu/research/papers/Erratum_LMRS.pdf">here</a>.
53   * <p>
54   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
55   * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
56   * <p>
57   * @version $Revision$, $LastChangedDate$, by $Author$, initial version Apr 13, 2016 <br>
58   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
59   */
60  public class LMRS extends AbstractLaneBasedTacticalPlanner implements DesireBased, Synchronizable, Blockable
61  {
62  
63      /** Parameter type for mandatory lane change incentives. */
64      public static final ParameterTypeClassList<MandatoryIncentive> MANDATORY = new ParameterTypeClassList<>("man.incent.",
65              "Mandatory lane-change incentives.", ParameterTypeClassList.getValueClass(MandatoryIncentive.class));
66  
67      /** Parameter type for voluntary lane change incentives. */
68      public static final ParameterTypeClassList<VoluntaryIncentive> VOLUNTARY = new ParameterTypeClassList<>("vol.incent.",
69              "Voluntary lane-change incentives.", ParameterTypeClassList.getValueClass(VoluntaryIncentive.class));
70  
71      /** Parameter type for acceleration incentives. */
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      /** Serialization id. */
77      private static final long serialVersionUID = 20160300L;
78  
79      /** Lane change status. */
80      private final LaneChange laneChange = new LaneChange();
81  
82      /** LMRS data. */
83      private final LmrsData lmrsData;
84  
85      /** Set of mandatory lane change incentives. */
86      private final LinkedHashSet<MandatoryIncentive> mandatoryIncentives = new LinkedHashSet<>();
87  
88      /** Set of voluntary lane change incentives. */
89      private final LinkedHashSet<VoluntaryIncentive> voluntaryIncentives = new LinkedHashSet<>();
90  
91      /** Set of acceleration incentives. */
92      private final LinkedHashSet<AccelerationIncentive> accelerationIncentives = new LinkedHashSet<>();
93  
94      /**
95       * Constructor setting the car-following model.
96       * @param carFollowingModel CarFollowingModel; Car-following model.
97       * @param gtu LaneBasedGTU; GTU
98       * @param lanePerception LanePerception; perception
99       * @param synchronization Synchronization; type of synchronization
100      * @param cooperation Cooperation; type of cooperation
101      * @param gapAcceptance GapAcceptance; gap-acceptance
102      * @param tailgating Tailgating; tail gating
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      * Adds a mandatory incentive. Ignores {@code null}.
114      * @param incentive MandatoryIncentive; Incentive to add.
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      * Adds a voluntary incentive. Ignores {@code null}.
126      * @param incentive VoluntaryIncentive; Incentive to add.
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      * Adds an acceleration incentive. Ignores {@code null}.
138      * @param incentive AccelerationIncentive; Incentive to add.
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      * Sets the default lane change incentives.
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         // this.mandatoryIncentives.add(new IncentiveGetInLane());
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     /** {@inheritDoc} */
166     @Override
167     public final OperationalPlan generateOperationalPlan(final Time startTime, final DirectedPoint locationAtStartTime)
168             throws OperationalPlanException, GTUException, NetworkException, ParameterException
169     {
170         // obtain objects to get info
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         // LMRS
177         SimpleOperationalPlan simplePlan = LmrsUtil.determinePlan(getGtu(), startTime, getCarFollowingModel(), this.laneChange,
178                 this.lmrsData, getPerception(), this.mandatoryIncentives, this.voluntaryIncentives);
179 
180         // Lower acceleration from additional sources, consider adjacent lane when changing lane or synchronizing
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             // adjust lane based data in perception
214         }
215 
216         // set turn indicator
217         simplePlan.setTurnIndicator(getGtu());
218 
219         // create plan
220         return LaneOperationalPlanBuilder.buildPlanFromSimplePlan(getGtu(), startTime, simplePlan, this.laneChange);
221 
222     }
223 
224     /** {@inheritDoc} */
225     @Override
226     public final Desire getLatestDesire(final Class<? extends Incentive> incentiveClass)
227     {
228         return this.lmrsData.getLatestDesire(incentiveClass);
229     }
230 
231     /** {@inheritDoc} */
232     @Override
233     public Synchronizable.State getSynchronizationState()
234     {
235         return this.lmrsData.getSynchronizationState();
236     }
237 
238     /** {@inheritDoc} */
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     /** {@inheritDoc} */
253     @Override
254     public final String toString()
255     {
256         return "LMRS [mandatoryIncentives=" + this.mandatoryIncentives + ", voluntaryIncentives=" + this.voluntaryIncentives
257                 + ", accelerationIncentives = " + this.accelerationIncentives + "]";
258     }
259 
260 }