GapAcceptance.java
- package org.opentrafficsim.road.gtu.lane.tactical.util.lmrs;
- import org.djunits.unit.AccelerationUnit;
- import org.djunits.value.vdouble.scalar.Acceleration;
- import org.djunits.value.vdouble.scalar.Speed;
- import org.opentrafficsim.base.parameters.ParameterException;
- import org.opentrafficsim.base.parameters.ParameterTypes;
- import org.opentrafficsim.base.parameters.Parameters;
- import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
- import org.opentrafficsim.core.network.LateralDirectionality;
- import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
- import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
- import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGtu;
- import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
- import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
- /**
- * Interface for LMRS gap-acceptance models.
- * <p>
- * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
- * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
- * </p>
- * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
- * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
- * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
- */
- public interface GapAcceptance
- {
- /** Being informed of the model and parameters of other drivers (default LMRS). */
- GapAcceptance INFORMED = new GapAcceptance()
- {
- /** {@inheritDoc} */
- @Override
- public boolean acceptGap(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
- final CarFollowingModel cfm, final double desire, final Speed ownSpeed, final Acceleration ownAcceleration,
- final LateralDirectionality lat) throws ParameterException, OperationalPlanException
- {
- NeighborsPerception neighbors = perception.getPerceptionCategory(NeighborsPerception.class);
- if (neighbors.isGtuAlongside(lat))
- {
- // gtu alongside
- return false;
- }
- // TODO
- /*-
- * Followers and are accepted if the acceleration and speed is 0, a leader is accepted if the ego speed is 0. This
- * is in place as vehicles that provide courtesy, will decelerate for us and overshoot the stand-still distance. As
- * a consequence, they will cease cooperation as they are too close. A pattern will arise where followers slow down
- * to (near) stand-still, and accelerate again, before we could ever accept the gap.
- *
- * By accepting the gap in the moment that they reach stand-still, this vehicle can at least accept the gap at some
- * point. All of this is only a problem if the own vehicle is standing still. Otherwise the stand-still distance is
- * not important and movement of our own will create an acceptable situation.
- *
- * What needs to be done, is to find a better way to deal with the cooperation and gap-acceptance, such that this
- * hack is not required.
- */
- Acceleration b = params.getParameter(ParameterTypes.B);
- Acceleration aFollow = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
- for (HeadwayGtu follower : neighbors.getFirstFollowers(lat))
- {
- if (follower.getSpeed().gt0() || follower.getAcceleration().gt0() || follower.getDistance().si < 1.0)
- {
- Acceleration a = LmrsUtil.singleAcceleration(follower.getDistance(), follower.getSpeed(), ownSpeed, desire,
- follower.getParameters(), follower.getSpeedLimitInfo(), follower.getCarFollowingModel());
- aFollow = Acceleration.min(aFollow, a);
- }
- }
- Acceleration aSelf = egoAcceleration(perception, params, sli, cfm, desire, ownSpeed, lat);
- Acceleration threshold = b.times(-desire);
- return aFollow.ge(threshold) && aSelf.ge(threshold) && ownAcceleration.ge(threshold);
- }
- /** {@inheritDoc} */
- @Override
- public String toString()
- {
- return "INFORMED";
- }
- };
- /** Being informed of the model and parameters of other drivers, but applying own headway value. */
- GapAcceptance EGO_HEADWAY = new GapAcceptance()
- {
- /** {@inheritDoc} */
- @Override
- public boolean acceptGap(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
- final CarFollowingModel cfm, final double desire, final Speed ownSpeed, final Acceleration ownAcceleration,
- final LateralDirectionality lat) throws ParameterException, OperationalPlanException
- {
- NeighborsPerception neigbors = perception.getPerceptionCategory(NeighborsPerception.class);
- if (neigbors.isGtuAlongside(lat))
- {
- // gtu alongside
- return false;
- }
- Acceleration b = params.getParameter(ParameterTypes.B);
- Acceleration aFollow = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
- for (HeadwayGtu follower : neigbors.getFirstFollowers(lat))
- {
- if (follower.getSpeed().gt0() || follower.getAcceleration().gt0())
- {
- // Change headway parameter
- Parameters folParams = follower.getParameters();
- folParams.setParameterResettable(ParameterTypes.TMIN, params.getParameter(ParameterTypes.TMIN));
- folParams.setParameterResettable(ParameterTypes.TMAX, params.getParameter(ParameterTypes.TMAX));
- Acceleration a = LmrsUtil.singleAcceleration(follower.getDistance(), follower.getSpeed(), ownSpeed, desire,
- folParams, follower.getSpeedLimitInfo(), follower.getCarFollowingModel());
- aFollow = Acceleration.min(aFollow, a);
- folParams.resetParameter(ParameterTypes.TMIN);
- folParams.resetParameter(ParameterTypes.TMAX);
- }
- }
- Acceleration aSelf = egoAcceleration(perception, params, sli, cfm, desire, ownSpeed, lat);
- Acceleration threshold = b.times(-desire);
- return aFollow.ge(threshold) && aSelf.ge(threshold);
- }
- /** {@inheritDoc} */
- @Override
- public String toString()
- {
- return "EGO_HEADWAY";
- }
- };
- /**
- * Determine whether a gap is acceptable.
- * @param perception LanePerception; perception
- * @param params Parameters; parameters
- * @param sli SpeedLimitInfo; speed limit info
- * @param cfm CarFollowingModel; car-following model
- * @param desire double; level of lane change desire
- * @param ownSpeed Speed; own speed
- * @param lat LateralDirectionality; lateral direction for synchronization
- * @return whether a gap is acceptable
- * @throws ParameterException if a parameter is not defined
- * @throws OperationalPlanException perception exception
- */
- static Acceleration egoAcceleration(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
- final CarFollowingModel cfm, final double desire, final Speed ownSpeed, final LateralDirectionality lat)
- throws ParameterException, OperationalPlanException
- {
- Acceleration aSelf = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
- if (ownSpeed.gt0())
- {
- for (
- HeadwayGtu leader : perception.getPerceptionCategory(NeighborsPerception.class).getFirstLeaders(lat))
- {
- Acceleration a = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(), desire, params,
- sli, cfm);
- aSelf = Acceleration.min(aSelf, a);
- }
- }
- return aSelf;
- }
- /**
- * Determine whether a gap is acceptable.
- * @param perception LanePerception; perception
- * @param params Parameters; parameters
- * @param sli SpeedLimitInfo; speed limit info
- * @param cfm CarFollowingModel; car-following model
- * @param desire double; level of lane change desire
- * @param ownSpeed Speed; own speed
- * @param ownAcceleration Acceleration; current car-following acceleration
- * @param lat LateralDirectionality; lateral direction for synchronization
- * @return whether a gap is acceptable
- * @throws ParameterException if a parameter is not defined
- * @throws OperationalPlanException perception exception
- */
- boolean acceptGap(LanePerception perception, Parameters params, SpeedLimitInfo sli, CarFollowingModel cfm, double desire,
- Speed ownSpeed, Acceleration ownAcceleration, LateralDirectionality lat)
- throws ParameterException, OperationalPlanException;
- }