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