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