View Javadoc
1   package org.opentrafficsim.road.gtu.lane.tactical.util.lmrs;
2   
3   import org.djunits.unit.AccelerationUnit;
4   import org.djunits.value.vdouble.scalar.Acceleration;
5   import org.djunits.value.vdouble.scalar.Speed;
6   import org.opentrafficsim.base.parameters.ParameterException;
7   import org.opentrafficsim.base.parameters.ParameterTypes;
8   import org.opentrafficsim.base.parameters.Parameters;
9   import org.opentrafficsim.core.gtu.perception.EgoPerception;
10  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
11  import org.opentrafficsim.core.network.LateralDirectionality;
12  import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
13  import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
14  import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable;
15  import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
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.network.speed.SpeedLimitInfo;
20  
21  /**
22   * Different forms of cooperation.
23   * <p>
24   * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
25   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
26   * </p>
27   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
28   * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
29   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
30   */
31  public interface Cooperation extends LmrsParameters
32  {
33  
34      /** Simple passive cooperation. */
35      Cooperation PASSIVE = new Cooperation()
36      {
37          /** {@inheritDoc} */
38          @Override
39          public Acceleration cooperate(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
40                  final CarFollowingModel cfm, final LateralDirectionality lat, final Desire ownDesire)
41                  throws ParameterException, OperationalPlanException
42          {
43              if ((lat.isLeft() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.LEFT))
44                      || (lat.isRight() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.RIGHT)))
45              {
46                  return new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
47              }
48              Acceleration b = params.getParameter(ParameterTypes.B);
49              Acceleration a = new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
50              double dCoop = params.getParameter(DCOOP);
51              Speed ownSpeed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
52              RelativeLane relativeLane = new RelativeLane(lat, 1);
53              for (HeadwayGtu leader : perception.getPerceptionCategory(NeighborsPerception.class).getLeaders(relativeLane))
54              {
55                  Parameters params2 = leader.getParameters();
56                  double desire = lat.equals(LateralDirectionality.LEFT) ? params2.getParameter(DRIGHT)
57                          : lat.equals(LateralDirectionality.RIGHT) ? params2.getParameter(DLEFT) : 0;
58                  if (desire >= dCoop && (leader.getSpeed().gt0() || leader.getDistance().gt0()))
59                  {
60                      Acceleration aSingle = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(),
61                              desire, params, sli, cfm);
62                      a = Acceleration.min(a, aSingle);
63                  }
64              }
65              return Acceleration.max(a, b.neg());
66          }
67          
68          /** {@inheritDoc} */
69          @Override
70          public String toString()
71          {
72              return "PASSIVE";
73          }
74      };
75  
76      /** Same as passive cooperation, except that cooperation is fully ignored if the potential lane changer brakes heavily. */
77      Cooperation PASSIVE_MOVING = new Cooperation()
78      {
79          /** {@inheritDoc} */
80          @Override
81          public Acceleration cooperate(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
82                  final CarFollowingModel cfm, final LateralDirectionality lat, final Desire ownDesire)
83                  throws ParameterException, OperationalPlanException
84          {
85              if ((lat.isLeft() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.LEFT))
86                      || (lat.isRight() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.RIGHT)))
87              {
88                  return new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
89              }
90              Acceleration bCrit = params.getParameter(ParameterTypes.BCRIT);
91              Acceleration a = new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
92              double dCoop = params.getParameter(DCOOP);
93              Speed ownSpeed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
94              RelativeLane relativeLane = new RelativeLane(lat, 1);
95              NeighborsPerception neighbours = perception.getPerceptionCategory(NeighborsPerception.class);
96              PerceptionCollectable<HeadwayGtu, LaneBasedGtu> leaders = neighbours.getLeaders(RelativeLane.CURRENT);
97              Speed thresholdSpeed = Speed.instantiateSI(40.0 / 3.6);
98              boolean leaderInCongestion = leaders.isEmpty() ? false : leaders.first().getSpeed().lt(thresholdSpeed);
99              for (HeadwayGtu leader : neighbours.getLeaders(relativeLane))
100             {
101                 Parameters params2 = leader.getParameters();
102                 double desire = lat.equals(LateralDirectionality.LEFT) ? params2.getParameter(DRIGHT)
103                         : lat.equals(LateralDirectionality.RIGHT) ? params2.getParameter(DLEFT) : 0;
104                 // TODO: only cooperate if merger still quite fast or there's congestion downstream anyway (which we can better
105                 // estimate than only considering the direct leader
106                 if (desire >= dCoop && (leader.getSpeed().gt0() || leader.getDistance().gt0())
107                         && (leader.getSpeed().ge(thresholdSpeed) || leaderInCongestion))
108                 {
109                     Acceleration aSingle = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(),
110                             desire, params, sli, cfm);
111                     a = Acceleration.min(a, aSingle);
112                 }
113             }
114             return Acceleration.max(a, bCrit.neg());
115         }
116         
117         /** {@inheritDoc} */
118         @Override
119         public String toString()
120         {
121             return "PASSIVE_MOVING";
122         }
123     };
124 
125     /** Cooperation similar to the default, with nuanced differences of when to ignore. */
126     Cooperation ACTIVE = new Cooperation()
127     {
128         /** {@inheritDoc} */
129         @Override
130         public Acceleration cooperate(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
131                 final CarFollowingModel cfm, final LateralDirectionality lat, final Desire ownDesire)
132                 throws ParameterException, OperationalPlanException
133         {
134 
135             if ((lat.isLeft() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.LEFT))
136                     || (lat.isRight() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.RIGHT)))
137             {
138                 return new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
139             }
140             Acceleration a = new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
141             double dCoop = params.getParameter(DCOOP);
142             Speed ownSpeed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
143             RelativeLane relativeLane = new RelativeLane(lat, 1);
144             for (HeadwayGtu leader : perception.getPerceptionCategory(NeighborsPerception.class).getLeaders(relativeLane))
145             {
146                 Parameters params2 = leader.getParameters();
147                 double desire = lat.equals(LateralDirectionality.LEFT) ? params2.getParameter(DRIGHT)
148                         : lat.equals(LateralDirectionality.RIGHT) ? params2.getParameter(DLEFT) : 0;
149                 if (desire >= dCoop && leader.getDistance().gt0()
150                         && leader.getAcceleration().gt(params.getParameter(ParameterTypes.BCRIT).neg()))
151                 {
152                     Acceleration aSingle = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(),
153                             desire, params, sli, cfm);
154                     a = Acceleration.min(a, Synchronization.gentleUrgency(aSingle, desire, params));
155                 }
156             }
157             return a;
158         }
159         
160         /** {@inheritDoc} */
161         @Override
162         public String toString()
163         {
164             return "ACTIVE";
165         }
166     };
167 
168     /**
169      * Determine acceleration for cooperation.
170      * @param perception LanePerception; perception
171      * @param params Parameters; parameters
172      * @param sli SpeedLimitInfo; speed limit info
173      * @param cfm CarFollowingModel; car-following model
174      * @param lat LateralDirectionality; lateral direction for cooperation
175      * @param ownDesire Desire; own lane change desire
176      * @return acceleration for synchronization
177      * @throws ParameterException if a parameter is not defined
178      * @throws OperationalPlanException perception exception
179      */
180     Acceleration cooperate(LanePerception perception, Parameters params, SpeedLimitInfo sli, CarFollowingModel cfm,
181             LateralDirectionality lat, Desire ownDesire) throws ParameterException, OperationalPlanException;
182 }