LaneBasedGTUFollowingTacticalPlanner.java

  1. package org.opentrafficsim.road.gtu.lane.tactical;

  2. import java.util.ArrayList;
  3. import java.util.List;

  4. import org.djunits.unit.DurationUnit;
  5. import org.djunits.value.vdouble.scalar.Duration;
  6. import org.djunits.value.vdouble.scalar.Length;
  7. import org.djunits.value.vdouble.scalar.Time;
  8. import org.opentrafficsim.base.parameters.ParameterException;
  9. import org.opentrafficsim.core.gtu.GTUException;
  10. import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan;
  11. import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan.Segment;
  12. import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
  13. import org.opentrafficsim.core.network.NetworkException;
  14. import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
  15. import org.opentrafficsim.road.gtu.lane.perception.CategoricalLanePerception;
  16. import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
  17. import org.opentrafficsim.road.gtu.lane.perception.categories.DefaultSimplePerception;
  18. import org.opentrafficsim.road.gtu.lane.perception.categories.DirectDefaultSimplePerception;
  19. import org.opentrafficsim.road.gtu.lane.perception.headway.Headway;
  20. import org.opentrafficsim.road.gtu.lane.tactical.following.AccelerationStep;
  21. import org.opentrafficsim.road.gtu.lane.tactical.following.GTUFollowingModelOld;

  22. import nl.tudelft.simulation.language.d3.DirectedPoint;

  23. /**
  24.  * Lane-based tactical planner that implements car following behavior. This tactical planner retrieves the car following model
  25.  * from the strategical planner and will generate an operational plan for the GTU.
  26.  * <p>
  27.  * This lane-based tactical planner makes decisions based on headway (GTU following model). It can ask the strategic planner for
  28.  * assistance on the route to take when the network splits.
  29.  * <p>
  30.  * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  31.  * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  32.  * </p>
  33.  * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
  34.  * initial version Nov 25, 2015 <br>
  35.  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  36.  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  37.  */
  38. public class LaneBasedGTUFollowingTacticalPlanner extends AbstractLaneBasedTacticalPlanner
  39. {
  40.     /** */
  41.     private static final long serialVersionUID = 20151125L;

  42.     /**
  43.      * Instantiate a tactical planner with just GTU following behavior and no lane changes.
  44.      * @param carFollowingModel Car-following model.
  45.      * @param gtu GTU
  46.      */
  47.     public LaneBasedGTUFollowingTacticalPlanner(final GTUFollowingModelOld carFollowingModel, final LaneBasedGTU gtu)
  48.     {
  49.         super(carFollowingModel, gtu, new CategoricalLanePerception(gtu));
  50.         getPerception().addPerceptionCategory(new DirectDefaultSimplePerception(getPerception()));
  51.     }

  52.     /** {@inheritDoc} */
  53.     @Override
  54.     public final OperationalPlan generateOperationalPlan(final Time startTime, final DirectedPoint locationAtStartTime)
  55.             throws OperationalPlanException, NetworkException, GTUException, ParameterException
  56.     {
  57.         // ask Perception for the local situation
  58.         LaneBasedGTU laneBasedGTU = getGtu();
  59.         LanePerception perception = getPerception();

  60.         // if the GTU's maximum speed is zero (block), generate a stand still plan for one second
  61.         if (laneBasedGTU.getMaximumSpeed().si < OperationalPlan.DRIFTING_SPEED_SI)
  62.         {
  63.             return new OperationalPlan(getGtu(), locationAtStartTime, startTime, new Duration(1.0, DurationUnit.SECOND));
  64.         }

  65.         // perceive every time step... This is the 'classical' way of tactical planning.
  66.         perception.perceive();

  67.         // see how far we can drive
  68.         Length maxDistance = laneBasedGTU.getParameters().getParameter(LOOKAHEAD);
  69.         LanePathInfo lanePathInfo = buildLanePathInfo(laneBasedGTU, maxDistance);

  70.         // look at the conditions for headway from a GTU in front
  71.         DefaultSimplePerception simplePerception = perception.getPerceptionCategory(DefaultSimplePerception.class);
  72.         Headway headwayGTU = simplePerception.getForwardHeadwayGTU();
  73.         AccelerationStep accelerationStepGTU = null;
  74.         if (headwayGTU.getDistance().ge(maxDistance))
  75.         {
  76.             // TODO I really don't like this -- if there is a lane drop at 20 m, the GTU should stop...
  77.             accelerationStepGTU = ((GTUFollowingModelOld) getCarFollowingModel()).computeAccelerationStepWithNoLeader(
  78.                     laneBasedGTU, lanePathInfo.getPath().getLength(), simplePerception.getSpeedLimit());
  79.         }
  80.         else
  81.         {
  82.             accelerationStepGTU =
  83.                     ((GTUFollowingModelOld) getCarFollowingModel()).computeAccelerationStep(laneBasedGTU, headwayGTU.getSpeed(),
  84.                             headwayGTU.getDistance(), lanePathInfo.getPath().getLength(), simplePerception.getSpeedLimit());
  85.         }

  86.         // look at the conditions for headway from an object in front
  87.         Headway headwayObject = simplePerception.getForwardHeadwayObject();
  88.         AccelerationStep accelerationStepObject = null;
  89.         if (headwayObject.getDistance().ge(maxDistance))
  90.         {
  91.             accelerationStepObject = ((GTUFollowingModelOld) getCarFollowingModel()).computeAccelerationStepWithNoLeader(
  92.                     laneBasedGTU, lanePathInfo.getPath().getLength(), simplePerception.getSpeedLimit());
  93.         }
  94.         else
  95.         {
  96.             accelerationStepObject = ((GTUFollowingModelOld) getCarFollowingModel()).computeAccelerationStep(laneBasedGTU,
  97.                     headwayObject.getSpeed(), headwayObject.getDistance(), lanePathInfo.getPath().getLength(),
  98.                     simplePerception.getSpeedLimit());
  99.         }

  100.         // see which one is most limiting
  101.         AccelerationStep accelerationStep = accelerationStepGTU.getAcceleration().lt(accelerationStepObject.getAcceleration())
  102.                 ? accelerationStepGTU : accelerationStepObject;

  103.         // see if we have to continue standing still. In that case, generate a stand still plan
  104.         if (accelerationStep.getAcceleration().si < 1E-6 && laneBasedGTU.getSpeed().si < OperationalPlan.DRIFTING_SPEED_SI)
  105.         {
  106.             return new OperationalPlan(getGtu(), locationAtStartTime, startTime, accelerationStep.getDuration());
  107.         }

  108.         List<Segment> operationalPlanSegmentList = new ArrayList<>();
  109.         if (accelerationStep.getAcceleration().si == 0.0)
  110.         {
  111.             Segment segment = new OperationalPlan.SpeedSegment(accelerationStep.getDuration());
  112.             operationalPlanSegmentList.add(segment);
  113.         }
  114.         else
  115.         {
  116.             Segment segment =
  117.                     new OperationalPlan.AccelerationSegment(accelerationStep.getDuration(), accelerationStep.getAcceleration());
  118.             operationalPlanSegmentList.add(segment);
  119.         }
  120.         OperationalPlan op = new OperationalPlan(getGtu(), lanePathInfo.getPath(), startTime, getGtu().getSpeed(),
  121.                 operationalPlanSegmentList);
  122.         return op;
  123.     }

  124.     /** {@inheritDoc} */
  125.     @Override
  126.     public final String toString()
  127.     {
  128.         return "LaneBasedGTUFollowingTacticalPlanner [carFollowingModel=" + getCarFollowingModel() + "]";
  129.     }
  130. }