1 package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2
3 import org.djunits.value.vdouble.scalar.Length;
4 import org.djunits.value.vdouble.scalar.Speed;
5 import org.djunits.value.vdouble.scalar.Time;
6 import org.djutils.exceptions.Try;
7 import org.opentrafficsim.base.parameters.ParameterException;
8 import org.opentrafficsim.base.parameters.ParameterTypes;
9 import org.opentrafficsim.base.parameters.Parameters;
10 import org.opentrafficsim.core.gtu.GTUException;
11 import org.opentrafficsim.core.gtu.perception.EgoPerception;
12 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan;
13 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
14 import org.opentrafficsim.core.network.NetworkException;
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.InfrastructurePerception;
19 import org.opentrafficsim.road.gtu.lane.plan.operational.LaneChange;
20 import org.opentrafficsim.road.gtu.lane.plan.operational.LaneOperationalPlanBuilder;
21 import org.opentrafficsim.road.gtu.lane.plan.operational.SimpleOperationalPlan;
22 import org.opentrafficsim.road.gtu.lane.tactical.Blockable;
23 import org.opentrafficsim.road.gtu.lane.tactical.DesireBased;
24 import org.opentrafficsim.road.gtu.lane.tactical.Synchronizable;
25 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
26 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
27 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
28 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance;
29 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Incentive;
30 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsData;
31 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
32 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsUtil;
33 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
34 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
35 import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
36 import org.opentrafficsim.road.network.speed.SpeedLimitProspect;
37
38 import nl.tudelft.simulation.language.d3.DirectedPoint;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public class LMRS extends AbstractIncentivesTacticalPlanner implements DesireBased, Synchronizable, Blockable
55 {
56
57
58 private static final long serialVersionUID = 20160300L;
59
60
61 private final LaneChange laneChange;
62
63
64 private final LmrsData lmrsData;
65
66
67
68
69
70
71
72
73
74
75
76 public LMRS(final CarFollowingModel carFollowingModel, final LaneBasedGTU gtu, final LanePerception lanePerception,
77 final Synchronization synchronization, final Cooperation cooperation, final GapAcceptance gapAcceptance,
78 final Tailgating tailgating)
79 {
80 super(carFollowingModel, gtu, lanePerception);
81 this.laneChange = Try.assign(() -> new LaneChange(gtu), "Parameter LCDUR is required.", GTUException.class);
82 this.lmrsData = new LmrsData(synchronization, cooperation, gapAcceptance, tailgating);
83 }
84
85
86 @Override
87 public final OperationalPlan generateOperationalPlan(final Time startTime, final DirectedPoint locationAtStartTime)
88 throws OperationalPlanException, GTUException, NetworkException, ParameterException
89 {
90
91 SpeedLimitProspect slp = getPerception().getPerceptionCategory(InfrastructurePerception.class)
92 .getSpeedLimitProspect(RelativeLane.CURRENT);
93 SpeedLimitInfo sli = slp.getSpeedLimitInfo(Length.ZERO);
94 Parameters params = getGtu().getParameters();
95
96
97 SimpleOperationalPlan simplePlan = LmrsUtil.determinePlan(getGtu(), startTime, getCarFollowingModel(), this.laneChange,
98 this.lmrsData, getPerception(), getMandatoryIncentives(), getVoluntaryIncentives());
99
100
101 Speed speed = getPerception().getPerceptionCategory(EgoPerception.class).getSpeed();
102 RelativeLane[] lanes;
103 double dLeft = params.getParameterOrNull(LmrsParameters.DLEFT);
104 double dRight = params.getParameterOrNull(LmrsParameters.DRIGHT);
105 double dSync = params.getParameterOrNull(LmrsParameters.DSYNC);
106 if (this.laneChange.isChangingLane())
107 {
108 lanes = new RelativeLane[] { RelativeLane.CURRENT, this.laneChange.getSecondLane(getGtu()) };
109 }
110 else if (dLeft >= dSync && dLeft >= dRight)
111 {
112 lanes = new RelativeLane[] { RelativeLane.CURRENT, RelativeLane.LEFT };
113 }
114 else if (dRight >= dSync)
115 {
116 lanes = new RelativeLane[] { RelativeLane.CURRENT, RelativeLane.RIGHT };
117 }
118 else
119 {
120 lanes = new RelativeLane[] { RelativeLane.CURRENT };
121 }
122 for (RelativeLane lane : lanes)
123 {
124
125
126
127 Length mergeDistance = lane.isCurrent() ? Length.ZERO
128 : Synchronization.getMergeDistance(getPerception(), lane.getLateralDirectionality());
129 for (AccelerationIncentive incentive : getAccelerationIncentives())
130 {
131 incentive.accelerate(simplePlan, lane, mergeDistance, getGtu(), getPerception(), getCarFollowingModel(), speed,
132 params, sli);
133 }
134 }
135
136 if (simplePlan.isLaneChange())
137 {
138 this.laneChange.setDesiredLaneChangeDuration(getGtu().getParameters().getParameter(ParameterTypes.LCDUR));
139
140 }
141
142
143 simplePlan.setTurnIndicator(getGtu());
144
145
146 return LaneOperationalPlanBuilder.buildPlanFromSimplePlan(getGtu(), startTime, simplePlan, this.laneChange);
147
148 }
149
150
151 @Override
152 public final Desire getLatestDesire(final Class<? extends Incentive> incentiveClass)
153 {
154 return this.lmrsData.getLatestDesire(incentiveClass);
155 }
156
157
158 @Override
159 public Synchronizable.State getSynchronizationState()
160 {
161 return this.lmrsData.getSynchronizationState();
162 }
163
164
165 @Override
166 public boolean isBlocking()
167 {
168 for (AccelerationIncentive acc : getAccelerationIncentives())
169 {
170 if (acc instanceof AccelerationConflicts)
171 {
172 return ((AccelerationConflicts) acc).isBlocking();
173 }
174 }
175 return false;
176 }
177
178
179 @Override
180 public final String toString()
181 {
182 return "LMRS [mandatoryIncentives=" + getMandatoryIncentives() + ", voluntaryIncentives=" + getVoluntaryIncentives()
183 + ", accelerationIncentives = " + getAccelerationIncentives() + "]";
184 }
185
186 }