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