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-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
25   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
26   * <p>
27   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 2 mrt. 2018 <br>
28   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
29   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
30   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
31   */
32  public interface Cooperation extends LmrsParameters
33  {
34  
35      /** Simple passive cooperation. */
36      Cooperation PASSIVE = new Cooperation()
37      {
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 : Synchronization.removeAllUpstreamOfConflicts(Synchronization.removeAllUpstreamOfConflicts(
54                      perception.getPerceptionCategory(NeighborsPerception.class).getLeaders(relativeLane), perception,
55                      relativeLane), perception, RelativeLane.CURRENT))
56              {
57                  Parameters params2 = leader.getParameters();
58                  double desire = lat.equals(LateralDirectionality.LEFT) ? params2.getParameter(DRIGHT)
59                          : lat.equals(LateralDirectionality.RIGHT) ? params2.getParameter(DLEFT) : 0;
60                  if (desire >= dCoop && (leader.getSpeed().gt0() || leader.getDistance().gt0()))
61                  {
62                      Acceleration aSingle = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(),
63                              desire, params, sli, cfm);
64                      a = Acceleration.min(a, aSingle);
65                  }
66              }
67              return Acceleration.max(a, b.neg());
68          }
69      };
70  
71      /** Same as passive cooperation, except that cooperation is fully ignored if the potential lane changer brakes heavily. */
72      Cooperation PASSIVE_MOVING = new Cooperation()
73      {
74          @Override
75          public Acceleration cooperate(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
76                  final CarFollowingModel cfm, final LateralDirectionality lat, final Desire ownDesire)
77                  throws ParameterException, OperationalPlanException
78          {
79              if ((lat.isLeft() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.LEFT))
80                      || (lat.isRight() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.RIGHT)))
81              {
82                  return new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
83              }
84              Acceleration bCrit = params.getParameter(ParameterTypes.BCRIT);
85              Acceleration b = params.getParameter(ParameterTypes.B);
86              Acceleration a = new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
87              double dCoop = params.getParameter(DCOOP);
88              Speed ownSpeed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
89              RelativeLane relativeLane = new RelativeLane(lat, 1);
90              NeighborsPerception neighbours = perception.getPerceptionCategory(NeighborsPerception.class);
91              PerceptionCollectable<HeadwayGTU, LaneBasedGTU> leaders = neighbours.getLeaders(RelativeLane.CURRENT);
92              Speed thresholdSpeed = Speed.createSI(40.0 / 3.6);
93              boolean leaderInCongestion = leaders.isEmpty() ? false : leaders.first().getSpeed().lt(thresholdSpeed);
94              for (HeadwayGTU leader : Synchronization.removeAllUpstreamOfConflicts(
95                      Synchronization.removeAllUpstreamOfConflicts(neighbours.getLeaders(relativeLane), perception, relativeLane),
96                      perception, RelativeLane.CURRENT))
97              {
98                  Parameters params2 = leader.getParameters();
99                  double desire = lat.equals(LateralDirectionality.LEFT) ? params2.getParameter(DRIGHT)
100                         : lat.equals(LateralDirectionality.RIGHT) ? params2.getParameter(DLEFT) : 0;
101                 // TODO: only cooperate if merger still quite fast or there's congestion downstream anyway (which we can better
102                 // estimate than only considering the direct leader
103                 if (desire >= dCoop && (leader.getSpeed().gt0() || leader.getDistance().gt0())
104                         && (leader.getSpeed().ge(thresholdSpeed) || leaderInCongestion))
105                 {
106                     Acceleration aSingle = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(),
107                             desire, params, sli, cfm);
108                     a = Acceleration.min(a, aSingle);
109                 }
110             }
111             return Acceleration.max(a, bCrit.neg());
112         }
113     };
114 
115     /** Cooperation similar to the default, with nuanced differences of when to ignore. */
116     Cooperation ACTIVE = new Cooperation()
117     {
118         @Override
119         public Acceleration cooperate(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
120                 final CarFollowingModel cfm, final LateralDirectionality lat, final Desire ownDesire)
121                 throws ParameterException, OperationalPlanException
122         {
123 
124             if ((lat.isLeft() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.LEFT))
125                     || (lat.isRight() && !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.RIGHT)))
126             {
127                 return new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
128             }
129             Acceleration a = new Acceleration(Double.MAX_VALUE, AccelerationUnit.SI);
130             double dCoop = params.getParameter(DCOOP);
131             Speed ownSpeed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
132             RelativeLane relativeLane = new RelativeLane(lat, 1);
133             for (HeadwayGTU leader : Synchronization.removeAllUpstreamOfConflicts(Synchronization.removeAllUpstreamOfConflicts(
134                     perception.getPerceptionCategory(NeighborsPerception.class).getLeaders(relativeLane), perception,
135                     relativeLane), perception, RelativeLane.CURRENT))
136             {
137                 Parameters params2 = leader.getParameters();
138                 double desire = lat.equals(LateralDirectionality.LEFT) ? params2.getParameter(DRIGHT)
139                         : lat.equals(LateralDirectionality.RIGHT) ? params2.getParameter(DLEFT) : 0;
140                 if (desire >= dCoop && leader.getDistance().gt0()
141                         && leader.getAcceleration().gt(params.getParameter(ParameterTypes.BCRIT).neg()))
142                 {
143                     Acceleration aSingle = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(),
144                             desire, params, sli, cfm);
145                     a = Acceleration.min(a, Synchronization.gentleUrgency(aSingle, desire, params));
146                 }
147             }
148             return a;
149         }
150     };
151 
152     /**
153      * Determine acceleration for cooperation.
154      * @param perception LanePerception; perception
155      * @param params Parameters; parameters
156      * @param sli SpeedLimitInfo; speed limit info
157      * @param cfm CarFollowingModel; car-following model
158      * @param lat LateralDirectionality; lateral direction for cooperation
159      * @param ownDesire Desire; own lane change desire
160      * @return acceleration for synchronization
161      * @throws ParameterException if a parameter is not defined
162      * @throws OperationalPlanException perception exception
163      */
164     Acceleration cooperate(LanePerception perception, Parameters params, SpeedLimitInfo sli, CarFollowingModel cfm,
165             LateralDirectionality lat, Desire ownDesire) throws ParameterException, OperationalPlanException;
166 }