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