1 package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2
3 import java.util.Optional;
4
5 import org.djunits.value.vdouble.scalar.Duration;
6 import org.djunits.value.vdouble.scalar.Length;
7 import org.djunits.value.vdouble.scalar.Speed;
8 import org.djutils.draw.point.DirectedPoint2d;
9 import org.opentrafficsim.base.parameters.ParameterException;
10 import org.opentrafficsim.base.parameters.ParameterTypes;
11 import org.opentrafficsim.base.parameters.Parameters;
12 import org.opentrafficsim.core.gtu.GtuException;
13 import org.opentrafficsim.core.gtu.perception.EgoPerception;
14 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan;
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.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 final LmrsData lmrsData;
56
57
58
59
60
61
62
63
64
65
66
67 public Lmrs(final CarFollowingModel carFollowingModel, final LaneBasedGtu gtu, final LanePerception lanePerception,
68 final Synchronization synchronization, final Cooperation cooperation, final GapAcceptance gapAcceptance,
69 final Tailgating tailgating)
70 {
71 super(carFollowingModel, gtu, lanePerception);
72 this.lmrsData = new LmrsData(synchronization, cooperation, gapAcceptance, tailgating);
73 }
74
75 @Override
76 public final OperationalPlan generateOperationalPlan(final Duration startTime, final DirectedPoint2d locationAtStartTime)
77 throws GtuException, NetworkException, ParameterException
78 {
79
80 SpeedLimitProspect slp = getPerception().getPerceptionCategory(InfrastructurePerception.class)
81 .getSpeedLimitProspect(RelativeLane.CURRENT);
82 SpeedLimitInfo sli = slp.getSpeedLimitInfo(Length.ZERO);
83 Parameters params = getGtu().getParameters();
84
85
86 SimpleOperationalPlan simplePlan = LmrsUtil.determinePlan(getGtu(), getCarFollowingModel(), this.lmrsData,
87 getPerception(), getMandatoryIncentives(), getVoluntaryIncentives());
88
89
90 Speed speed = getPerception().getPerceptionCategory(EgoPerception.class).getSpeed();
91 RelativeLane[] lanes;
92 double dLeft = params.getParameter(LmrsParameters.DLEFT);
93 double dRight = params.getParameter(LmrsParameters.DRIGHT);
94 double dSync = params.getParameter(LmrsParameters.DSYNC);
95 if (dLeft >= dSync && dLeft >= dRight)
96 {
97 lanes = new RelativeLane[] {RelativeLane.CURRENT, RelativeLane.LEFT};
98 }
99 else if (dRight >= dSync)
100 {
101 lanes = new RelativeLane[] {RelativeLane.CURRENT, RelativeLane.RIGHT};
102 }
103 else
104 {
105 lanes = new RelativeLane[] {RelativeLane.CURRENT};
106 }
107 for (RelativeLane lane : lanes)
108 {
109 if (getPerception().getLaneStructure().getRootCrossSection().contains(lane))
110 {
111
112
113
114
115 Length mergeDistance = lane.isCurrent() ? Length.ZERO
116 : Synchronization.getMergeDistance(getPerception(), lane.getLateralDirectionality());
117 for (AccelerationIncentive incentive : getAccelerationIncentives())
118 {
119 incentive.accelerate(simplePlan, lane, mergeDistance, getGtu(), getPerception(), getCarFollowingModel(),
120 speed, params, sli);
121 }
122 }
123 }
124
125
126 simplePlan.setTurnIndicator(getGtu());
127
128
129 return LaneOperationalPlanBuilder.buildPlanFromSimplePlan(getGtu(), simplePlan,
130 getGtu().getParameters().getParameter(ParameterTypes.LCDUR));
131
132 }
133
134 @Override
135 public final Optional<Desire> getLatestDesire(final Class<? extends Incentive> incentiveClass)
136 {
137 return this.lmrsData.getLatestDesire(incentiveClass);
138 }
139
140 @Override
141 public Synchronizable.State getSynchronizationState()
142 {
143 return this.lmrsData.getSynchronizationState();
144 }
145
146 @Override
147 public boolean isBlocking()
148 {
149 for (AccelerationIncentive acc : getAccelerationIncentives())
150 {
151 if (acc instanceof AccelerationConflicts)
152 {
153 return ((AccelerationConflicts) acc).isBlocking();
154 }
155 }
156 return false;
157 }
158
159 @Override
160 public final String toString()
161 {
162 return "LMRS [mandatoryIncentives=" + getMandatoryIncentives() + ", voluntaryIncentives=" + getVoluntaryIncentives()
163 + ", accelerationIncentives = " + getAccelerationIncentives() + "]";
164 }
165
166 }