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
34 @Override
35 public Desire determineDesire(final Parameters parameters, final LanePerception perception,
36 final CarFollowingModel carFollowingModel, final Desire mandatoryDesire, final Desire voluntaryDesire)
37 throws ParameterException, OperationalPlanException
38 {
39 InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
40
41 SortedSet<RelativeLane> rootCrossSection = perception.getLaneStructure().getRootCrossSection();
42 RelativeLane lane = rootCrossSection.first();
43
44 Speed speed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
45 double curUrgency = urgency(infra.getLegalLaneChangeInfo(lane), parameters, speed);
46 double rightUrgency;
47 RelativeLane right;
48 while (rootCrossSection.contains(right = lane.getRight())
49 && (rightUrgency = urgency(infra.getLegalLaneChangeInfo(right), parameters, speed)) <= curUrgency)
50 {
51 curUrgency = rightUrgency;
52 lane = right;
53 }
54 boolean legalLeft = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.LEFT).ge0();
55 if (lane.getLateralDirectionality().isRight() && lane.getNumLanes() > 1)
56 {
57
58 return new Desire(legalLeft ? -1.0 : 0.0, parameters.getParameter(LmrsParameters.DSYNC));
59 }
60 if (lane.isRight())
61 {
62
63 return new Desire(legalLeft ? -1.0 : 0.0, 0.0);
64 }
65 return new Desire(0.0, 0.0);
66 }
67
68
69
70
71
72
73
74
75
76 private double urgency(final SortedSet<LaneChangeInfo> laneChangeInfo, final Parameters parameters, final Speed speed)
77 throws ParameterException
78 {
79 double urgency = 0.0;
80 for (LaneChangeInfo info : laneChangeInfo)
81 {
82 double nextUrgency =
83 IncentiveRoute.getDesireToLeave(parameters, info.remainingDistance(), info.numberOfLaneChanges(), speed);
84 urgency = urgency > nextUrgency ? urgency : nextUrgency;
85 }
86 return urgency;
87 }
88
89 }