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