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-2023 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://dittlab.tudelft.nl">Wouter Schakel</a>
30   */
31  public interface Cooperation extends LmrsParameters
32  {
33  
34      /** Simple passive cooperation. */
35      Cooperation PASSIVE = new Cooperation()
36      {
37          @Override
38          public Acceleration cooperate(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
39                  final CarFollowingModel cfm, final LateralDirectionality lat, final Desire ownDesire)
40                  throws ParameterException, OperationalPlanException
41          {
42              if ((lat.isLeft() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.LEFT))
43                      || (lat.isRight() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.RIGHT)))
44              {
45                  return new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
46              }
47              Acceleration b = params.getParameter(ParameterTypes.B);
48              Acceleration a = new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
49              double dCoop = params.getParameter(DCOOP);
50              Speed ownSpeed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
51              RelativeLane relativeLane = new RelativeLane(lat, 1);
52              for (HeadwayGtu leader : Synchronization.removeAllUpstreamOfConflicts(Synchronization.removeAllUpstreamOfConflicts(
53                      perception.getPerceptionCategory(NeighborsPerception.class).getLeaders(relativeLane), perception,
54                      relativeLane), perception, RelativeLane.CURRENT))
55              {
56                  Parameters params2 = leader.getParameters();
57                  double desire = lat.equals(LateralDirectionality.LEFT) ? params2.getParameter(DRIGHT)
58                          : lat.equals(LateralDirectionality.RIGHT) ? params2.getParameter(DLEFT) : 0;
59                  if (desire >= dCoop && (leader.getSpeed().gt0() || leader.getDistance().gt0()))
60                  {
61                      Acceleration aSingle = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(),
62                              desire, params, sli, cfm);
63                      a = Acceleration.min(a, aSingle);
64                  }
65              }
66              return Acceleration.max(a, b.neg());
67          }
68      };
69  
70      /** Same as passive cooperation, except that cooperation is fully ignored if the potential lane changer brakes heavily. */
71      Cooperation PASSIVE_MOVING = new Cooperation()
72      {
73          @Override
74          public Acceleration cooperate(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
75                  final CarFollowingModel cfm, final LateralDirectionality lat, final Desire ownDesire)
76                  throws ParameterException, OperationalPlanException
77          {
78              if ((lat.isLeft() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.LEFT))
79                      || (lat.isRight() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.RIGHT)))
80              {
81                  return new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
82              }
83              Acceleration bCrit = params.getParameter(ParameterTypes.BCRIT);
84              Acceleration b = params.getParameter(ParameterTypes.B);
85              Acceleration a = new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
86              double dCoop = params.getParameter(DCOOP);
87              Speed ownSpeed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
88              RelativeLane relativeLane = new RelativeLane(lat, 1);
89              NeighborsPerception neighbours = perception.getPerceptionCategory(NeighborsPerception.class);
90              PerceptionCollectable<HeadwayGtu, LaneBasedGtu> leaders = neighbours.getLeaders(RelativeLane.CURRENT);
91              Speed thresholdSpeed = Speed.instantiateSI(40.0 / 3.6);
92              boolean leaderInCongestion = leaders.isEmpty() ? false : leaders.first().getSpeed().lt(thresholdSpeed);
93              for (HeadwayGtu leader : Synchronization.removeAllUpstreamOfConflicts(
94                      Synchronization.removeAllUpstreamOfConflicts(neighbours.getLeaders(relativeLane), perception, relativeLane),
95                      perception, RelativeLane.CURRENT))
96              {
97                  Parameters params2 = leader.getParameters();
98                  double desire = lat.equals(LateralDirectionality.LEFT) ? params2.getParameter(DRIGHT)
99                          : lat.equals(LateralDirectionality.RIGHT) ? params2.getParameter(DLEFT) : 0;
100                 // TODO: only cooperate if merger still quite fast or there's congestion downstream anyway (which we can better
101                 // estimate than only considering the direct leader
102                 if (desire >= dCoop && (leader.getSpeed().gt0() || leader.getDistance().gt0())
103                         && (leader.getSpeed().ge(thresholdSpeed) || leaderInCongestion))
104                 {
105                     Acceleration aSingle = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(),
106                             desire, params, sli, cfm);
107                     a = Acceleration.min(a, aSingle);
108                 }
109             }
110             return Acceleration.max(a, bCrit.neg());
111         }
112     };
113 
114     /** Cooperation similar to the default, with nuanced differences of when to ignore. */
115     Cooperation ACTIVE = new Cooperation()
116     {
117         @Override
118         public Acceleration cooperate(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
119                 final CarFollowingModel cfm, final LateralDirectionality lat, final Desire ownDesire)
120                 throws ParameterException, OperationalPlanException
121         {
122 
123             if ((lat.isLeft() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.LEFT))
124                     || (lat.isRight() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.RIGHT)))
125             {
126                 return new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
127             }
128             Acceleration a = new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
129             double dCoop = params.getParameter(DCOOP);
130             Speed ownSpeed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
131             RelativeLane relativeLane = new RelativeLane(lat, 1);
132             for (HeadwayGtu leader : Synchronization.removeAllUpstreamOfConflicts(Synchronization.removeAllUpstreamOfConflicts(
133                     perception.getPerceptionCategory(NeighborsPerception.class).getLeaders(relativeLane), perception,
134                     relativeLane), perception, RelativeLane.CURRENT))
135             {
136                 Parameters params2 = leader.getParameters();
137                 double desire = lat.equals(LateralDirectionality.LEFT) ? params2.getParameter(DRIGHT)
138                         : lat.equals(LateralDirectionality.RIGHT) ? params2.getParameter(DLEFT) : 0;
139                 if (desire >= dCoop && leader.getDistance().gt0()
140                         && leader.getAcceleration().gt(params.getParameter(ParameterTypes.BCRIT).neg()))
141                 {
142                     Acceleration aSingle = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(),
143                             desire, params, sli, cfm);
144                     a = Acceleration.min(a, Synchronization.gentleUrgency(aSingle, desire, params));
145                 }
146             }
147             return a;
148         }
149     };
150 
151     /**
152      * Determine acceleration for cooperation.
153      * @param perception LanePerception; perception
154      * @param params Parameters; parameters
155      * @param sli SpeedLimitInfo; speed limit info
156      * @param cfm CarFollowingModel; car-following model
157      * @param lat LateralDirectionality; lateral direction for cooperation
158      * @param ownDesire Desire; own lane change desire
159      * @return acceleration for synchronization
160      * @throws ParameterException if a parameter is not defined
161      * @throws OperationalPlanException perception exception
162      */
163     Acceleration cooperate(LanePerception perception, Parameters params, SpeedLimitInfo sli, CarFollowingModel cfm,
164             LateralDirectionality lat, Desire ownDesire) throws ParameterException, OperationalPlanException;
165 }