1   package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2   
3   import org.djunits.value.vdouble.scalar.Length;
4   import org.djunits.value.vdouble.scalar.Speed;
5   import org.djutils.exceptions.Try;
6   import org.opentrafficsim.base.parameters.ParameterException;
7   import org.opentrafficsim.base.parameters.ParameterTypeDouble;
8   import org.opentrafficsim.base.parameters.ParameterTypeLength;
9   import org.opentrafficsim.base.parameters.ParameterTypeSpeed;
10  import org.opentrafficsim.base.parameters.ParameterTypes;
11  import org.opentrafficsim.base.parameters.Parameters;
12  import org.opentrafficsim.core.gtu.perception.EgoPerception;
13  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
14  import org.opentrafficsim.core.network.LateralDirectionality;
15  import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
16  import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
17  import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable;
18  import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
19  import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
20  import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
21  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTU;
22  import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
23  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
24  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
25  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
26  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  public class IncentiveSocioSpeed implements VoluntaryIncentive
43  {
44  
45      
46      protected static final ParameterTypeDouble RHO = Tailgating.RHO;
47  
48      
49      protected static final ParameterTypeDouble SOCIO = LmrsParameters.SOCIO;
50  
51      
52      protected static final ParameterTypeSpeed VCONG = ParameterTypes.VCONG;
53  
54      
55      protected static final ParameterTypeSpeed VGAIN = LmrsParameters.VGAIN;
56  
57      
58      protected static final ParameterTypeLength LOOKAHEAD = ParameterTypes.LOOKAHEAD;
59  
60      
61      @Override
62      public final Desire determineDesire(final Parameters parameters, final LanePerception perception,
63              final CarFollowingModel carFollowingModel, final Desire mandatoryDesire, final Desire voluntaryDesire)
64              throws ParameterException, OperationalPlanException
65      {
66          double dLeft = 0;
67          double dRight = 0;
68          Speed vCong = parameters.getParameter(VCONG);
69          Speed ownSpeed = perception.getPerceptionCategoryOrNull(EgoPerception.class).getSpeed();
70          if (ownSpeed.gt(vCong))
71          {
72              double sigma = parameters.getParameter(SOCIO);
73              NeighborsPerception neighbors = perception.getPerceptionCategory(NeighborsPerception.class);
74              InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
75              boolean leftLane = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.LEFT).si > 0.0;
76              boolean rightLane = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.RIGHT).si > 0.0;
77              
78              if (rightLane && mandatoryDesire.getRight() >= 0.0)
79              {
80                  PerceptionCollectable<HeadwayGTU, LaneBasedGTU> followers = neighbors.getFollowers(RelativeLane.CURRENT);
81                  if (!followers.isEmpty())
82                  {
83                      double rho = parameters.getParameter(RHO);
84                      HeadwayGTU follower = followers.first();
85                      double rhoFollower = follower.getParameters().getParameter(RHO);
86                      if (rhoFollower * sigma > rho)
87                      {
88                          dRight = rhoFollower * sigma;
89                      }
90                  }
91              }
92              
93              if (leftLane && mandatoryDesire.getLeft() <= 0.0)
94              {
95                  PerceptionCollectable<HeadwayGTU, LaneBasedGTU> followers = neighbors.getFollowers(RelativeLane.LEFT);
96                  if (followers != null && !followers.isEmpty())
97                  {
98                      double rho;
99                      PerceptionCollectable<HeadwayGTU, LaneBasedGTU> leaders = neighbors.getLeaders(RelativeLane.LEFT);
100                     if (leaders != null && !leaders.isEmpty())
101                     {
102                         HeadwayGTU leader = leaders.first();
103                         Speed vDes = Try.assign(() -> perception.getGtu().getDesiredSpeed(),
104                                 "Could not obtain GTU from perception.");
105                         Speed vGain = parameters.getParameter(VGAIN);
106                         Length x0 = parameters.getParameter(LOOKAHEAD);
107                         rho = Tailgating.socialPressure(ownSpeed, vCong, vDes, leader.getSpeed(), vGain, leader.getDistance(),
108                                 x0);
109                     }
110                     else
111                     {
112                         rho = 0.0;
113                     }
114                     HeadwayGTU follower = followers.first();
115                     Speed vGainFollower = follower.getParameters().getParameter(VGAIN);
116                     Length x0Follower = follower.getParameters().getParameter(LOOKAHEAD);
117                     double rhoFollower = Tailgating.socialPressure(follower.getSpeed(), vCong, follower.getDesiredSpeed(),
118                             ownSpeed, vGainFollower, follower.getDistance(), x0Follower);
119                     if (rhoFollower * sigma > rho)
120                     {
121                         dLeft = -rhoFollower * sigma;
122                     }
123                 }
124             }
125         }
126         return new Desire(dLeft, dRight);
127     }
128 
129     
130     @Override
131     public final String toString()
132     {
133         return "IncentiveSocioSpeed";
134     }
135 
136 }