package org.opentrafficsim.road.gtu.lane;
import java.util.Map;
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.gtu.GtuException;
import org.opentrafficsim.core.gtu.InternalGtu;
import org.opentrafficsim.core.gtu.RelativePosition;
import org.opentrafficsim.core.gtu.TurnIndicatorStatus;
import org.opentrafficsim.core.network.LateralDirectionality;
import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlanner;
import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
import org.opentrafficsim.road.network.lane.Lane;
import nl.tudelft.simulation.dsol.formalisms.eventscheduling.SimEventInterface;
import nl.tudelft.simulation.dsol.simtime.SimTimeDoubleUnit;
/**
* InternalLaneBasedGTU.java.
*
* Copyright (c) 2020-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
* BSD-style license. See OpenTrafficSim License.
*
* @author Alexander Verbraeck
* @author Peter Knoppers
* @author Wouter Schakel
*/
public interface InternalLaneBasedGtu extends LaneBasedGtu, InternalGtu
{
/** {@inheritDoc} */
@Override
LaneBasedStrategicalPlanner getStrategicalPlanner();
/** {@inheritDoc} */
@Override
LaneBasedStrategicalPlanner getStrategicalPlanner(Time time);
/** {@inheritDoc} */
@Override
default LaneBasedTacticalPlanner getTacticalPlanner()
{
return getStrategicalPlanner().getTacticalPlanner();
}
/** {@inheritDoc} */
@Override
default LaneBasedTacticalPlanner getTacticalPlanner(final Time time)
{
return getStrategicalPlanner(time).getTacticalPlanner(time);
}
/**
* Change lanes instantaneously.
* @param laneChangeDirection LateralDirectionality; the direction to change to
* @throws GtuException in case lane change fails
*/
void changeLaneInstantaneously(LateralDirectionality laneChangeDirection) throws GtuException;
/**
* Register on lanes in target lane.
* @param laneChangeDirection LateralDirectionality; direction of lane change
* @throws GtuException exception
*/
void initLaneChange(LateralDirectionality laneChangeDirection) throws GtuException;
/**
* Sets event to finalize lane change.
* @param event SimEventInterface<SimTimeDoubleUnit>; event
*/
void setFinalizeLaneChangeEvent(SimEventInterface event);
/**
* Sets whether the GTU perform lane changes instantaneously or not.
* @param instantaneous boolean; whether the GTU perform lane changes instantaneously or not
*/
void setInstantaneousLaneChange(boolean instantaneous);
/**
* Returns whether the GTU perform lane changes instantaneously or not.
* @return boolean; whether the GTU perform lane changes instantaneously or not
*/
boolean isInstantaneousLaneChange();
/**
* Return the longitudinal positions of a point relative to this GTU, relative to the center line of the Lanes in which the
* vehicle is registered.
* @param relativePosition RelativePosition; the position on the vehicle relative to the reference point.
* @param when Time; the future time for which to calculate the positions.
* @return the lanes and the position on the lanes where the GTU will be registered at the time, for the given position of
* the GTU.
* @throws GtuException when the vehicle is not on one of the lanes on which it is registered.
*/
Map positions(RelativePosition relativePosition, Time when) throws GtuException;
/**
* Return the longitudinal position of a point relative to this GTU, relative to the center line of the Lane.
* @param lane Lane; the position on this lane will be returned.
* @param relativePosition RelativePosition; the position on the vehicle relative to the reference point.
* @param when Time; the future time for which to calculate the positions.
* @return DoubleScalarAbs<LengthUnit>; the position, relative to the center line of the Lane.
* @throws GtuException when the vehicle is not on the given lane.
*/
Length position(Lane lane, RelativePosition relativePosition, Time when) throws GtuException;
/**
* Return the longitudinal positions of a point relative to this GTU, relative to the center line of the Lanes in which the
* vehicle is registered, as fractions of the length of the lane. This is important when we want to see if two vehicles are
* next to each other and we compare an 'inner' and 'outer' curve.
* @param relativePosition RelativePosition; the position on the vehicle relative to the reference point.
* @param when Time; the future time for which to calculate the positions.
* @return the lanes and the position on the lanes where the GTU will be registered at the time, for the given position of
* the GTU.
* @throws GtuException when the vehicle is not on one of the lanes on which it is registered.
*/
Map fractionalPositions(RelativePosition relativePosition, Time when) throws GtuException;
/**
* Return the longitudinal position of a point relative to this GTU, relative to the center line of the Lane, as a fraction
* of the length of the lane. This is important when we want to see if two vehicles are next to each other and we compare an
* 'inner' and 'outer' curve.
* @param lane Lane; the position on this lane will be returned.
* @param relativePosition RelativePosition; the position on the vehicle relative to the reference point.
* @param when Time; the future time for which to calculate the positions.
* @return the fractional relative position on the lane at the given time.
* @throws GtuException when the vehicle is not on the given lane.
*/
double fractionalPosition(Lane lane, RelativePosition relativePosition, Time when) throws GtuException;
/**
* Add an event to the list of lane triggers scheduled for this GTU.
* @param lane Lane; the lane on which the event occurs
* @param event SimEventInterface<SimTimeDoubleUnit>; SimeEvent<SimTimeDoubleUnit> the event
*/
void addTrigger(Lane lane, SimEventInterface event);
/**
* Set distance over which the GTU should not change lane after being created.
* @param distance Length; distance over which the GTU should not change lane after being created
*/
void setNoLaneChangeDistance(Length distance);
/**
* Returns whether a lane change is allowed.
* @return whether a lane change is allowed
*/
boolean laneChangeAllowed();
/**
* This method returns the current desired speed of the GTU. This value is required often, so implementations can cache it.
* @return Speed; current desired speed
*/
Speed getDesiredSpeed();
/**
* This method returns the current car-following acceleration of the GTU. This value is required often, so implementations
* can cache it.
* @return Acceleration; current car-following acceleration
*/
Acceleration getCarFollowingAcceleration();
/**
* Returns the vehicle model.
* @return VehicleModel; vehicle model
*/
default VehicleModel getVehicleModel()
{
return VehicleModel.MINMAX;
}
/**
* The default implementation returns {@code true} if the deceleration is larger than a speed-dependent threshold given
* by:
*
* c0 * g(v) + c1 + c3*v^2
*
* where c0 = 0.2, c1 = 0.15 and c3 = 0.00025 (with c2 = 0 implicit) are empirically derived averages, and g(v) is 0 below
* 25 km/h or 1 otherwise, representing that the engine is disengaged at low speeds.
* @param when Time; time
* @return boolean; whether the braking lights are on
*/
default boolean isBrakingLightsOn(final Time when)
{
double v = getSpeed(when).si;
double a = getAcceleration(when).si;
return a < (v < 6.944 ? 0.0 : -0.2) - 0.15 * v - 0.00025 * v * v;
}
/**
* @param time Time; time to obtain the turn indicator status at
* @return the status of the turn indicator at the given time
*/
TurnIndicatorStatus getTurnIndicatorStatus(Time time);
/**
* Set the status of the turn indicator.
* @param turnIndicatorStatus TurnIndicatorStatus; the new status of the turn indicator.
* @throws GtuException when GTUType does not have a turn indicator
*/
void setTurnIndicatorStatus(TurnIndicatorStatus turnIndicatorStatus) throws GtuException;
}