View Javadoc
1   package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2   
3   import java.util.SortedSet;
4   
5   import org.djunits.unit.LengthUnit;
6   import org.djunits.value.vdouble.scalar.Acceleration;
7   import org.djunits.value.vdouble.scalar.Length;
8   import org.djunits.value.vdouble.scalar.Speed;
9   import org.djunits.value.vdouble.scalar.Time;
10  import org.opentrafficsim.core.gtu.GTUException;
11  import org.opentrafficsim.core.gtu.behavioralcharacteristics.BehavioralCharacteristics;
12  import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterException;
13  import org.opentrafficsim.core.gtu.perception.EgoPerception;
14  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
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.RelativeLane;
18  import org.opentrafficsim.road.gtu.lane.perception.categories.BusStopPerception;
19  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayBusStop;
20  import org.opentrafficsim.road.gtu.lane.plan.operational.SimpleOperationalPlan;
21  import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
22  import org.opentrafficsim.road.gtu.lane.tactical.pt.BusSchedule;
23  import org.opentrafficsim.road.gtu.lane.tactical.util.CarFollowingUtil;
24  import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
25  
26  /**
27   * <p>
28   * Copyright (c) 2013-2017 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
29   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
30   * <p>
31   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 27 jan. 2017 <br>
32   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
33   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
34   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
35   */
36  public class AccelerationBusStop implements AccelerationIncentive
37  {
38  
39      /** Distance within which the bus can open the doors. */
40      // TODO this is much more complex: tail blocking other traffic? other bus in front? many people at bus stop?
41      private static final Length STOP_DISTANCE = new Length(15.0, LengthUnit.SI);
42  
43      /** {@inheritDoc} */
44      @Override
45      @SuppressWarnings("checkstyle:parameternumber")
46      public void accelerate(final SimpleOperationalPlan simplePlan, final RelativeLane lane, final LaneBasedGTU gtu,
47              final LanePerception perception, final CarFollowingModel carFollowingModel, final Speed speed,
48              final BehavioralCharacteristics bc, final SpeedLimitInfo speedLimitInfo)
49              throws OperationalPlanException, ParameterException, GTUException
50      {
51          SortedSet<HeadwayBusStop> stops = perception.getPerceptionCategory(BusStopPerception.class).getBusStops();
52          if (stops.isEmpty())
53          {
54              return;
55          }
56          BusSchedule busSchedule = (BusSchedule) gtu.getStrategicalPlanner().getRoute();
57          Time now = gtu.getSimulator().getSimulatorTime().getTime();
58          for (HeadwayBusStop stop : stops)
59          {
60              String busStopId = stop.getId();
61              if (busSchedule.isLineStop(busStopId, now))
62              {
63  
64                  // check when to leave
65                  boolean stoppedAtStop = stop.getRelativeLane().isCurrent() && stop.getDistance().le(STOP_DISTANCE)
66                          && perception.getPerceptionCategory(EgoPerception.class).getSpeed().eq0();
67                  if (busSchedule.getActualDepartureBusStop(busStopId) == null)
68                  {
69                      if (stoppedAtStop)
70                      {
71                          // bus just stopped
72                          Time departureTime = now.plus(busSchedule.getDwellTime(busStopId));
73                          if (busSchedule.isForceSchedule(busStopId))
74                          {
75                              departureTime = Time.max(departureTime, busSchedule.getDepartureTime(busStopId));
76                          }
77                          busSchedule.setActualDeparture(busStopId, stop.getConflictIds(), departureTime);
78                      }
79                  }
80  
81                  // stop if not known yet, or before departure time
82                  if (busSchedule.getActualDepartureBusStop(busStopId) == null
83                          || now.lt(busSchedule.getActualDepartureBusStop(busStopId)))
84                  {
85                      if (stoppedAtStop)
86                      {
87                          // stand still at location where stop was initiated
88                          simplePlan.minimizeAcceleration(Acceleration.ZERO);
89                      }
90                      else
91                      {
92                          // decelerate to initiate stop
93                          simplePlan.minimizeAcceleration(
94                                  CarFollowingUtil.stop(carFollowingModel, bc, speed, speedLimitInfo, stop.getDistance()));
95                      }
96                  }
97              }
98          }
99      }
100 
101     /** {@inheritDoc} */
102     @Override
103     public String toString()
104     {
105         return "AccelerationBusStop";
106     }
107 
108 }