package org.opentrafficsim.road.gtu.lane; import java.io.Serializable; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.djunits.value.vdouble.scalar.Acceleration; import org.djunits.value.vdouble.scalar.Length; import org.djunits.value.vdouble.scalar.Speed; import org.djutils.immutablecollections.Immutable; import org.djutils.immutablecollections.ImmutableHashSet; import org.djutils.immutablecollections.ImmutableLinkedHashMap; import org.djutils.immutablecollections.ImmutableMap; import org.djutils.immutablecollections.ImmutableSet; import org.opentrafficsim.core.dsol.OTSSimulatorInterface; import org.opentrafficsim.core.gtu.GTUException; import org.opentrafficsim.core.gtu.GTUType; import org.opentrafficsim.core.gtu.RelativePosition; import org.opentrafficsim.core.gtu.RelativePosition.TYPE; import org.opentrafficsim.core.network.Node; import org.opentrafficsim.core.network.OTSNetwork; import org.opentrafficsim.core.network.route.Route; import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner; import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory; import org.opentrafficsim.road.network.lane.DirectedLanePosition; import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface; /** * Augments the AbstractLaneBasedIndividualGTU with a LaneBasedIndividualCarBuilder and animation support *

* Copyright (c) 2013-2019 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 Oct 22, 2014
* @author Alexander Verbraeck * @author Peter Knoppers */ public class LaneBasedIndividualGTU extends AbstractLaneBasedIndividualGTU { /** */ private static final long serialVersionUID = 20141025L; /** Sensing positions. */ private final Map relativePositions = new HashMap<>(); /** cached front. */ private final RelativePosition frontPos; /** cached rear. */ private final RelativePosition rearPos; /** contour points. */ private final Set contourPoints = new HashSet<>(); /** * Construct a new LaneBasedIndividualGTU. * @param id String; the id of the GTU * @param gtuType GTUType; the type of GTU, e.g. TruckType, CarType, BusType * @param length Length; the maximum length of the GTU (parallel with driving direction) * @param width Length; the maximum width of the GTU (perpendicular to driving direction) * @param maximumSpeed Speed;the maximum speed of the GTU (in the driving direction) * @param front Length; front distance relative to the reference position * @param simulator OTSSimulatorInterface; the simulator * @param network OTSNetwork; the network that the GTU is initially registered in * @throws GTUException when a parameter is invalid */ @SuppressWarnings("checkstyle:parameternumber") public LaneBasedIndividualGTU(final String id, final GTUType gtuType, final Length length, final Length width, final Speed maximumSpeed, final Length front, final OTSSimulatorInterface simulator, final OTSNetwork network) throws GTUException { this(id, gtuType, length, width, maximumSpeed, front, Length.ZERO, simulator, network); } /** * Construct a new LaneBasedIndividualGTU. * @param id String; the id of the GTU * @param gtuType GTUType; the type of GTU, e.g. TruckType, CarType, BusType * @param length Length; the maximum length of the GTU (parallel with driving direction) * @param width Length; the maximum width of the GTU (perpendicular to driving direction) * @param maximumSpeed Speed;the maximum speed of the GTU (in the driving direction) * @param front Length; front distance relative to the reference position * @param centerOfGravity Length; distance from the center of gravity to the reference position * @param simulator OTSSimulatorInterface; the simulator * @param network OTSNetwork; the network that the GTU is initially registered in * @throws GTUException when a parameter is invalid */ @SuppressWarnings("checkstyle:parameternumber") public LaneBasedIndividualGTU(final String id, final GTUType gtuType, final Length length, final Length width, final Speed maximumSpeed, final Length front, final Length centerOfGravity, final OTSSimulatorInterface simulator, final OTSNetwork network) throws GTUException { super(id, gtuType, length, width, maximumSpeed, simulator, network); // sensor positions. Length dy2 = getWidth().multiplyBy(0.5); this.frontPos = new RelativePosition(front, Length.ZERO, Length.ZERO, RelativePosition.FRONT); this.relativePositions.put(RelativePosition.FRONT, this.frontPos); this.rearPos = new RelativePosition(front.minus(getLength()), Length.ZERO, Length.ZERO, RelativePosition.REAR); this.relativePositions.put(RelativePosition.REAR, this.rearPos); this.relativePositions.put(RelativePosition.REFERENCE, RelativePosition.REFERENCE_POSITION); this.relativePositions.put(RelativePosition.CENTER, new RelativePosition(Length.ZERO, Length.ZERO, Length.ZERO, RelativePosition.CENTER)); this.relativePositions.put(RelativePosition.CENTER_GRAVITY, new RelativePosition(centerOfGravity, Length.ZERO, Length.ZERO, RelativePosition.CENTER_GRAVITY)); // Contour positions. For now, a rectangle with the four corners. for (int i = -1; i <= 1; i += 2) { Length x = i < 0 ? front.minus(getLength()) : front; for (int j = -1; j <= 1; j += 2) { this.contourPoints.add(new RelativePosition(x, dy2.multiplyBy(j), Length.ZERO, RelativePosition.CONTOUR)); } } } /** {@inheritDoc} */ @Override public final RelativePosition getFront() { return this.frontPos; } /** {@inheritDoc} */ @Override public final RelativePosition getRear() { return this.rearPos; } /** {@inheritDoc} */ @Override public final RelativePosition getCenter() { return this.relativePositions.get(RelativePosition.CENTER); } /** {@inheritDoc} */ @Override public final ImmutableMap getRelativePositions() { return new ImmutableLinkedHashMap<>(this.relativePositions, Immutable.WRAP); } /** {@inheritDoc} */ @Override public final ImmutableSet getContourPoints() { return new ImmutableHashSet<>(this.contourPoints, Immutable.WRAP); } /** {@inheritDoc} */ @Override public final String toString() { return "LaneBasedIndividualGTU [id=" + getId() + "]"; } /** * Build an individual car and use easy setter methods to instantiate the car. Typical use looks like: * *

     * LaneBasedIndividualCar<String> car = new LaneBasedIndividualCarBuilder<String>().setId("Car:"+nr)
     *    .setLength(new Length(4.0, METER))....build(); 
     *    
     * or
     * 
     * LaneBasedIndividualCarBuilder<String> carBuilder = new LaneBasedIndividualCarBuilder<String>();
     * carBuilder.setId("Car:"+nr);
     * carBuilder.setLength(new Length(4.0, METER));
     * carBuilder.setWidth(new Length(1.8, METER));
     * ...
     * LaneBasedIndividualCar<String> car = carBuilder.build();
     * 
*

* Copyright (c) 2013-2019 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 Feb 3, 2015
* @author Alexander Verbraeck */ @SuppressWarnings("checkstyle:hiddenfield") public static class LaneBasedIndividualCarBuilder implements Serializable { /** */ private static final long serialVersionUID = 20160000L; /** The id of the GTU. */ private String id = null; /** The type of GTU, e.g. TruckType, CarType, BusType. */ private GTUType gtuType = null; /** The initial positions of the car on one or more lanes. */ private Set initialLongitudinalPositions = null; /** The initial speed of the car on the lane. */ private Speed initialSpeed = null; /** The length of the GTU (parallel with driving direction). */ private Length length = null; /** The width of the GTU (perpendicular to driving direction). */ private Length width = null; /** The maximum speed of the GTU (in the driving direction). */ private Speed maximumSpeed = null; /** Maximum acceleration. */ private Acceleration maximumAcceleration = null; /** Maximum deceleration (a negative value). */ private Acceleration maximumDeceleration = null; /** The distance of the front relative to the reference position. */ private Length front = null; /** The simulator. */ private OTSSimulatorInterface simulator = null; /** Network. */ private OTSNetwork network = null; /** * @param id String; set id * @return the class itself for chaining the setters */ public final LaneBasedIndividualCarBuilder setId(final String id) { this.id = id; return this; } /** * @param gtuType GTUType; set gtuType * @return the class itself for chaining the setters */ public final LaneBasedIndividualCarBuilder setGtuType(final GTUType gtuType) { this.gtuType = gtuType; return this; } /** * @param initialLongitudinalPositions Set<DirectedLanePosition>; set initialLongitudinalPositions * @return the class itself for chaining the setters */ public final LaneBasedIndividualCarBuilder setInitialLongitudinalPositions( final Set initialLongitudinalPositions) { this.initialLongitudinalPositions = initialLongitudinalPositions; return this; } /** * @param initialSpeed Speed; set initialSpeed * @return the class itself for chaining the setters */ public final LaneBasedIndividualCarBuilder setInitialSpeed(final Speed initialSpeed) { this.initialSpeed = initialSpeed; return this; } /** * @param length Length; set length * @return the class itself for chaining the setters */ public final LaneBasedIndividualCarBuilder setLength(final Length length) { this.length = length; return this; } /** * @param width Length; set width * @return the class itself for chaining the setters */ public final LaneBasedIndividualCarBuilder setWidth(final Length width) { this.width = width; return this; } /** * @param maximumSpeed Speed; set maximumSpeed * @return the class itself for chaining the setters */ public final LaneBasedIndividualCarBuilder setMaximumSpeed(final Speed maximumSpeed) { this.maximumSpeed = maximumSpeed; return this; } /** * @param maximumAcceleration Acceleration; maximum acceleration * @return the class itself for chaining the setters */ public final LaneBasedIndividualCarBuilder setMaximumAcceleration(final Acceleration maximumAcceleration) { this.maximumAcceleration = maximumAcceleration; return this; } /** * @param maximumDeceleration Acceleration; maximum deceleration (a negative value) * @return the class itself for chaining the setters */ public final LaneBasedIndividualCarBuilder setMaximumDeceleration(final Acceleration maximumDeceleration) { this.maximumDeceleration = maximumDeceleration; return this; } /** * @param simulator OTSSimulatorInterface; set simulator * @return the class itself for chaining the setters */ public final LaneBasedIndividualCarBuilder setSimulator(final OTSSimulatorInterface simulator) { this.simulator = simulator; return this; } /** * @param front Length; distance of the front relative to the reference point * @return the class itself for chaining the setters */ public final LaneBasedIndividualCarBuilder setFront(final Length front) { this.front = front; return this; } /** * @param network OTSNetwork; set network * @return the class itself for chaining the setters */ public final LaneBasedIndividualCarBuilder setNetwork(final OTSNetwork network) { this.network = network; return this; } /** * @return id. */ public final String getId() { return this.id; } /** * @return gtuType. */ public final GTUType getGtuType() { return this.gtuType; } /** * @return initialLongitudinalPositions. */ public final Set getInitialLongitudinalPositions() { return this.initialLongitudinalPositions; } /** * @return initialSpeed. */ public final Speed getInitialSpeed() { return this.initialSpeed; } /** * @return length. */ public final Length getLength() { return this.length; } /** * @return width. */ public final Length getWidth() { return this.width; } /** * @return maximumSpeed. */ public final Speed getMaximumSpeed() { return this.maximumSpeed; } /** * @return simulator. */ public final DEVSSimulatorInterface.TimeDoubleUnit getSimulator() { return this.simulator; } /** * @return network */ public final OTSNetwork getNetwork() { return this.network; } /** * Build one LaneBasedIndividualCar. * @param laneBasedStrategicalPlannerFactory LaneBasedStrategicalPlannerFactory<? extends * LaneBasedStrategicalPlanner>; LaneBasedStrategicalPlannerFactory<? extends * LaneBasedStrategicalPlanner>; LaneBasedStrategicalPlannerFactory<? extends * LaneBasedStrategicalPlanner>; LaneBasedStrategicalPlannerFactory<? extends * LaneBasedStrategicalPlanner>; factory for the strategical planner * @param route Route; route * @param origin Node; origin * @param destination Node; destination * @return the built Car with the set properties * @throws Exception when not all required values have been set */ public final LaneBasedIndividualGTU build( final LaneBasedStrategicalPlannerFactory< ? extends LaneBasedStrategicalPlanner> laneBasedStrategicalPlannerFactory, final Route route, final Node origin, final Node destination) throws Exception { if (null == this.id || null == this.gtuType || null == this.initialLongitudinalPositions || null == this.initialSpeed || null == this.length || null == this.width || null == this.maximumSpeed || null == this.maximumAcceleration || null == this.maximumDeceleration || null == this.front || null == this.simulator || null == this.network) { // TODO Should throw a more specific Exception type throw new GTUException("factory settings incomplete"); } LaneBasedIndividualGTU gtu = new LaneBasedIndividualGTU(this.id, this.gtuType, this.length, this.width, this.maximumSpeed, this.front, this.simulator, this.network); gtu.setMaximumAcceleration(this.maximumAcceleration); gtu.setMaximumDeceleration(this.maximumDeceleration); gtu.init(laneBasedStrategicalPlannerFactory.create(gtu, route, origin, destination), this.initialLongitudinalPositions, this.initialSpeed); return gtu; } /** {@inheritDoc} */ @Override public final String toString() { return "LaneBasedIndividualCarBuilder [id=" + this.id + ", gtuType=" + this.gtuType + ", initialLongitudinalPositions=" + this.initialLongitudinalPositions + ", initialSpeed=" + this.initialSpeed + ", length=" + this.length + ", width=" + this.width + ", maximumSpeed=" + this.maximumSpeed + ", strategicalPlanner=" + "]"; } } }