ToledoCarFollowing.java
package org.opentrafficsim.road.gtu.lane.tactical.toledo;
import static org.opentrafficsim.core.gtu.behavioralcharacteristics.AbstractParameterType.Check.NEGATIVE;
import static org.opentrafficsim.core.gtu.behavioralcharacteristics.AbstractParameterType.Check.POSITIVE;
import java.util.SortedMap;
import org.djunits.unit.AccelerationUnit;
import org.djunits.unit.LengthUnit;
import org.djunits.unit.SpeedUnit;
import org.djunits.unit.TimeUnit;
import org.djunits.value.vdouble.scalar.Acceleration;
import org.djunits.value.vdouble.scalar.Duration;
import org.djunits.value.vdouble.scalar.Length;
import org.djunits.value.vdouble.scalar.Speed;
import org.opentrafficsim.core.gtu.behavioralcharacteristics.BehavioralCharacteristics;
import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterException;
import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterTypeDouble;
import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterTypeDuration;
import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterTypeSpeed;
import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractCarFollowingModel;
import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
/**
* <p>
* Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
* BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
* <p>
* @version $Revision$, $LastChangedDate$, by $Author$, initial version Jul 7, 2016 <br>
* @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
* @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
* @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
*/
public class ToledoCarFollowing extends AbstractCarFollowingModel
{
/** */
public static final ParameterTypeSpeed CDS = new ParameterTypeSpeed("C_DS", "Constant in desired speed.", new Speed(
17.636, SpeedUnit.SI), POSITIVE);
/** */
public static final ParameterTypeSpeed BETADS = new ParameterTypeSpeed("BETA_DS",
"Reduction of desired speed for trucks.", new Speed(-1.458, SpeedUnit.SI), NEGATIVE);
/** */
public static final ParameterTypeSpeed ALPHADS = new ParameterTypeSpeed("ALPHA_DS",
"Factor on error term of desired speed.", new Speed(-0.105, SpeedUnit.SI));
/** */
public static final ParameterTypeDuration HSTAR = new ParameterTypeDuration("h*", "Desired time headway.", new Duration(
2.579, TimeUnit.SI));
/** */
public static final ParameterTypeDouble LAMBDAFF = new ParameterTypeDouble("Lambda_ff",
"Free flow acceleration sensitivity.", 0.0881, POSITIVE);
/** */
public static final ParameterTypeDouble SIGMAFF = new ParameterTypeDouble("Sigma_ff",
"Free flow acceleration standard deviation.", Math.exp(0.169));
/** */
public static final ParameterTypeDouble CCFACC = new ParameterTypeDouble("C_CF_ACC",
"Constant for car following acceleration.", 0.0355, POSITIVE);
/** */
public static final ParameterTypeDouble BETAACC = new ParameterTypeDouble("BETA_ACC",
"Power on speed for acceleration.", 0.291, POSITIVE);
/** */
public static final ParameterTypeDouble GAMMAACC = new ParameterTypeDouble("GAMMA_ACC",
"Power on distance headway for acceleration.", -0.166, NEGATIVE);
/** */
public static final ParameterTypeDouble RHOACC = new ParameterTypeDouble("RHO_ACC",
"Power on density for acceleration.", 0.550, POSITIVE);
/** */
public static final ParameterTypeDouble LAMBDAACC = new ParameterTypeDouble("LAMBDA_ACC",
"Power on speed difference for acceleration.", 0.520, POSITIVE);
/** */
public static final ParameterTypeDouble SIGMAACC = new ParameterTypeDouble("Sigma_acc",
"Car-following acceleration standard deviation.", Math.exp(0.126));
/** */
public static final ParameterTypeDouble CCFDEC = new ParameterTypeDouble("C_CF_DEC",
"Constant for car following deceleration.", -0.860, NEGATIVE);
/** */
public static final ParameterTypeDouble GAMMADEC = new ParameterTypeDouble("GAMMA_DEC",
"Power on distance headway for deceleration.", -0.565, NEGATIVE);
/** */
public static final ParameterTypeDouble RHODEC = new ParameterTypeDouble("RHO_DEC",
"Power on density for deceleration.", 0.143, POSITIVE);
/** */
public static final ParameterTypeDouble LAMBDADEC = new ParameterTypeDouble("LAMBDA_DEC",
"Power on speed difference for deceleration.", 0.834, POSITIVE);
/** */
public static final ParameterTypeDouble SIGMADEC = new ParameterTypeDouble("Sigma_DEC",
"Car-following deceleration standard deviation.", Math.exp(0.156));
/** {@inheritDoc} */
@Override
public final Speed
desiredSpeed(final BehavioralCharacteristics behavioralCharacteristics, final SpeedLimitInfo speedInfo)
throws ParameterException
{
return behavioralCharacteristics.getParameter(CDS).plus(behavioralCharacteristics.getParameter(BETADS)).plus(
behavioralCharacteristics.getParameter(ALPHADS).multiplyBy(
behavioralCharacteristics.getParameter(ToledoLaneChangeParameters.ERROR_TERM)));
}
/** {@inheritDoc} */
@Override
public final Length desiredHeadway(final BehavioralCharacteristics behavioralCharacteristics, final Speed speed)
throws ParameterException
{
return behavioralCharacteristics.getParameter(HSTAR).multiplyBy(speed);
}
/** {@inheritDoc} */
@Override
protected final Acceleration followingAcceleration(final BehavioralCharacteristics behavioralCharacteristics,
final Speed speed, final Speed desiredSpeed, final Length desiredHeadway, final SortedMap<Length, Speed> leaders)
throws ParameterException
{
if (leaders.isEmpty() || leaders.firstKey().gt(desiredHeadway))
{
// free
double eff =
Toledo.RANDOM.nextGaussian() * behavioralCharacteristics.getParameter(SIGMAFF)
* behavioralCharacteristics.getParameter(SIGMAFF);
return new Acceleration(behavioralCharacteristics.getParameter(LAMBDAFF) * (desiredSpeed.si - speed.si) + eff,
AccelerationUnit.SI);
}
// TODO speed difference with reaction time
if (leaders.get(leaders.firstKey()).ge(speed))
{
// accelerate
double eCfAcc =
Toledo.RANDOM.nextGaussian() * behavioralCharacteristics.getParameter(SIGMAACC)
* behavioralCharacteristics.getParameter(SIGMAACC);
// {@formatter:off}
return new Acceleration(
behavioralCharacteristics.getParameter(CCFACC)
* Math.pow(speed.si, behavioralCharacteristics.getParameter(BETAACC))
* Math.pow(leaders.firstKey().si, behavioralCharacteristics.getParameter(GAMMAACC))
* Math.pow(getDensity(leaders), behavioralCharacteristics.getParameter(RHOACC))
* Math.pow(leaders.get(leaders.firstKey()).si - speed.si, behavioralCharacteristics.getParameter(LAMBDAACC))
+ eCfAcc,
AccelerationUnit.SI);
// {@formatter:on}
}
// decelerate
double eCfDec =
Toledo.RANDOM.nextGaussian() * behavioralCharacteristics.getParameter(SIGMADEC)
* behavioralCharacteristics.getParameter(SIGMADEC);
// {@formatter:off}
return new Acceleration(
behavioralCharacteristics.getParameter(CCFDEC)
* Math.pow(leaders.firstKey().si, behavioralCharacteristics.getParameter(GAMMADEC))
* Math.pow(getDensity(leaders), behavioralCharacteristics.getParameter(RHODEC))
* Math.pow(speed.si - leaders.get(leaders.firstKey()).si, behavioralCharacteristics.getParameter(LAMBDADEC))
+ eCfDec,
AccelerationUnit.SI);
// {@formatter:on}
}
/** {@inheritDoc} */
@Override
public final String getName()
{
return "ToledoCFM";
}
/** {@inheritDoc} */
@Override
public final String getLongName()
{
return "Toledo car-following model";
}
/**
* Returns the density based on the leaders in veh/km.
* @param leaders leading vehicles
* @return density based on the leaders in veh/km
*/
private double getDensity(final SortedMap<Length, Speed> leaders)
{
if (leaders.isEmpty())
{
return 0;
}
return leaders.lastKey().getInUnit(LengthUnit.KILOMETER) / leaders.size();
}
}