IncentiveSocioSpeed.java

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

  2. import org.djunits.value.vdouble.scalar.Length;
  3. import org.djunits.value.vdouble.scalar.Speed;
  4. import org.djutils.exceptions.Try;
  5. import org.opentrafficsim.base.parameters.ParameterException;
  6. import org.opentrafficsim.base.parameters.ParameterTypeDouble;
  7. import org.opentrafficsim.base.parameters.ParameterTypeLength;
  8. import org.opentrafficsim.base.parameters.ParameterTypeSpeed;
  9. import org.opentrafficsim.base.parameters.ParameterTypes;
  10. import org.opentrafficsim.base.parameters.Parameters;
  11. import org.opentrafficsim.core.gtu.perception.EgoPerception;
  12. import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
  13. import org.opentrafficsim.core.network.LateralDirectionality;
  14. import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
  15. import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
  16. import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable;
  17. import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
  18. import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
  19. import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
  20. import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGtu;
  21. import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
  22. import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
  23. import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
  24. import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
  25. import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;

  26. /**
  27.  * Lane change incentive based on social pressure. Drivers may refrain from changing left to not hinder faster traffic, or
  28.  * drivers may change right to get out of the way. When drivers are on the left lane, this is considered 'overtaking', and
  29.  * related to this the desired speed could be increased by using {@code SocioDesiredSpeedModel}.
  30.  * <p>
  31.  * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  32.  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  33.  * </p>
  34.  * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  35.  * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
  36.  * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
  37.  */
  38. // TODO keep left or right rules
  39. public class IncentiveSocioSpeed implements VoluntaryIncentive
  40. {

  41.     /** Social pressure applied to the leader. */
  42.     protected static final ParameterTypeDouble RHO = Tailgating.RHO;

  43.     /** Hierarchy parameter. */
  44.     protected static final ParameterTypeDouble SOCIO = LmrsParameters.SOCIO;

  45.     /** Speed threshold below which traffic is considered congested. */
  46.     protected static final ParameterTypeSpeed VCONG = ParameterTypes.VCONG;

  47.     /** Vgain parameter; ego-speed sensitivity. */
  48.     protected static final ParameterTypeSpeed VGAIN = LmrsParameters.VGAIN;

  49.     /** Look-ahead distance. */
  50.     protected static final ParameterTypeLength LOOKAHEAD = ParameterTypes.LOOKAHEAD;

  51.     @Override
  52.     public final Desire determineDesire(final Parameters parameters, final LanePerception perception,
  53.             final CarFollowingModel carFollowingModel, final Desire mandatoryDesire, final Desire voluntaryDesire)
  54.             throws ParameterException, OperationalPlanException
  55.     {
  56.         double dLeft = 0;
  57.         double dRight = 0;
  58.         Speed vCong = parameters.getParameter(VCONG);
  59.         Speed ownSpeed = perception.getPerceptionCategoryOrNull(EgoPerception.class).getSpeed();
  60.         if (ownSpeed.gt(vCong))
  61.         {
  62.             double sigma = parameters.getParameter(SOCIO);
  63.             NeighborsPerception neighbors = perception.getPerceptionCategory(NeighborsPerception.class);
  64.             InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
  65.             boolean leftLane = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.LEFT).si > 0.0;
  66.             boolean rightLane = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.RIGHT).si > 0.0;
  67.             // change right to get out of the way
  68.             if (rightLane && mandatoryDesire.right() >= 0.0)
  69.             {
  70.                 PerceptionCollectable<HeadwayGtu, LaneBasedGtu> followers = neighbors.getFollowers(RelativeLane.CURRENT);
  71.                 if (!followers.isEmpty())
  72.                 {
  73.                     double rho = parameters.getParameter(RHO);
  74.                     HeadwayGtu follower = followers.first();
  75.                     double rhoFollower = follower.getParameters().getParameter(RHO);
  76.                     if (rhoFollower * sigma > rho)
  77.                     {
  78.                         dRight = rhoFollower * sigma;
  79.                     }
  80.                 }
  81.             }
  82.             // stay right to keep out of the way
  83.             if (leftLane && mandatoryDesire.left() <= 0.0)
  84.             {
  85.                 PerceptionCollectable<HeadwayGtu, LaneBasedGtu> followers = neighbors.getFollowers(RelativeLane.LEFT);
  86.                 if (followers != null && !followers.isEmpty())
  87.                 {
  88.                     double rho;
  89.                     PerceptionCollectable<HeadwayGtu, LaneBasedGtu> leaders = neighbors.getLeaders(RelativeLane.LEFT);
  90.                     if (leaders != null && !leaders.isEmpty())
  91.                     {
  92.                         HeadwayGtu leader = leaders.first();
  93.                         Speed vDes = Try.assign(() -> perception.getGtu().getDesiredSpeed(),
  94.                                 "Could not obtain GTU from perception.");
  95.                         Speed vGain = parameters.getParameter(VGAIN);
  96.                         Length x0 = parameters.getParameter(LOOKAHEAD);
  97.                         rho = Tailgating.socialPressure(ownSpeed, vCong, vDes, leader.getSpeed(), vGain, leader.getDistance(),
  98.                                 x0);
  99.                     }
  100.                     else
  101.                     {
  102.                         rho = 0.0;
  103.                     }
  104.                     HeadwayGtu follower = followers.first();
  105.                     Speed vGainFollower = follower.getParameters().getParameter(VGAIN);
  106.                     Length x0Follower = follower.getParameters().getParameter(LOOKAHEAD);
  107.                     double rhoFollower = Tailgating.socialPressure(follower.getSpeed(), vCong, follower.getDesiredSpeed(),
  108.                             ownSpeed, vGainFollower, follower.getDistance(), x0Follower);
  109.                     if (rhoFollower * sigma > rho)
  110.                     {
  111.                         dLeft = -rhoFollower * sigma;
  112.                     }
  113.                 }
  114.             }
  115.         }
  116.         return new Desire(dLeft, dRight);
  117.     }

  118.     @Override
  119.     public final String toString()
  120.     {
  121.         return "IncentiveSocioSpeed";
  122.     }

  123. }