1   package org.opentrafficsim.road.gtu.lane.tactical;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import org.djunits.unit.DurationUnit;
7   import org.djunits.value.vdouble.scalar.Duration;
8   import org.djunits.value.vdouble.scalar.Length;
9   import org.djunits.value.vdouble.scalar.Time;
10  import org.opentrafficsim.base.parameters.ParameterException;
11  import org.opentrafficsim.core.gtu.GTUException;
12  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan;
13  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan.Segment;
14  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
15  import org.opentrafficsim.core.network.NetworkException;
16  import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
17  import org.opentrafficsim.road.gtu.lane.perception.CategoricalLanePerception;
18  import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
19  import org.opentrafficsim.road.gtu.lane.perception.categories.DefaultSimplePerception;
20  import org.opentrafficsim.road.gtu.lane.perception.categories.DirectDefaultSimplePerception;
21  import org.opentrafficsim.road.gtu.lane.perception.headway.Headway;
22  import org.opentrafficsim.road.gtu.lane.tactical.following.AccelerationStep;
23  import org.opentrafficsim.road.gtu.lane.tactical.following.GTUFollowingModelOld;
24  
25  import nl.tudelft.simulation.language.d3.DirectedPoint;
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  public class LaneBasedGTUFollowingTacticalPlanner extends AbstractLaneBasedTacticalPlanner
43  {
44      
45      private static final long serialVersionUID = 20151125L;
46  
47      
48  
49  
50  
51  
52      public LaneBasedGTUFollowingTacticalPlanner(final GTUFollowingModelOld carFollowingModel, final LaneBasedGTU gtu)
53      {
54          super(carFollowingModel, gtu, new CategoricalLanePerception(gtu));
55          getPerception().addPerceptionCategory(new DirectDefaultSimplePerception(getPerception()));
56      }
57  
58      
59      @Override
60      public final OperationalPlan generateOperationalPlan(final Time startTime, final DirectedPoint locationAtStartTime)
61              throws OperationalPlanException, NetworkException, GTUException, ParameterException
62      {
63          
64          LaneBasedGTU laneBasedGTU = getGtu();
65          LanePerception perception = getPerception();
66  
67          
68          if (laneBasedGTU.getMaximumSpeed().si < OperationalPlan.DRIFTING_SPEED_SI)
69          {
70              return new OperationalPlan(getGtu(), locationAtStartTime, startTime, new Duration(1.0, DurationUnit.SECOND));
71          }
72  
73          
74          Length maxDistance = laneBasedGTU.getParameters().getParameter(LOOKAHEAD);
75          LanePathInfo lanePathInfo = buildLanePathInfo(laneBasedGTU, maxDistance);
76  
77          
78          DefaultSimplePerception simplePerception = perception.getPerceptionCategory(DefaultSimplePerception.class);
79          Headway headwayGTU = simplePerception.getForwardHeadwayGTU();
80          AccelerationStep accelerationStepGTU = null;
81          if (headwayGTU.getDistance().ge(maxDistance))
82          {
83              
84              accelerationStepGTU = ((GTUFollowingModelOld) getCarFollowingModel()).computeAccelerationStepWithNoLeader(
85                      laneBasedGTU, lanePathInfo.getPath().getLength(), simplePerception.getSpeedLimit());
86          }
87          else
88          {
89              accelerationStepGTU =
90                      ((GTUFollowingModelOld) getCarFollowingModel()).computeAccelerationStep(laneBasedGTU, headwayGTU.getSpeed(),
91                              headwayGTU.getDistance(), lanePathInfo.getPath().getLength(), simplePerception.getSpeedLimit());
92          }
93  
94          
95          Headway headwayObject = simplePerception.getForwardHeadwayObject();
96          AccelerationStep accelerationStepObject = null;
97          if (headwayObject.getDistance().ge(maxDistance))
98          {
99              accelerationStepObject = ((GTUFollowingModelOld) getCarFollowingModel()).computeAccelerationStepWithNoLeader(
100                     laneBasedGTU, lanePathInfo.getPath().getLength(), simplePerception.getSpeedLimit());
101         }
102         else
103         {
104             accelerationStepObject = ((GTUFollowingModelOld) getCarFollowingModel()).computeAccelerationStep(laneBasedGTU,
105                     headwayObject.getSpeed(), headwayObject.getDistance(), lanePathInfo.getPath().getLength(),
106                     simplePerception.getSpeedLimit());
107         }
108 
109         
110         AccelerationStep accelerationStep = accelerationStepGTU.getAcceleration().lt(accelerationStepObject.getAcceleration())
111                 ? accelerationStepGTU : accelerationStepObject;
112 
113         
114         if (accelerationStep.getAcceleration().si < 1E-6 && laneBasedGTU.getSpeed().si < OperationalPlan.DRIFTING_SPEED_SI)
115         {
116             return new OperationalPlan(getGtu(), locationAtStartTime, startTime, accelerationStep.getDuration());
117         }
118 
119         List<Segment> operationalPlanSegmentList = new ArrayList<>();
120         if (accelerationStep.getAcceleration().si == 0.0)
121         {
122             Segment segment = new OperationalPlan.SpeedSegment(accelerationStep.getDuration());
123             operationalPlanSegmentList.add(segment);
124         }
125         else
126         {
127             Segment segment =
128                     new OperationalPlan.AccelerationSegment(accelerationStep.getDuration(), accelerationStep.getAcceleration());
129             operationalPlanSegmentList.add(segment);
130         }
131         OperationalPlan op = new OperationalPlan(getGtu(), lanePathInfo.getPath(), startTime, getGtu().getSpeed(),
132                 operationalPlanSegmentList);
133         return op;
134     }
135 
136     
137     @Override
138     public final String toString()
139     {
140         return "LaneBasedGTUFollowingTacticalPlanner [carFollowingModel=" + getCarFollowingModel() + "]";
141     }
142 }