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://github.com/peter-knoppers">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
59       * @param cooperation cooperation
60       * @param gapAcceptance gap-acceptance
61       * @param 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 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 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 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 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     @Override
171     public Desire getLatestDesire(final Class<? extends Incentive> incentiveClass)
172     {
173         return this.desireMap.get(incentiveClass);
174     }
175 
176     /**
177      * Returns the desire map.
178      * @return desire map
179      */
180     Map<Class<? extends Incentive>, Desire> getDesireMap()
181     {
182         return this.desireMap;
183     }
184 
185     /**
186      * Sets the synchronization state.
187      * @param synchronizationState Synchronizable.State; synchronization step
188      */
189     void setSynchronizationState(final Synchronizable.State synchronizationState)
190     {
191         this.synchronizationState = synchronizationState;
192     }
193 
194     @Override
195     public Synchronizable.State getSynchronizationState()
196     {
197         return this.synchronizationState;
198     }
199 
200     /**
201      * @return humanLongitudinalControl.
202      */
203     boolean isHumanLongitudinalControl()
204     {
205         return this.humanLongitudinalControl;
206     }
207 
208     /**
209      * @param humanLongitudinalControl set humanLongitudinalControl.
210      */
211     public void setHumanLongitudinalControl(final boolean humanLongitudinalControl)
212     {
213         this.humanLongitudinalControl = humanLongitudinalControl;
214     }
215 
216     @Override
217     public String toString()
218     {
219         return "LmrsData [synchronization=" + this.synchronization + ", leaders=" + this.leaders + ", tempLeaders="
220                 + this.tempLeaders + ", syncVehicle=" + this.syncVehicle + "]";
221     }
222 
223 }