AbstractLaneBasedTacticalPlannerFactory.java
package org.opentrafficsim.road.gtu.lane.tactical;
import org.djunits.value.vdouble.scalar.Length;
import org.djunits.value.vdouble.scalar.Speed;
import org.opentrafficsim.base.parameters.ParameterException;
import org.opentrafficsim.base.parameters.Parameters;
import org.opentrafficsim.core.gtu.GtuException;
import org.opentrafficsim.core.gtu.GtuType;
import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
import org.opentrafficsim.road.gtu.lane.perception.PerceptionFactory;
import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModelFactory;
import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
import org.opentrafficsim.road.network.speed.SpeedLimitTypes;
/**
* Abstract tactical planner factory which uses a car-following model factory for supplying peeked desired speed and headway. To
* this end the next car-following model is created and used throughout all peek invocations until an implementation of this
* class calls {@code nextCarFollowingModel()} to generate a new tactical planner. Implementations should also use
* {@code getCarFollowingParameters()} in the {@code getParameters()} method to include the parameters a car-following model
* requires.
* <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>
* @param <T> class of the tactical planner generated
*/
public abstract class AbstractLaneBasedTacticalPlannerFactory<T extends LaneBasedTacticalPlanner>
implements LaneBasedTacticalPlannerFactory<T>
{
/** Constructor for the car-following model. */
private final CarFollowingModelFactory<? extends CarFollowingModel> carFollowingModelFactory;
/** Peeked car following model. */
private CarFollowingModel peekedCarFollowingModel = null;
/** Perception factory. */
private final PerceptionFactory perceptionFactory;
/**
* Constructor.
* @param carFollowingModelFactory CarFollowingModelFactory<? extends CarFollowingModel>; car-following model factory
* @param perceptionFactory PerceptionFactory; perception factory
*/
public AbstractLaneBasedTacticalPlannerFactory(
final CarFollowingModelFactory<? extends CarFollowingModel> carFollowingModelFactory,
final PerceptionFactory perceptionFactory)
{
this.carFollowingModelFactory = carFollowingModelFactory;
this.perceptionFactory = perceptionFactory;
}
/**
* Returns the next car following model, which will be a fixed peeked instance until {@code nextCarFollowingModel()} is
* called.
* @return CarFollowingModel; next car following model
*/
private CarFollowingModel peekCarFollowingModel()
{
if (this.peekedCarFollowingModel != null)
{
return this.peekedCarFollowingModel;
}
this.peekedCarFollowingModel = this.carFollowingModelFactory.generateCarFollowingModel();
return this.peekedCarFollowingModel;
}
/**
* Returns the next car following model.
* @param gtu LaneBasedGtu; gtu
* @return CarFollowingModel; next car following model
*/
protected final CarFollowingModel nextCarFollowingModel(final LaneBasedGtu gtu)
{
CarFollowingModel model = peekCarFollowingModel();
model.init(gtu);
this.peekedCarFollowingModel = null; // peek will create a new one
return model;
}
/**
* Returns the parameters for the car-following model using the factory. This method should be used in the
* {@code getParameters()} method of implementing sub-classes.
* @return Parameters; parameters for the car-following model using the factory
* @throws ParameterException on illegal parameter value
*/
protected final Parameters getCarFollowingParameters() throws ParameterException
{
return this.carFollowingModelFactory.getParameters();
}
/**
* Returns a {@code String} representation of the car-following model factory. This method may be used in the
* {@code toString()} method of implementing sub-classes.
* @return String; representation of the car-following model factory
*/
protected final String getCarFollowingModelFactoryString()
{
return this.carFollowingModelFactory.toString();
}
/** {@inheritDoc} */
@Override
public final Speed peekDesiredSpeed(final GtuType gtuType, final Speed speedLimit, final Speed maxGtuSpeed,
final Parameters parameters) throws GtuException
{
try
{
SpeedLimitInfo sli = new SpeedLimitInfo();
sli.addSpeedInfo(SpeedLimitTypes.MAX_VEHICLE_SPEED, maxGtuSpeed);
sli.addSpeedInfo(SpeedLimitTypes.FIXED_SIGN, speedLimit);
return peekCarFollowingModel().desiredSpeed(parameters, sli);
}
catch (ParameterException exception)
{
throw new GtuException(exception);
}
}
/** {@inheritDoc} */
@Override
public final Length peekDesiredHeadway(final GtuType gtuType, final Speed speed, final Parameters parameters)
throws GtuException
{
try
{
return peekCarFollowingModel().desiredHeadway(parameters, speed);
}
catch (ParameterException exception)
{
throw new GtuException(exception);
}
}
/**
* Returns the perception factory.
* @return PerceptionFactory; perception factory
*/
public PerceptionFactory getPerceptionFactory()
{
return this.perceptionFactory;
}
}