View Javadoc
1   package org.opentrafficsim.road.gtu.lane.tactical.util.lmrs;
2   
3   import java.util.LinkedHashMap;
4   import java.util.LinkedHashSet;
5   import java.util.Map;
6   import java.util.Set;
7   
8   import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
9   import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable;
10  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGtu;
11  import org.opentrafficsim.road.gtu.lane.tactical.DesireBased;
12  import org.opentrafficsim.road.gtu.lane.tactical.Synchronizable;
13  
14  /**
15   * Keeps data for LMRS for a specific GTU.
16   * <p>
17   * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
18   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
19   * </p>
20   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
21   * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
22   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
23   */
24  public final class LmrsData implements DesireBased, Synchronizable
25  {
26  
27      /** Form of synchronization. */
28      private final Synchronization synchronization;
29  
30      /** Form of cooperation. */
31      private final Cooperation cooperation;
32  
33      /** Form of gap-acceptance. */
34      private final GapAcceptance gapAcceptance;
35  
36      /** Form of tail gating. */
37      private final Tailgating tailgating;
38  
39      /** Most recent leaders. */
40      private final Set<String> leaders = new LinkedHashSet<>();
41  
42      /** Current leaders. */
43      private final Set<String> tempLeaders = new LinkedHashSet<>();
44  
45      /** Latest desire value for visualization. */
46      private final Map<Class<? extends Incentive>, Desire> desireMap = new LinkedHashMap<>();
47  
48      /** Synchronization state. */
49      private Synchronizable.State synchronizationState = Synchronizable.State.NONE;
50  
51      /** Vehicle that is being synchronized to. */
52      private String syncVehicle;
53  
54      /** Whether the longitudinal control is human. */
55      private boolean humanLongitudinalControl = true;
56  
57      /**
58       * @param synchronization Synchronization; synchronization
59       * @param cooperation Cooperation; cooperation
60       * @param gapAcceptance GapAcceptance; gap-acceptance
61       * @param tailgating Tailgating; tail gating
62       */
63      public LmrsData(final Synchronization synchronization, final Cooperation cooperation, final GapAcceptance gapAcceptance,
64              final Tailgating tailgating)
65      {
66          this.synchronization = synchronization;
67          this.cooperation = cooperation;
68          this.gapAcceptance = gapAcceptance;
69          this.tailgating = tailgating;
70      }
71  
72      /**
73       * Checks if the given leader is a new leader.
74       * @param gtu HeadwayGtu; gtu to check
75       * @return whether the gtu is a new leader
76       */
77      boolean isNewLeader(final HeadwayGtu gtu)
78      {
79          this.tempLeaders.add(gtu.getId());
80          return !this.leaders.contains(gtu.getId());
81      }
82  
83      /**
84       * Remembers the leaders of the current time step (those forwarded to isNewLeader()) for the next time step.
85       */
86      void finalizeStep()
87      {
88          this.leaders.clear();
89          this.leaders.addAll(this.tempLeaders);
90          this.tempLeaders.clear();
91      }
92  
93      /**
94       * Remembers the gtu that is synchronized to.
95       * @param gtu HeadwayGtu; gtu that is synchronized to
96       */
97      void setSyncVehicle(final HeadwayGtu gtu)
98      {
99          this.syncVehicle = gtu == null ? null : gtu.getId();
100     }
101 
102     /**
103      * Returns whether the provided gtu is the gtu that is synchronized to.
104      * @param gtu HeadwayGtu; gtu to inquiry
105      * @return whether the provided gtu is the gtu that is synchronized to
106      */
107     boolean isSyncVehicle(final HeadwayGtu gtu)
108     {
109         return this.syncVehicle == null ? false : gtu.getId().equals(this.syncVehicle);
110     }
111 
112     /**
113      * 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
114      * in the set.
115      * @param adjLeaders PerceptionCollectable&lt;HeadwayGtu,LaneBasedGtu&gt;; leaders in adjacent lane
116      * @return gtu from the set that is the current sync vehicle
117      */
118     HeadwayGtu getSyncVehicle(final PerceptionCollectable<HeadwayGtu, LaneBasedGtu> adjLeaders)
119     {
120         if (this.syncVehicle == null)
121         {
122             return null;
123         }
124         for (HeadwayGtu leader : adjLeaders)
125         {
126             if (leader.getId().equals(this.syncVehicle))
127             {
128                 return leader;
129             }
130         }
131         return null;
132     }
133 
134     /**
135      * Returns the synchronization.
136      * @return synchronization
137      */
138     Synchronization getSynchronization()
139     {
140         return this.synchronization;
141     }
142 
143     /**
144      * Returns the cooperation.
145      * @return cooperation
146      */
147     Cooperation getCooperation()
148     {
149         return this.cooperation;
150     }
151 
152     /**
153      * Return the gap-acceptance.
154      * @return gap-acceptance
155      */
156     GapAcceptance getGapAcceptance()
157     {
158         return this.gapAcceptance;
159     }
160 
161     /**
162      * Return the tail gating.
163      * @return gap-acceptance
164      */
165     Tailgating getTailgating()
166     {
167         return this.tailgating;
168     }
169 
170     /** {@inheritDoc} */
171     @Override
172     public Desire getLatestDesire(final Class<? extends Incentive> incentiveClass)
173     {
174         return this.desireMap.get(incentiveClass);
175     }
176 
177     /**
178      * Returns the desire map.
179      * @return Map&lt;Class&lt;? extends Incentive&gt;, Desire&gt;; desire map
180      */
181     Map<Class<? extends Incentive>, Desire> getDesireMap()
182     {
183         return this.desireMap;
184     }
185 
186     /**
187      * Sets the synchronization state.
188      * @param synchronizationState Synchronizable.State; synchronization step
189      */
190     void setSynchronizationState(final Synchronizable.State synchronizationState)
191     {
192         this.synchronizationState = synchronizationState;
193     }
194 
195     /** {@inheritDoc} */
196     @Override
197     public Synchronizable.State getSynchronizationState()
198     {
199         return this.synchronizationState;
200     }
201 
202     /**
203      * @return humanLongitudinalControl.
204      */
205     boolean isHumanLongitudinalControl()
206     {
207         return this.humanLongitudinalControl;
208     }
209 
210     /**
211      * @param humanLongitudinalControl boolean; set humanLongitudinalControl.
212      */
213     public void setHumanLongitudinalControl(final boolean humanLongitudinalControl)
214     {
215         this.humanLongitudinalControl = humanLongitudinalControl;
216     }
217 
218     /** {@inheritDoc} */
219     @Override
220     public String toString()
221     {
222         return "LmrsData [synchronization=" + this.synchronization + ", leaders=" + this.leaders + ", tempLeaders="
223                 + this.tempLeaders + ", syncVehicle=" + this.syncVehicle + "]";
224     }
225 
226 }