View Javadoc
1   package org.opentrafficsim.road.gtu.tactical.util.lmrs;
2   
3   import java.util.LinkedHashSet;
4   import java.util.Set;
5   
6   import org.djunits.value.vdouble.scalar.Speed;
7   import org.opentrafficsim.base.TimeStampedObject;
8   import org.opentrafficsim.core.gtu.TurnIndicatorStatus;
9   import org.opentrafficsim.road.gtu.LaneBasedGtu;
10  import org.opentrafficsim.road.gtu.perception.PerceptionCollectable;
11  import org.opentrafficsim.road.gtu.perception.object.PerceivedGtu;
12  import org.opentrafficsim.road.gtu.tactical.Synchronizable;
13  import org.opentrafficsim.road.gtu.tactical.WithDesiredSpeed;
14  
15  /**
16   * Keeps data for LMRS for a specific GTU.
17   * <p>
18   * Copyright (c) 2013-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
19   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
20   * </p>
21   * @author Alexander Verbraeck
22   * @author Peter Knoppers
23   * @author Wouter Schakel
24   */
25  public final class LmrsData implements Synchronizable, WithDesiredSpeed
26  {
27  
28      /** Form of synchronization. */
29      private final Synchronization synchronization;
30  
31      /** Form of cooperation. */
32      private final Cooperation cooperation;
33  
34      /** Form of gap-acceptance. */
35      private final GapAcceptance gapAcceptance;
36  
37      /** Form of tail gating. */
38      private final Tailgating tailgating;
39  
40      /** Most recent leaders. */
41      private final Set<String> leaders = new LinkedHashSet<>();
42  
43      /** Current leaders. */
44      private final Set<String> tempLeaders = new LinkedHashSet<>();
45  
46      /** Synchronization state. */
47      private Synchronizable.State synchronizationState = Synchronizable.State.NONE;
48  
49      /** Desired speed. */
50      private Speed desiredSpeed;
51  
52      /** Vehicle that is being synchronized to. */
53      private String syncVehicle;
54  
55      /** Whether the longitudinal control is human. */
56      private boolean humanLongitudinalControl = true;
57  
58      /** Turn indicator for lane change. */
59      private TimeStampedObject<TurnIndicatorStatus> laneChangeIndicator;
60  
61      /**
62       * Constructor.
63       * @param synchronization synchronization
64       * @param cooperation cooperation
65       * @param gapAcceptance gap-acceptance
66       * @param tailgating tail gating
67       */
68      public LmrsData(final Synchronization synchronization, final Cooperation cooperation, final GapAcceptance gapAcceptance,
69              final Tailgating tailgating)
70      {
71          this.synchronization = synchronization;
72          this.cooperation = cooperation;
73          this.gapAcceptance = gapAcceptance;
74          this.tailgating = tailgating;
75      }
76  
77      /**
78       * Remembers the leaders of the current time step (those forwarded to isNewLeader()) for the next time step.
79       */
80      void initStep()
81      {
82          this.leaders.clear();
83          this.leaders.addAll(this.tempLeaders);
84          this.tempLeaders.clear();
85          this.synchronizationState = Synchronizable.State.NONE;
86      }
87  
88      /**
89       * Checks if the given leader is a new leader. It should be a current leader.
90       * @param gtu gtu to check
91       * @return whether the gtu is a new leader
92       */
93      boolean isNewLeader(final PerceivedGtu gtu)
94      {
95          this.tempLeaders.add(gtu.getId());
96          return !this.leaders.contains(gtu.getId());
97      }
98  
99      /**
100      * Remembers the gtu that is synchronized to.
101      * @param gtu gtu that is synchronized to
102      */
103     void setSyncVehicle(final PerceivedGtu gtu)
104     {
105         this.syncVehicle = gtu == null ? null : gtu.getId();
106     }
107 
108     /**
109      * Returns whether the provided gtu is the gtu that is synchronized to.
110      * @param gtu gtu to inquiry
111      * @return whether the provided gtu is the gtu that is synchronized to
112      */
113     boolean isSyncVehicle(final PerceivedGtu gtu)
114     {
115         return this.syncVehicle == null ? false : gtu.getId().equals(this.syncVehicle);
116     }
117 
118     /**
119      * 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
120      * in the set.
121      * @param adjLeaders leaders in adjacent lane
122      * @return gtu from the set that is the current sync vehicle
123      */
124     PerceivedGtu getSyncVehicle(final PerceptionCollectable<PerceivedGtu, LaneBasedGtu> adjLeaders)
125     {
126         if (this.syncVehicle == null)
127         {
128             return null;
129         }
130         for (PerceivedGtu leader : adjLeaders)
131         {
132             if (leader.getId().equals(this.syncVehicle))
133             {
134                 return leader;
135             }
136         }
137         return null;
138     }
139 
140     /**
141      * Returns the synchronization.
142      * @return synchronization
143      */
144     Synchronization getSynchronization()
145     {
146         return this.synchronization;
147     }
148 
149     /**
150      * Returns the cooperation.
151      * @return cooperation
152      */
153     Cooperation getCooperation()
154     {
155         return this.cooperation;
156     }
157 
158     /**
159      * Return the gap-acceptance.
160      * @return gap-acceptance
161      */
162     GapAcceptance getGapAcceptance()
163     {
164         return this.gapAcceptance;
165     }
166 
167     /**
168      * Return the tail gating.
169      * @return gap-acceptance
170      */
171     Tailgating getTailgating()
172     {
173         return this.tailgating;
174     }
175 
176     /**
177      * Sets the synchronization state, but only if the given value is more critical than any previous. The order is NONE,
178      * COOPERATING, SYNCHRONIZING, INDICATING.
179      * @param synchronizationState Synchronizable.State; synchronization step
180      */
181     void setSynchronizationState(final Synchronizable.State synchronizationState)
182     {
183         if (synchronizationState.compareTo(this.synchronizationState) > 0)
184         {
185             this.synchronizationState = synchronizationState;
186         }
187     }
188 
189     @Override
190     public Synchronizable.State getSynchronizationState()
191     {
192         return this.synchronizationState;
193     }
194 
195     /**
196      * Set desired speed.
197      * @param desiredSpeed desired speed
198      */
199     public void setDesiredSpeed(final Speed desiredSpeed)
200     {
201         this.desiredSpeed = desiredSpeed;
202     }
203 
204     @Override
205     public Speed getDesiredSpeed()
206     {
207         return this.desiredSpeed;
208     }
209 
210     /**
211      * Return whether control is human.
212      * @return humanLongitudinalControl.
213      */
214     boolean isHumanLongitudinalControl()
215     {
216         return this.humanLongitudinalControl;
217     }
218 
219     /**
220      * Set human longitudinal control.
221      * @param humanLongitudinalControl set humanLongitudinalControl.
222      */
223     public void setHumanLongitudinalControl(final boolean humanLongitudinalControl)
224     {
225         this.humanLongitudinalControl = humanLongitudinalControl;
226     }
227 
228     /**
229      * Return initiated lane change.
230      * @return initiated lane change
231      */
232     public TimeStampedObject<TurnIndicatorStatus> getInitiatedLaneChange()
233     {
234         return this.laneChangeIndicator;
235     }
236 
237     /**
238      * Set turn indicator for lane change.
239      * @param laneChangeIndicator indicator for lane change
240      */
241     @SuppressWarnings("hiddenfield")
242     public void setInitiatedLaneChange(final TimeStampedObject<TurnIndicatorStatus> laneChangeIndicator)
243     {
244         this.laneChangeIndicator = laneChangeIndicator;
245     }
246 
247     @Override
248     public String toString()
249     {
250         return "LmrsData [synchronization=" + this.synchronization + ", leaders=" + this.leaders + ", tempLeaders="
251                 + this.tempLeaders + ", syncVehicle=" + this.syncVehicle + "]";
252     }
253 
254 }