1   package org.opentrafficsim.road.gtu.lane.tactical.util.lmrs;
2   
3   import static org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance.egoAcceleration;
4   
5   import org.djunits.unit.AccelerationUnit;
6   import org.djunits.value.vdouble.scalar.Acceleration;
7   import org.djunits.value.vdouble.scalar.Speed;
8   import org.opentrafficsim.base.parameters.ParameterException;
9   import org.opentrafficsim.base.parameters.ParameterTypes;
10  import org.opentrafficsim.base.parameters.Parameters;
11  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
12  import org.opentrafficsim.core.network.LateralDirectionality;
13  import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
14  import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
15  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTU;
16  import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
17  import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  public interface GapAcceptance
31  {
32  
33      
34      GapAcceptance INFORMED = new GapAcceptance()
35      {
36  
37          @Override
38          public boolean acceptGap(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
39                  final CarFollowingModel cfm, final double desire, final Speed ownSpeed, final Acceleration ownAcceleration,
40                  final LateralDirectionality lat) throws ParameterException, OperationalPlanException
41          {
42              NeighborsPerception neighbors = perception.getPerceptionCategory(NeighborsPerception.class);
43              if (neighbors.isGtuAlongside(lat))
44              {
45                  
46                  return false;
47              }
48  
49              
50              
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64              Acceleration b = params.getParameter(ParameterTypes.B);
65              Acceleration aFollow = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
66              for (HeadwayGTU follower : neighbors.getFirstFollowers(lat))
67              {
68                  if (follower.getSpeed().gt0() || follower.getAcceleration().gt0() || follower.getDistance().si < 1.0)
69                  {
70                      Acceleration a = LmrsUtil.singleAcceleration(follower.getDistance(), follower.getSpeed(), ownSpeed, desire,
71                              follower.getParameters(), follower.getSpeedLimitInfo(), follower.getCarFollowingModel());
72                      aFollow = Acceleration.min(aFollow, a);
73                  }
74              }
75  
76              Acceleration aSelf = egoAcceleration(perception, params, sli, cfm, desire, ownSpeed, lat);
77              Acceleration threshold = b.multiplyBy(-desire);
78              return aFollow.ge(threshold) && aSelf.ge(threshold) && ownAcceleration.ge(threshold);
79          }
80  
81          
82          @Override
83          public String toString()
84          {
85              return "INFORMED";
86          }
87  
88      };
89  
90      
91      GapAcceptance EGO_HEADWAY = new GapAcceptance()
92      {
93  
94          @Override
95          public boolean acceptGap(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
96                  final CarFollowingModel cfm, final double desire, final Speed ownSpeed, final Acceleration ownAcceleration,
97                  final LateralDirectionality lat) throws ParameterException, OperationalPlanException
98          {
99              NeighborsPerception neigbors = perception.getPerceptionCategory(NeighborsPerception.class);
100             if (neigbors.isGtuAlongside(lat))
101             {
102                 
103                 return false;
104             }
105 
106             Acceleration b = params.getParameter(ParameterTypes.B);
107             Acceleration aFollow = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
108             for (HeadwayGTU follower : neigbors.getFirstFollowers(lat))
109             {
110                 if (follower.getSpeed().gt0() || follower.getAcceleration().gt0())
111                 {
112                     
113                     Parameters folParams = follower.getParameters();
114                     folParams.setParameterResettable(ParameterTypes.TMIN, params.getParameter(ParameterTypes.TMIN));
115                     folParams.setParameterResettable(ParameterTypes.TMAX, params.getParameter(ParameterTypes.TMAX));
116                     Acceleration a = LmrsUtil.singleAcceleration(follower.getDistance(), follower.getSpeed(), ownSpeed, desire,
117                             folParams, follower.getSpeedLimitInfo(), follower.getCarFollowingModel());
118                     aFollow = Acceleration.min(aFollow, a);
119                     folParams.resetParameter(ParameterTypes.TMIN);
120                     folParams.resetParameter(ParameterTypes.TMAX);
121                 }
122             }
123 
124             Acceleration aSelf = egoAcceleration(perception, params, sli, cfm, desire, ownSpeed, lat);
125             Acceleration threshold = b.multiplyBy(-desire);
126             return aFollow.ge(threshold) && aSelf.ge(threshold);
127         }
128 
129         
130         @Override
131         public String toString()
132         {
133             return "EGO_HEADWAY";
134         }
135 
136     };
137 
138     
139 
140 
141 
142 
143 
144 
145 
146 
147 
148 
149 
150 
151     static Acceleration egoAcceleration(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
152             final CarFollowingModel cfm, final double desire, final Speed ownSpeed, final LateralDirectionality lat)
153             throws ParameterException, OperationalPlanException
154     {
155         Acceleration aSelf = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
156         if (ownSpeed.gt0())
157         {
158             for (
159 
160             HeadwayGTU leader : perception.getPerceptionCategory(NeighborsPerception.class).getFirstLeaders(lat))
161             {
162                 Acceleration a = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(), desire, params,
163                         sli, cfm);
164                 aSelf = Acceleration.min(aSelf, a);
165             }
166         }
167         return aSelf;
168     }
169 
170     
171 
172 
173 
174 
175 
176 
177 
178 
179 
180 
181 
182 
183 
184     boolean acceptGap(LanePerception perception, Parameters params, SpeedLimitInfo sli, CarFollowingModel cfm, double desire,
185             Speed ownSpeed, Acceleration ownAcceleration, LateralDirectionality lat)
186             throws ParameterException, OperationalPlanException;
187 
188 }