1 package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2
3 import java.util.LinkedHashSet;
4
5 import org.djunits.value.vdouble.scalar.Length;
6 import org.djunits.value.vdouble.scalar.Speed;
7 import org.djunits.value.vdouble.scalar.Time;
8 import org.opentrafficsim.core.gtu.GTUException;
9 import org.opentrafficsim.core.gtu.behavioralcharacteristics.BehavioralCharacteristics;
10 import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterException;
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.DelayedNeighborsPerception;
19 import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
20 import org.opentrafficsim.road.gtu.lane.plan.operational.LaneOperationalPlanBuilder.LaneChange;
21 import org.opentrafficsim.road.gtu.lane.plan.operational.SimpleOperationalPlan;
22 import org.opentrafficsim.road.gtu.lane.tactical.AbstractLaneBasedTacticalPlanner;
23 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
24 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsData;
25 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsUtil;
26 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.MandatoryIncentive;
27 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
28 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
29 import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
30 import org.opentrafficsim.road.network.speed.SpeedLimitProspect;
31
32 import nl.tudelft.simulation.language.d3.DirectedPoint;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class LMRS extends AbstractLaneBasedTacticalPlanner
49 {
50
51
52 private static final long serialVersionUID = 20160300L;
53
54
55 private final LaneChange laneChange = new LaneChange();
56
57
58 private final LmrsData lmrsData;
59
60
61 private final LinkedHashSet<MandatoryIncentive> mandatoryIncentives = new LinkedHashSet<>();
62
63
64 private final LinkedHashSet<VoluntaryIncentive> voluntaryIncentives = new LinkedHashSet<>();
65
66
67 private final LinkedHashSet<AccelerationIncentive> accelerationIncentives = new LinkedHashSet<>();
68
69
70
71
72
73
74
75
76 public LMRS(final CarFollowingModel carFollowingModel, final LaneBasedGTU gtu, final LanePerception lanePerception,
77 final Synchronization synchronization)
78 {
79 super(carFollowingModel, gtu, lanePerception);
80 this.lmrsData = new LmrsData(synchronization);
81 }
82
83
84
85
86
87 public final void addMandatoryIncentive(final MandatoryIncentive incentive)
88 {
89 if (incentive != null)
90 {
91 this.mandatoryIncentives.add(incentive);
92 }
93 }
94
95
96
97
98
99 public final void addVoluntaryIncentive(final VoluntaryIncentive incentive)
100 {
101 if (incentive != null)
102 {
103 this.voluntaryIncentives.add(incentive);
104 }
105 }
106
107
108
109
110
111 public final void addAccelerationIncentive(final AccelerationIncentive incentive)
112 {
113 if (incentive != null)
114 {
115 this.accelerationIncentives.add(incentive);
116 }
117 }
118
119
120
121
122 public final void setDefaultIncentives()
123 {
124 this.mandatoryIncentives.clear();
125 this.voluntaryIncentives.clear();
126 this.accelerationIncentives.clear();
127 this.mandatoryIncentives.add(new IncentiveRoute());
128 this.mandatoryIncentives.add(new IncentiveGetInLane());
129 this.voluntaryIncentives.add(new IncentiveSpeedWithCourtesy());
130 this.voluntaryIncentives.add(new IncentiveKeep());
131 this.accelerationIncentives.add(new AccelerationSpeedLimitTransition());
132 this.accelerationIncentives.add(new AccelerationTrafficLights());
133 this.accelerationIncentives.add(new AccelerationConflicts());
134 }
135
136
137 @Override
138 public final OperationalPlan generateOperationalPlan(final Time startTime, final DirectedPoint locationAtStartTime)
139 throws OperationalPlanException, GTUException, NetworkException, ParameterException
140 {
141
142
143 getPerception().perceive();
144 SpeedLimitProspect slp = getPerception().getPerceptionCategory(InfrastructurePerception.class)
145 .getSpeedLimitProspect(RelativeLane.CURRENT);
146 SpeedLimitInfo sli = slp.getSpeedLimitInfo(Length.ZERO);
147 BehavioralCharacteristics bc = getGtu().getBehavioralCharacteristics();
148
149
150 SimpleOperationalPlan simplePlan = LmrsUtil.determinePlan(getGtu(), startTime, getCarFollowingModel(), this.laneChange,
151 this.lmrsData, getPerception(), this.mandatoryIncentives, this.voluntaryIncentives);
152
153
154 Speed speed = getPerception().getPerceptionCategory(EgoPerception.class).getSpeed();
155 RelativeLane[] lanes = this.laneChange.isChangingLane()
156 ? new RelativeLane[] { RelativeLane.CURRENT, this.laneChange.getSecondLane(getGtu()) }
157 : new RelativeLane[] { RelativeLane.CURRENT };
158 for (AccelerationIncentive incentive : this.accelerationIncentives)
159 {
160 for (RelativeLane lane : lanes)
161 {
162 incentive.accelerate(simplePlan, lane, getGtu(), getPerception(), getCarFollowingModel(), speed, bc, sli);
163 }
164 }
165
166
167
168 if (simplePlan.isLaneChange())
169 {
170 if (getPerception().contains(DelayedNeighborsPerception.class))
171 {
172 getPerception().getPerceptionCategory(DelayedNeighborsPerception.class)
173 .changeLane(simplePlan.getLaneChangeDirection());
174 }
175 }
176
177
178 simplePlan.setTurnIndicator(getGtu());
179
180
181 return buildPlanFromSimplePlan(getGtu(), startTime, bc, simplePlan, this.laneChange);
182
183 }
184
185
186 @Override
187 public final String toString()
188 {
189 String mandatory;
190 mandatory = "mandatoryIncentives=" + this.mandatoryIncentives + ", ";
191 String voluntary;
192 if (!this.voluntaryIncentives.isEmpty())
193 {
194 voluntary = "voluntaryIncentives=" + this.voluntaryIncentives;
195 }
196 else
197 {
198 voluntary = "voluntaryIncentives=[]";
199 }
200 return "LMRS [" + mandatory + voluntary + "]";
201 }
202
203 }