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.draw.point.OrientedPoint2d;
7 import org.djutils.exceptions.Try;
8 import org.opentrafficsim.base.parameters.ParameterException;
9 import org.opentrafficsim.base.parameters.ParameterTypes;
10 import org.opentrafficsim.base.parameters.Parameters;
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 OrientedPoint2d 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 if (getPerception().getLaneStructure().getRootCrossSection().contains(lane))
123 {
124
125
126
127
128 Length mergeDistance = lane.isCurrent() ? Length.ZERO
129 : Synchronization.getMergeDistance(getPerception(), lane.getLateralDirectionality());
130 for (AccelerationIncentive incentive : getAccelerationIncentives())
131 {
132 incentive.accelerate(simplePlan, lane, mergeDistance, getGtu(), getPerception(), getCarFollowingModel(),
133 speed, params, sli);
134 }
135 }
136 }
137
138 if (simplePlan.isLaneChange())
139 {
140 this.laneChange.setDesiredLaneChangeDuration(getGtu().getParameters().getParameter(ParameterTypes.LCDUR));
141
142 }
143
144
145 simplePlan.setTurnIndicator(getGtu());
146
147
148 return LaneOperationalPlanBuilder.buildPlanFromSimplePlan(getGtu(), startTime, simplePlan, this.laneChange);
149
150 }
151
152
153 @Override
154 public final Desire getLatestDesire(final Class<? extends Incentive> incentiveClass)
155 {
156 return this.lmrsData.getLatestDesire(incentiveClass);
157 }
158
159
160 @Override
161 public Synchronizable.State getSynchronizationState()
162 {
163 return this.lmrsData.getSynchronizationState();
164 }
165
166
167 @Override
168 public boolean isBlocking()
169 {
170 for (AccelerationIncentive acc : getAccelerationIncentives())
171 {
172 if (acc instanceof AccelerationConflicts)
173 {
174 return ((AccelerationConflicts) acc).isBlocking();
175 }
176 }
177 return false;
178 }
179
180
181 @Override
182 public final String toString()
183 {
184 return "LMRS [mandatoryIncentives=" + getMandatoryIncentives() + ", voluntaryIncentives=" + getVoluntaryIncentives()
185 + ", accelerationIncentives = " + getAccelerationIncentives() + "]";
186 }
187
188 }