View Javadoc
1   package org.opentrafficsim.road.gtu.lane.tactical;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import nl.tudelft.simulation.language.d3.DirectedPoint;
7   
8   import org.djunits.unit.TimeUnit;
9   import org.djunits.value.vdouble.scalar.Duration;
10  import org.djunits.value.vdouble.scalar.Length;
11  import org.djunits.value.vdouble.scalar.Time;
12  import org.opentrafficsim.core.gtu.GTUException;
13  import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterException;
14  import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterTypes;
15  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan;
16  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan.Segment;
17  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
18  import org.opentrafficsim.core.network.NetworkException;
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.categories.DefaultSimplePerception;
22  import org.opentrafficsim.road.gtu.lane.perception.headway.Headway;
23  import org.opentrafficsim.road.gtu.lane.tactical.following.AccelerationStep;
24  import org.opentrafficsim.road.gtu.lane.tactical.following.GTUFollowingModelOld;
25  
26  /**
27   * Lane-based tactical planner that implements car following behavior. This tactical planner retrieves the car following model
28   * from the strategical planner and will generate an operational plan for the GTU.
29   * <p>
30   * This lane-based tactical planner makes decisions based on headway (GTU following model). It can ask the strategic planner for
31   * assistance on the route to take when the network splits.
32   * <p>
33   * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
34   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
35   * </p>
36   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
37   * initial version Nov 25, 2015 <br>
38   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
39   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
40   */
41  public class LaneBasedGTUFollowingTacticalPlanner extends AbstractLaneBasedTacticalPlanner
42  {
43      /** */
44      private static final long serialVersionUID = 20151125L;
45  
46      /**
47       * Instantiate a tactical planner with just GTU following behavior and no lane changes.
48       * @param carFollowingModel Car-following model.
49       * @param gtu GTU
50       */
51      public LaneBasedGTUFollowingTacticalPlanner(final GTUFollowingModelOld carFollowingModel, final LaneBasedGTU gtu)
52      {
53          super(carFollowingModel, gtu);
54      }
55  
56      /** {@inheritDoc} */
57      @Override
58      public OperationalPlan generateOperationalPlan(final Time startTime, final DirectedPoint locationAtStartTime)
59          throws OperationalPlanException, NetworkException, GTUException, ParameterException
60      {
61          // ask Perception for the local situation
62          LaneBasedGTU laneBasedGTU = getGtu();
63          LanePerception perception = getPerception();
64  
65          // if the GTU's maximum speed is zero (block), generate a stand still plan for one second
66          if (laneBasedGTU.getMaximumSpeed().si < OperationalPlan.DRIFTING_SPEED_SI)
67          {
68              return new OperationalPlan(getGtu(), locationAtStartTime, startTime, new Duration(1.0, TimeUnit.SECOND));
69          }
70  
71          // perceive every time step... This is the 'classical' way of tactical planning.
72          perception.perceive();
73  
74          // see how far we can drive
75          Length maxDistance = laneBasedGTU.getBehavioralCharacteristics().getParameter(ParameterTypes.LOOKAHEAD);
76          LanePathInfo lanePathInfo = buildLanePathInfo(laneBasedGTU, maxDistance);
77  
78          // look at the conditions for headway
79          Headway headway = perception.getPerceptionCategory(DefaultSimplePerception.class).getForwardHeadway();
80          AccelerationStep accelerationStep = null;
81          if (headway.getDistance().ge(maxDistance))
82          {
83              // TODO I really don't like this -- if there is a lane drop at 20 m, the GTU should stop...
84              accelerationStep =
85                  ((GTUFollowingModelOld) getCarFollowingModel()).computeAccelerationStepWithNoLeader(laneBasedGTU,
86                      lanePathInfo.getPath().getLength(), perception.getPerceptionCategory(DefaultSimplePerception.class)
87                          .getSpeedLimit());
88          }
89          else
90          {
91              accelerationStep =
92                  ((GTUFollowingModelOld) getCarFollowingModel()).computeAccelerationStep(laneBasedGTU, headway.getSpeed(),
93                      headway.getDistance(), lanePathInfo.getPath().getLength(), perception.getPerceptionCategory(
94                          DefaultSimplePerception.class).getSpeedLimit());
95          }
96  
97          // see if we have to continue standing still. In that case, generate a stand still plan
98          if (accelerationStep.getAcceleration().si < 1E-6 && laneBasedGTU.getSpeed().si < OperationalPlan.DRIFTING_SPEED_SI)
99          {
100             return new OperationalPlan(getGtu(), locationAtStartTime, startTime, accelerationStep.getDuration());
101         }
102 
103         List<Segment> operationalPlanSegmentList = new ArrayList<>();
104         if (accelerationStep.getAcceleration().si == 0.0)
105         {
106             Segment segment = new OperationalPlan.SpeedSegment(accelerationStep.getDuration());
107             operationalPlanSegmentList.add(segment);
108         }
109         else
110         {
111             Segment segment =
112                 new OperationalPlan.AccelerationSegment(accelerationStep.getDuration(), accelerationStep.getAcceleration());
113             operationalPlanSegmentList.add(segment);
114         }
115         OperationalPlan op =
116             new OperationalPlan(getGtu(), lanePathInfo.getPath(), startTime, getGtu().getSpeed(), operationalPlanSegmentList);
117         return op;
118     }
119 
120     /** {@inheritDoc} */
121     @Override
122     public final String toString()
123     {
124         return "LaneBasedGTUFollowingTacticalPlanner [carFollowingModel=" + getCarFollowingModel() + "]";
125     }
126 }