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.perception.EgoPerception;
9 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
10 import org.opentrafficsim.core.network.LateralDirectionality;
11 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
12 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
13 import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
14 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
15 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
16 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
17 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
18 import org.opentrafficsim.road.network.LaneChangeInfo;
19
20
21
22
23
24
25
26
27
28
29
30 public class IncentiveStayRight implements VoluntaryIncentive
31 {
32
33 @Override
34 public Desire determineDesire(final Parameters parameters, final LanePerception perception,
35 final CarFollowingModel carFollowingModel, final Desire mandatoryDesire, final Desire voluntaryDesire)
36 throws ParameterException, OperationalPlanException
37 {
38 InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
39
40 SortedSet<RelativeLane> rootCrossSection = perception.getLaneStructure().getRootCrossSection();
41 RelativeLane lane = rootCrossSection.first();
42
43 Speed speed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
44 double curUrgency = urgency(infra.getLegalLaneChangeInfo(lane), parameters, speed);
45 double rightUrgency;
46 RelativeLane right;
47 while (rootCrossSection.contains(right = lane.getRight())
48 && (rightUrgency = urgency(infra.getLegalLaneChangeInfo(right), parameters, speed)) <= curUrgency)
49 {
50 curUrgency = rightUrgency;
51 lane = right;
52 }
53 boolean legalLeft = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.LEFT).ge0();
54 if (lane.getLateralDirectionality().isRight() && lane.getNumLanes() > 1)
55 {
56
57 return new Desire(legalLeft ? -1.0 : 0.0, parameters.getParameter(LmrsParameters.DSYNC));
58 }
59 if (lane.isRight())
60 {
61
62 return new Desire(legalLeft ? -1.0 : 0.0, 0.0);
63 }
64 return new Desire(0.0, 0.0);
65 }
66
67
68
69
70
71
72
73
74
75 private double urgency(final SortedSet<LaneChangeInfo> laneChangeInfo, final Parameters parameters, final Speed speed)
76 throws ParameterException
77 {
78 double urgency = 0.0;
79 for (LaneChangeInfo info : laneChangeInfo)
80 {
81 double nextUrgency =
82 IncentiveRoute.getDesireToLeave(parameters, info.remainingDistance(), info.numberOfLaneChanges(), speed);
83 urgency = urgency > nextUrgency ? urgency : nextUrgency;
84 }
85 return urgency;
86 }
87
88 }