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