View Javadoc
1   package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2   
3   import java.util.LinkedHashSet;
4   
5   import nl.tudelft.simulation.language.d3.DirectedPoint;
6   
7   import org.djunits.value.vdouble.scalar.Length;
8   import org.djunits.value.vdouble.scalar.Speed;
9   import org.djunits.value.vdouble.scalar.Time;
10  import org.opentrafficsim.core.gtu.GTUException;
11  import org.opentrafficsim.core.gtu.behavioralcharacteristics.BehavioralCharacteristics;
12  import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterException;
13  import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterTypes;
14  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan;
15  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
16  import org.opentrafficsim.core.network.NetworkException;
17  import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
18  import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
19  import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
20  import org.opentrafficsim.road.gtu.lane.perception.categories.IntersectionPerception;
21  import org.opentrafficsim.road.gtu.lane.perception.categories.NeighborsPerception;
22  import org.opentrafficsim.road.gtu.lane.plan.operational.SimpleOperationalPlan;
23  import org.opentrafficsim.road.gtu.lane.plan.operational.LaneOperationalPlanBuilder.LaneChange;
24  import org.opentrafficsim.road.gtu.lane.tactical.AbstractLaneBasedTacticalPlanner;
25  import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
26  import org.opentrafficsim.road.gtu.lane.tactical.util.ConflictUtil;
27  import org.opentrafficsim.road.gtu.lane.tactical.util.ConflictUtil.ConflictPlans;
28  import org.opentrafficsim.road.gtu.lane.tactical.util.SpeedLimitUtil;
29  import org.opentrafficsim.road.gtu.lane.tactical.util.TrafficLightUtil;
30  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsUtil;
31  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.MandatoryIncentive;
32  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
33  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsUtil.LmrsStatus;
34  import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
35  import org.opentrafficsim.road.network.speed.SpeedLimitProspect;
36  
37  /**
38   * Implementation of the LMRS (Lane change Model with Relaxation and Synchronization). See Schakel, W.J., Knoop, V.L., and Van
39   * Arem, B. (2012), <a href="http://victorknoop.eu/research/papers/TRB2012_LMRS_reviewed.pdf">LMRS: Integrated Lane Change Model
40   * with Relaxation and Synchronization</a>, Transportation Research Records: Journal of the Transportation Research Board, No.
41   * 2316, pp. 47-57. Note in the official versions of TRB and TRR some errors appeared due to the typesetting of the papers (not
42   * in the preprint provided here). A list of errata for the official versions is found
43   * <a href="http://victorknoop.eu/research/papers/Erratum_LMRS.pdf">here</a>.
44   * <p>
45   * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
46   * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
47   * <p>
48   * @version $Revision$, $LastChangedDate$, by $Author$, initial version Apr 13, 2016 <br>
49   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
50   */
51  public class LMRS extends AbstractLaneBasedTacticalPlanner
52  {
53  
54      /** Serialization id. */
55      private static final long serialVersionUID = 20160300L;
56  
57      /** Set of yield plans at conflicts with priority. Remembering for static model. */
58      private final ConflictPlans yieldPlans = new ConflictPlans();
59  
60      /** Lane change status. */
61      private final LaneChange laneChange = new LaneChange();
62  
63      /** LMRS status. */
64      private final LmrsStatus lmrsStatus = new LmrsStatus();
65  
66      /** Set of mandatory lane change incentives. */
67      private final LinkedHashSet<MandatoryIncentive> mandatoryIncentives = new LinkedHashSet<>();
68  
69      /** Set of voluntary lane change incentives. */
70      private final LinkedHashSet<VoluntaryIncentive> voluntaryIncentives = new LinkedHashSet<>();
71  
72      /**
73       * Constructor setting the car-following model.
74       * @param carFollowingModel Car-following model.
75       * @param gtu GTU
76       */
77      public LMRS(final CarFollowingModel carFollowingModel, final LaneBasedGTU gtu)
78      {
79          super(carFollowingModel, gtu);
80      }
81  
82      /**
83       * Adds a mandatory incentive. Ignores <tt>null</tt>.
84       * @param incentive Incentive to add.
85       */
86      public final void addMandatoryIncentive(final MandatoryIncentive incentive)
87      {
88          if (incentive != null)
89          {
90              this.mandatoryIncentives.add(incentive);
91          }
92      }
93  
94      /**
95       * Adds a voluntary incentive. Ignores <tt>null</tt>.
96       * @param incentive Incentive to add.
97       */
98      public final void addVoluntaryIncentive(final VoluntaryIncentive incentive)
99      {
100         if (incentive != null)
101         {
102             this.voluntaryIncentives.add(incentive);
103         }
104     }
105 
106     /**
107      * Sets the default lane change incentives.
108      */
109     public final void setDefaultIncentives()
110     {
111         this.mandatoryIncentives.clear();
112         this.voluntaryIncentives.clear();
113         this.mandatoryIncentives.add(new IncentiveRoute());
114         this.voluntaryIncentives.add(new IncentiveSpeedWithCourtesy());
115         this.voluntaryIncentives.add(new IncentiveKeep());
116     }
117 
118     /** {@inheritDoc} */
119     @Override
120     public final OperationalPlan generateOperationalPlan(final Time startTime, final DirectedPoint locationAtStartTime)
121             throws OperationalPlanException, GTUException, NetworkException, ParameterException
122     {
123         // obtain objects to get info
124         getPerception().perceive();
125         SpeedLimitProspect slp = getPerception().getPerceptionCategory(InfrastructurePerception.class)
126                 .getSpeedLimitProspect(RelativeLane.CURRENT);
127         SpeedLimitInfo sli = slp.getSpeedLimitInfo(Length.ZERO);
128         BehavioralCharacteristics bc = getGtu().getBehavioralCharacteristics();
129 
130         // LMRS
131         SimpleOperationalPlan simplePlan = LmrsUtil.determinePlan(getGtu(), startTime, this.lmrsStatus, getCarFollowingModel(),
132                 this.laneChange, getPerception(), this.mandatoryIncentives, this.voluntaryIncentives);
133 
134         // speed limits
135         Speed speed = getGtu().getSpeed();
136         simplePlan.minimumAcceleration(SpeedLimitUtil.considerSpeedLimitTransitions(bc, speed, slp, getCarFollowingModel()));
137 
138         // traffic lights
139         // TODO traffic lights on route, possible on different lane (and possibly close)
140         simplePlan.minimumAcceleration(TrafficLightUtil.respondToTrafficLights(bc,
141                 getPerception().getPerceptionCategory(IntersectionPerception.class).getTrafficLights(RelativeLane.CURRENT),
142                 getCarFollowingModel(), speed, sli));
143 
144         // conflicts
145         simplePlan.minimumAcceleration(ConflictUtil.approachConflicts(bc,
146                 getPerception().getPerceptionCategory(IntersectionPerception.class).getConflicts(RelativeLane.CURRENT),
147                 getPerception().getPerceptionCategory(NeighborsPerception.class).getLeaders(RelativeLane.CURRENT),
148                 getCarFollowingModel(), getGtu().getLength(), speed, sli, this.yieldPlans));
149 
150         // create plan
151         return buildPlanFromSimplePlan(getGtu(), startTime, bc, simplePlan, this.laneChange);
152 
153     }
154 
155     /** {@inheritDoc} */
156     @Override
157     public final String toString()
158     {
159         String mandatory;
160         mandatory = "mandatoryIncentives=" + this.mandatoryIncentives + ", ";
161         String voluntary;
162         if (!this.voluntaryIncentives.isEmpty())
163         {
164             voluntary = "voluntaryIncentives=" + this.voluntaryIncentives;
165         }
166         else
167         {
168             voluntary = "voluntaryIncentives=[]";
169         }
170         return "LMRS [" + mandatory + voluntary + "]";
171     }
172 
173 }