package org.opentrafficsim.road.gtu.following; import java.util.ArrayList; import java.util.List; import java.util.Set; import org.djunits.unit.AccelerationUnit; import org.djunits.unit.TimeUnit; import org.djunits.value.vdouble.scalar.Acceleration; import org.djunits.value.vdouble.scalar.Length; import org.djunits.value.vdouble.scalar.Speed; import org.djunits.value.vdouble.scalar.Time; import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface; /** * Extended version of FixedAccelerationModel. The addition is that this GTUFollowingModel stores a series of acceleration and * duration values. Mostly used for testing. *

* Copyright (c) 2013-2015 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
* BSD-style license. See OpenTrafficSim License. *

* @version $Revision: 1401 $, $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, by $Author: averbraeck $, * initial version 6 feb. 2015
* @author Alexander Verbraeck * @author Peter Knoppers */ public class SequentialFixedAccelerationModel extends AbstractGTUFollowingModel { /** The list of result values of this SequentialFixedAccelerationModel. */ private final List steps = new ArrayList(); /** The simulator engine. */ private final OTSDEVSSimulatorInterface simulator; /** * Construct a SequentialFixedAccelerationModel with empty list of FixedAccelerationModel steps. * @param simulator DEVSSimulator; the simulator (needed to obtain the current simulation time) */ public SequentialFixedAccelerationModel(final OTSDEVSSimulatorInterface simulator) { this.simulator = simulator; } /** * Construct a SequentialFixedAccelerationModel and load it with a list of FixedAccelerationModel steps. * @param simulator DEVSSimulator; the simulator (needed to obtain the current simulation time) * @param steps Set<FixedAccelerationModel>; the list of FixedAccelerationModel steps. */ public SequentialFixedAccelerationModel(final OTSDEVSSimulatorInterface simulator, final Set steps) { this(simulator); this.steps.addAll(steps); } /** * Add one FixedAccelerationModel step to this SequentialFixedAccelerationModel. * @param step FixedAccelerationModel; the step to add * @return SequentialFixedAccelerationModel; this modified SequentialFixedAccelerationModel */ public final SequentialFixedAccelerationModel addStep(final FixedAccelerationModel step) { this.steps.add(step); return this; } /** * Retrieve the number of FixedAccelerationModel steps in this SequentialFixedAccelerationModel. * @return int; the number of steps in this SequentialFixedAccelerationModel */ public final int size() { return this.steps.size(); } /** * Retrieve one FixedAccelerationModel step. * @param index int; the index of the retrieved FixedAccelerationModel step * @return FixedAccelerationModel */ public final FixedAccelerationModel get(final int index) { return this.steps.get(index); } /** * Retrieve the simulation time at the end of the Nth step of this SequentialFixedAccelerationModel. * @param index int; the step * @return DoubleScalar.Abs<TimeUnit> */ public final Time.Abs timeAfterCompletionOfStep(final int index) { Time.Abs sum = new Time.Abs(0, TimeUnit.SI); for (int i = 0; i <= index; i++) { sum = sum.plus(this.steps.get(i).getDuration()); } return sum; } /** Maximum error of the simulator clock. */ private static final double MAXIMUMTIMEERROR = 0.001; // 1 millisecond /** * Find the FixedAccelerationModel that starts at the current simulator time. * @return FixedAccelerationModel; the FixedAccelerationModel that starts at the current simulator time */ private FixedAccelerationModel getAccelerationModel() { Time.Abs when = this.simulator.getSimulatorTime().getTime(); double remainingTime = when.getSI(); for (FixedAccelerationModel step : this.steps) { if (remainingTime < -MAXIMUMTIMEERROR) { throw new Error("FixedSequentialAcceleration does not have a result for " + when); } if (remainingTime < MAXIMUMTIMEERROR) { return step; } remainingTime -= step.getDuration().getSI(); } throw new Error("FixedSequentialAcceleration does not have a result for " + when); } /** {@inheritDoc} */ @Override public final Acceleration computeAcceleration(final Speed followerSpeed, final Speed followerMaximumSpeed, final Speed leaderSpeed, final Length.Rel headway, final Speed speedLimit) { return getAccelerationModel().getAcceleration(); } /** {@inheritDoc} */ @Override public final Acceleration maximumSafeDeceleration() { // TODO specify in constructor return new Acceleration(2, AccelerationUnit.METER_PER_SECOND_2); } /** {@inheritDoc} */ @Override public final Time.Rel getStepSize() { return getAccelerationModel().getStepSize(); } /** {@inheritDoc} */ @Override public final String getName() { return "FSAM"; } /** {@inheritDoc} */ @Override public final String getLongName() { return "Fixed sequential acceleration model"; } }