IncentiveRoute.java

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

  2. import java.util.SortedSet;

  3. import org.djunits.value.vdouble.scalar.Length;
  4. import org.djunits.value.vdouble.scalar.Speed;
  5. import org.opentrafficsim.base.parameters.ParameterException;
  6. import org.opentrafficsim.base.parameters.ParameterTypeDuration;
  7. import org.opentrafficsim.base.parameters.ParameterTypeLength;
  8. import org.opentrafficsim.base.parameters.ParameterTypes;
  9. import org.opentrafficsim.base.parameters.Parameters;
  10. import org.opentrafficsim.core.gtu.perception.EgoPerception;
  11. import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
  12. import org.opentrafficsim.core.network.LateralDirectionality;
  13. import org.opentrafficsim.road.gtu.lane.perception.InfrastructureLaneChangeInfo;
  14. import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
  15. import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
  16. import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
  17. import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
  18. import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
  19. import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.MandatoryIncentive;

  20. /**
  21.  * Determines desire by assessing the number of required lane change to be performed and the distance within which these have to
  22.  * be performed. Desire starts to increase from 0 linearly over a distance of x0 per required lane change, or per v*t0 per
  23.  * required lane change. For v>x0/t0 this gives that remaining time is critical, while for v<x0/t0 remaining space is
  24.  * critical. The desire is set towards the adjacent lane with a better situation. Negative desire towards the other lane, the
  25.  * extent of which pertains to the other adjacent lane, is also set.
  26.  * <p>
  27.  * Copyright (c) 2013-2022 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  28.  * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
  29.  * <p>
  30.  * @version $Revision$, $LastChangedDate$, by $Author$, initial version Apr 13, 2016 <br>
  31.  * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  32.  */
  33. public class IncentiveRoute implements MandatoryIncentive
  34. {

  35.     /** Look ahead parameter type. */
  36.     protected static final ParameterTypeLength LOOKAHEAD = ParameterTypes.LOOKAHEAD;

  37.     /** Look-ahead time for mandatory lane changes parameter type. */
  38.     public static final ParameterTypeDuration T0 = ParameterTypes.T0;

  39.     /** {@inheritDoc} */
  40.     @Override
  41.     public final Desire determineDesire(final Parameters parameters, final LanePerception perception,
  42.             final CarFollowingModel carFollowingModel, final Desire mandatoryDesire)
  43.             throws ParameterException, OperationalPlanException
  44.     {
  45.         Speed speed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
  46.         InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);

  47.         // desire to leave current lane
  48.         SortedSet<InfrastructureLaneChangeInfo> currentInfo = infra.getInfrastructureLaneChangeInfo(RelativeLane.CURRENT);
  49.         Length currentFirst = currentInfo.isEmpty() || currentInfo.first().getRequiredNumberOfLaneChanges() == 0
  50.                 ? Length.POSITIVE_INFINITY : currentInfo.first().getRemainingDistance();
  51.         double dCurr = getDesireToLeave(parameters, infra, RelativeLane.CURRENT, speed);
  52.         double dLeft = 0;
  53.         if (perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.LEFT)
  54.                 && infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.LEFT).neg().lt(currentFirst))
  55.         {
  56.             // desire to leave left lane
  57.             dLeft = getDesireToLeave(parameters, infra, RelativeLane.LEFT, speed);
  58.             // desire to leave from current to left lane
  59.             dLeft = dLeft < dCurr ? dCurr : dLeft > dCurr ? -dLeft : 0;
  60.         }
  61.         double dRigh = 0;
  62.         if (perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.RIGHT) && infra
  63.                 .getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.RIGHT).neg().lt(currentFirst))
  64.         {
  65.             // desire to leave right lane
  66.             dRigh = getDesireToLeave(parameters, infra, RelativeLane.RIGHT, speed);
  67.             // desire to leave from current to right lane
  68.             dRigh = dRigh < dCurr ? dCurr : dRigh > dCurr ? -dRigh : 0;
  69.         }
  70.         return new Desire(dLeft, dRigh);
  71.     }

  72.     /**
  73.      * Calculates desire to leave a lane.
  74.      * @param params Parameters; parameters
  75.      * @param infra InfrastructurePerception; infrastructure perception
  76.      * @param lane RelativeLane; relative lane to evaluate
  77.      * @param speed Speed; speed
  78.      * @return desire to leave a lane
  79.      * @throws ParameterException in case of a parameter exception
  80.      * @throws OperationalPlanException in case of perception exceptions
  81.      */
  82.     private static double getDesireToLeave(final Parameters params, final InfrastructurePerception infra,
  83.             final RelativeLane lane, final Speed speed) throws ParameterException, OperationalPlanException
  84.     {
  85.         double dOut = 0.0;
  86.         if (infra.getCrossSection().contains(lane))
  87.         {
  88.             for (InfrastructureLaneChangeInfo info : infra.getInfrastructureLaneChangeInfo(lane))
  89.             {
  90.                 double d = getDesireToLeave(params, info.getRemainingDistance(), info.getRequiredNumberOfLaneChanges(), speed);
  91.                 dOut = d > dOut ? d : dOut;
  92.             }
  93.         }
  94.         return dOut;
  95.     }

  96.     /**
  97.      * Calculates desire to leave a lane for a single infrastructure info.
  98.      * @param params Parameters; parameters
  99.      * @param x Length; remaining distance for lane changes
  100.      * @param n int; number of required lane changes
  101.      * @param v Speed; current speed
  102.      * @return desire to leave a lane for a single infrastructure info
  103.      * @throws ParameterException in case of a parameter exception
  104.      */
  105.     public static double getDesireToLeave(final Parameters params, final Length x, final int n, final Speed v)
  106.             throws ParameterException
  107.     {
  108.         double d1 = 1 - x.si / (n * params.getParameter(LOOKAHEAD).si);
  109.         double d2 = 1 - (x.si / v.si) / (n * params.getParameter(T0).si);
  110.         d1 = d2 > d1 ? d2 : d1;
  111.         return d1 < 0 ? 0 : d1;
  112.     }

  113.     /** {@inheritDoc} */
  114.     @Override
  115.     public final String toString()
  116.     {
  117.         return "IncentiveRoute";
  118.     }

  119. }