1   package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2   
3   import java.util.SortedSet;
4   
5   import org.djunits.value.vdouble.scalar.Speed;
6   import org.opentrafficsim.base.parameters.ParameterException;
7   import org.opentrafficsim.base.parameters.ParameterTypeDouble;
8   import org.opentrafficsim.base.parameters.ParameterTypeSpeed;
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.road.gtu.lane.perception.InfrastructureLaneChangeInfo;
13  import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
14  import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
15  import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
16  import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
17  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTU;
18  import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
19  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
20  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
21  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.MandatoryIncentive;
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  public class IncentiveGetInLane implements MandatoryIncentive
36  {
37  
38      
39      protected static final ParameterTypeSpeed VCONG = ParameterTypes.VCONG;
40  
41      
42      protected static final ParameterTypeDouble SOCIO = LmrsParameters.SOCIO;
43  
44      
45      @Override
46      public Desire determineDesire(final Parameters parameters, final LanePerception perception,
47              final CarFollowingModel carFollowingModel, final Desire mandatoryDesire)
48              throws ParameterException, OperationalPlanException
49      {
50  
51          Speed vCong = parameters.getParameter(VCONG);
52          double socio = parameters.getParameter(SOCIO);
53          InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
54          NeighborsPerception neighbors = perception.getPerceptionCategory(NeighborsPerception.class);
55          SortedSet<InfrastructureLaneChangeInfo> info = infra.getInfrastructureLaneChangeInfo(RelativeLane.CURRENT);
56          double dCur = info.isEmpty() ? Double.POSITIVE_INFINITY
57                  : info.first().getRemainingDistance().si / info.first().getRequiredNumberOfLaneChanges();
58          double left = 0;
59          double right = 0;
60          double vCur = Double.POSITIVE_INFINITY;
61  
62          for (RelativeLane lane : new RelativeLane[] { RelativeLane.LEFT, RelativeLane.RIGHT })
63          {
64              if (infra.getCrossSection().contains(lane))
65              {
66                  SortedSet<InfrastructureLaneChangeInfo> adjInfo = infra.getInfrastructureLaneChangeInfo(lane);
67                  double dAdj = adjInfo.isEmpty() ? Double.POSITIVE_INFINITY
68                          : adjInfo.first().getRemainingDistance().si / adjInfo.first().getRequiredNumberOfLaneChanges();
69                  if (!info.isEmpty() && !info.first().isDeadEnd() && dCur < dAdj)
70                  {
71                      double v = Double.POSITIVE_INFINITY;
72                      for (HeadwayGTU neighbor : neighbors.getLeaders(lane))
73                      {
74                          v = Math.min(v, neighbor.getSpeed().si);
75                      }
76                      if (lane.isLeft())
77                      {
78                          double d = Math.max(0.0, 1.0 - v / vCong.si);
79                          left += d;
80                          
81                      }
82                      else
83                      {
84                          double d = Math.max(0.0, 1.0 - v / vCong.si);
85                          right += d;
86                          
87                      }
88                  }
89                  if (!adjInfo.isEmpty() && !adjInfo.first().isDeadEnd()
90                          && (info.isEmpty() || (!info.isEmpty() && !info.first().isDeadEnd())) && dCur > dAdj)
91                  {
92                      if (Double.isInfinite(vCur))
93                      {
94                          for (HeadwayGTU neighbor : neighbors.getLeaders(RelativeLane.CURRENT))
95                          {
96                              vCur = Math.min(vCur, neighbor.getSpeed().si);
97                          }
98                      }
99                      if (lane.isLeft())
100                     {
101                         left -= Math.max(0.0, 1.0 - vCur / vCong.si);
102                     }
103                     else
104                     {
105                         right -= Math.max(0.0, 1.0 - vCur / vCong.si);
106                     }
107                 }
108             }
109         }
110         return new Desire(left * socio, right * socio);
111     }
112 
113     
114     @Override
115     public final String toString()
116     {
117         return "IncentiveGetInLane";
118     }
119 
120 }