LmrsData.java
package org.opentrafficsim.road.gtu.lane.tactical.util.lmrs;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable;
import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGtu;
import org.opentrafficsim.road.gtu.lane.tactical.DesireBased;
import org.opentrafficsim.road.gtu.lane.tactical.Synchronizable;
/**
* Keeps data for LMRS for a specific GTU.
* <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>
*/
public final class LmrsData implements DesireBased, Synchronizable
{
/** Form of synchronization. */
private final Synchronization synchronization;
/** Form of cooperation. */
private final Cooperation cooperation;
/** Form of gap-acceptance. */
private final GapAcceptance gapAcceptance;
/** Form of tail gating. */
private final Tailgating tailgating;
/** Most recent leaders. */
private final Set<String> leaders = new LinkedHashSet<>();
/** Current leaders. */
private final Set<String> tempLeaders = new LinkedHashSet<>();
/** Latest desire value for visualization. */
private final Map<Class<? extends Incentive>, Desire> desireMap = new LinkedHashMap<>();
/** Synchronization state. */
private Synchronizable.State synchronizationState = Synchronizable.State.NONE;
/** Vehicle that is being synchronized to. */
private String syncVehicle;
/** Whether the longitudinal control is human. */
private boolean humanLongitudinalControl = true;
/**
* @param synchronization Synchronization; synchronization
* @param cooperation Cooperation; cooperation
* @param gapAcceptance GapAcceptance; gap-acceptance
* @param tailgating Tailgating; tail gating
*/
public LmrsData(final Synchronization synchronization, final Cooperation cooperation, final GapAcceptance gapAcceptance,
final Tailgating tailgating)
{
this.synchronization = synchronization;
this.cooperation = cooperation;
this.gapAcceptance = gapAcceptance;
this.tailgating = tailgating;
}
/**
* Checks if the given leader is a new leader.
* @param gtu HeadwayGtu; gtu to check
* @return whether the gtu is a new leader
*/
boolean isNewLeader(final HeadwayGtu gtu)
{
this.tempLeaders.add(gtu.getId());
return !this.leaders.contains(gtu.getId());
}
/**
* Remembers the leaders of the current time step (those forwarded to isNewLeader()) for the next time step.
*/
void finalizeStep()
{
this.leaders.clear();
this.leaders.addAll(this.tempLeaders);
this.tempLeaders.clear();
}
/**
* Remembers the gtu that is synchronized to.
* @param gtu HeadwayGtu; gtu that is synchronized to
*/
void setSyncVehicle(final HeadwayGtu gtu)
{
this.syncVehicle = gtu == null ? null : gtu.getId();
}
/**
* Returns whether the provided gtu is the gtu that is synchronized to.
* @param gtu HeadwayGtu; gtu to inquiry
* @return whether the provided gtu is the gtu that is synchronized to
*/
boolean isSyncVehicle(final HeadwayGtu gtu)
{
return this.syncVehicle == null ? false : gtu.getId().equals(this.syncVehicle);
}
/**
* Returns the gtu from the set that is the current sync vehicle, or {@code null} of there is no sync vehicle or it is not
* in the set.
* @param adjLeaders PerceptionCollectable<HeadwayGtu,LaneBasedGtu>; leaders in adjacent lane
* @return gtu from the set that is the current sync vehicle
*/
HeadwayGtu getSyncVehicle(final PerceptionCollectable<HeadwayGtu, LaneBasedGtu> adjLeaders)
{
if (this.syncVehicle == null)
{
return null;
}
for (HeadwayGtu leader : adjLeaders)
{
if (leader.getId().equals(this.syncVehicle))
{
return leader;
}
}
return null;
}
/**
* Returns the synchronization.
* @return synchronization
*/
Synchronization getSynchronization()
{
return this.synchronization;
}
/**
* Returns the cooperation.
* @return cooperation
*/
Cooperation getCooperation()
{
return this.cooperation;
}
/**
* Return the gap-acceptance.
* @return gap-acceptance
*/
GapAcceptance getGapAcceptance()
{
return this.gapAcceptance;
}
/**
* Return the tail gating.
* @return gap-acceptance
*/
Tailgating getTailgating()
{
return this.tailgating;
}
/** {@inheritDoc} */
@Override
public Desire getLatestDesire(final Class<? extends Incentive> incentiveClass)
{
return this.desireMap.get(incentiveClass);
}
/**
* Returns the desire map.
* @return Map<Class<? extends Incentive>, Desire>; desire map
*/
Map<Class<? extends Incentive>, Desire> getDesireMap()
{
return this.desireMap;
}
/**
* Sets the synchronization state.
* @param synchronizationState Synchronizable.State; synchronization step
*/
void setSynchronizationState(final Synchronizable.State synchronizationState)
{
this.synchronizationState = synchronizationState;
}
/** {@inheritDoc} */
@Override
public Synchronizable.State getSynchronizationState()
{
return this.synchronizationState;
}
/**
* @return humanLongitudinalControl.
*/
boolean isHumanLongitudinalControl()
{
return this.humanLongitudinalControl;
}
/**
* @param humanLongitudinalControl boolean; set humanLongitudinalControl.
*/
public void setHumanLongitudinalControl(final boolean humanLongitudinalControl)
{
this.humanLongitudinalControl = humanLongitudinalControl;
}
/** {@inheritDoc} */
@Override
public String toString()
{
return "LmrsData [synchronization=" + this.synchronization + ", leaders=" + this.leaders + ", tempLeaders="
+ this.tempLeaders + ", syncVehicle=" + this.syncVehicle + "]";
}
}