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