1 package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2
3 import java.util.SortedSet;
4
5 import org.djunits.value.vdouble.scalar.Speed;
6 import org.opentrafficsim.base.parameters.ParameterException;
7 import org.opentrafficsim.base.parameters.Parameters;
8 import org.opentrafficsim.core.gtu.Stateless;
9 import org.opentrafficsim.core.gtu.perception.EgoPerception;
10 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
11 import org.opentrafficsim.core.network.LateralDirectionality;
12 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
13 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
14 import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
15 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
16 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
17 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
18 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
19 import org.opentrafficsim.road.network.LaneChangeInfo;
20
21
22
23
24
25
26
27
28
29
30
31 public final class IncentiveStayRight implements VoluntaryIncentive, Stateless<IncentiveStayRight>
32 {
33
34
35 public static final IncentiveStayRight SINGLETON = new IncentiveStayRight();
36
37 @Override
38 public IncentiveStayRight get()
39 {
40 return SINGLETON;
41 }
42
43
44
45
46 private IncentiveStayRight()
47 {
48
49 }
50
51 @Override
52 public Desire determineDesire(final Parameters parameters, final LanePerception perception,
53 final CarFollowingModel carFollowingModel, final Desire mandatoryDesire, final Desire voluntaryDesire)
54 throws ParameterException, OperationalPlanException
55 {
56 InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
57
58 SortedSet<RelativeLane> rootCrossSection = perception.getLaneStructure().getRootCrossSection();
59 RelativeLane lane = rootCrossSection.first();
60
61 Speed speed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
62 double curUrgency = urgency(infra.getLegalLaneChangeInfo(lane), parameters, speed);
63 double rightUrgency;
64 RelativeLane right;
65 while (rootCrossSection.contains(right = lane.getRight())
66 && (rightUrgency = urgency(infra.getLegalLaneChangeInfo(right), parameters, speed)) <= curUrgency)
67 {
68 curUrgency = rightUrgency;
69 lane = right;
70 }
71 boolean legalLeft = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.LEFT).ge0();
72 if (lane.getLateralDirectionality().isRight() && lane.getNumLanes() > 1)
73 {
74
75 return new Desire(legalLeft ? -1.0 : 0.0, parameters.getParameter(LmrsParameters.DSYNC));
76 }
77 if (lane.isRight())
78 {
79
80 return new Desire(legalLeft ? -1.0 : 0.0, 0.0);
81 }
82 return new Desire(0.0, 0.0);
83 }
84
85
86
87
88
89
90
91
92
93 private double urgency(final SortedSet<LaneChangeInfo> laneChangeInfo, final Parameters parameters, final Speed speed)
94 throws ParameterException
95 {
96 double urgency = 0.0;
97 for (LaneChangeInfo info : laneChangeInfo)
98 {
99 double nextUrgency =
100 IncentiveRoute.getDesireToLeave(parameters, info.remainingDistance(), info.numberOfLaneChanges(), speed);
101 urgency = urgency > nextUrgency ? urgency : nextUrgency;
102 }
103 return urgency;
104 }
105
106 @Override
107 public String toString()
108 {
109 return "IncentiveStayRight";
110 }
111
112 }