View Javadoc
1   package org.opentrafficsim.road.gtu.lane.tactical.cacc;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import org.opentrafficsim.core.gtu.GTU;
7   import org.opentrafficsim.core.network.LateralDirectionality;
8   
9   import nl.tudelft.simulation.dsol.SimRuntimeException;
10  
11  /**
12   * Platoon meta data.
13   * <p>
14   * Copyright (c) 2013-2017 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
15   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
16   * <p>
17   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 22 okt. 2018 <br>
18   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
19   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
20   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
21   */
22  public class Platoon
23  {
24  
25      /** List of GTUs. */
26      private final List<String> gtuList = new ArrayList<>();
27  
28      /** Lane change direction. */
29      private LateralDirectionality laneChangeDir = LateralDirectionality.NONE;
30  
31      /** List of changed GTUs. */
32      private List<String> changedGtus = new ArrayList<>();
33  
34      /**
35       * Adds a GTU to the platoon. This is done by a generator listener.
36       * @param id String; GTU id
37       */
38      public void addGtu(final String id)
39      {
40          this.gtuList.add(id);
41      }
42  
43      /**
44       * Returns the size of the platoon.
45       * @return int; size of the platoon
46       */
47      public int size()
48      {
49          return this.gtuList.size();
50      }
51  
52      /**
53       * Returns the GTU id of the index
54       * @param index int; index position of gtuList
55       * @return String; id of gtu on index position; NULL is none?
56       */
57      public String getId(int index)
58      {
59          return this.gtuList.get(index);
60      }
61  
62      /**
63       * Add a lane change as it's finished. This will reset the lane change when all GTUs in the platoon changed lane.
64       * @param gtu GTU; gtu
65       */
66      public void addLaneChange(final GTU gtu)
67      {
68          this.changedGtus.add(gtu.getId());
69          if (this.changedGtus.size() == size())
70          {
71              // all GTUs in platoon changed
72              try
73              {
74                  gtu.getSimulator().scheduleEventNow(this, this, "endLaneChangeProcess", null);
75              }
76              catch (SimRuntimeException exception)
77              {
78                  throw new RuntimeException(exception);
79              }
80          }
81      }
82  
83      /**
84       * End lane change process.
85       */
86      @SuppressWarnings("unused")
87      private void endLaneChangeProcess()
88      {
89          this.laneChangeDir = LateralDirectionality.NONE;
90          this.changedGtus.clear();
91      }
92  
93      /**
94       * Returns whether the platoon is ready for a lane change (i.e. not in the process of a lane change).
95       * @return boolean; whether the platoon is ready for a lane change (i.e. not in the process of a lane change)
96       */
97      public boolean canInitiateLaneChangeProcess()
98      {
99          return this.laneChangeDir.isNone();
100     }
101 
102     /**
103      * Initiates a lane change.
104      * @param laneChangeDirection LateralDirectionality; direction of the lane change
105      */
106     public void initiateLaneChange(final LateralDirectionality laneChangeDirection)
107     {
108         this.laneChangeDir = laneChangeDirection;
109     }
110 
111     /**
112      * Returns the index of the GTU in the platoon, with the leader {@code 0}.
113      * @param gtuId String; GTU id
114      * @return int; index of the GTU in the platoon, with the leader {@code 0}
115      */
116     public int getIndex(final String gtuId)
117     {
118         return this.gtuList.indexOf(gtuId);
119     }
120 
121     /**
122      * Returns whether the GTU is the platoon.
123      * @param gtuId String; GTU id
124      * @return boolean; whether the GTU is the platoon
125      */
126     public boolean isInPlatoon(final String gtuId)
127     {
128         return this.gtuList.contains(gtuId);
129     }
130 
131     /**
132      * Returns the direction in which the GTU should change lane.
133      * @param gtuId String; GTU id
134      * @return LateralDirectionality; direction to change to, or {@code NONE}
135      */
136     public LateralDirectionality shouldChangeLane(final String gtuId)
137     {
138         if (this.changedGtus.isEmpty()) // No trucks have changed yet
139         {
140             return size() == (getIndex(gtuId) + 1) ? this.laneChangeDir : LateralDirectionality.NONE;
141         }
142         else if (this.changedGtus.contains(gtuId))
143         {
144             return LateralDirectionality.NONE;
145         }
146         else
147         {
148             return this.laneChangeDir;
149         }
150 
151     }
152 
153     /**
154      * Returns true when a lane change is in progress.
155      * @return boolean; whether a lane change is currently in progress
156      */
157     public boolean laneChangeInProgress()
158     {
159         return !this.changedGtus.isEmpty();
160     }
161 
162     /**
163      * Number of gtus that have changed lanes.
164      * @return int; number of gtus changed lanes currently
165      */
166     public int numberOfChanged()
167     {
168         return this.changedGtus.size();
169     }
170 
171 }