1 package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2
3 import org.djunits.value.vdouble.scalar.Length;
4 import org.djunits.value.vdouble.scalar.Speed;
5 import org.djutils.exceptions.Try;
6 import org.opentrafficsim.base.parameters.ParameterException;
7 import org.opentrafficsim.base.parameters.ParameterTypeDouble;
8 import org.opentrafficsim.base.parameters.ParameterTypeLength;
9 import org.opentrafficsim.base.parameters.ParameterTypeSpeed;
10 import org.opentrafficsim.base.parameters.ParameterTypes;
11 import org.opentrafficsim.base.parameters.Parameters;
12 import org.opentrafficsim.core.gtu.Stateless;
13 import org.opentrafficsim.core.gtu.perception.EgoPerception;
14 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
15 import org.opentrafficsim.core.network.LateralDirectionality;
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.PerceptionCollectable;
19 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
20 import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
21 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
22 import org.opentrafficsim.road.gtu.lane.perception.object.PerceivedGtu;
23 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
24 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
25 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
26 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
27 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public final class IncentiveSocioSpeed implements VoluntaryIncentive, Stateless<IncentiveSocioSpeed>
43 {
44
45
46 protected static final ParameterTypeDouble RHO = Tailgating.RHO;
47
48
49 protected static final ParameterTypeDouble SOCIO = LmrsParameters.SOCIO;
50
51
52 protected static final ParameterTypeSpeed VCONG = ParameterTypes.VCONG;
53
54
55 protected static final ParameterTypeSpeed VGAIN = LmrsParameters.VGAIN;
56
57
58 protected static final ParameterTypeLength LOOKAHEAD = ParameterTypes.LOOKAHEAD;
59
60
61 public static final IncentiveSocioSpeed SINGLETON = new IncentiveSocioSpeed();
62
63 @Override
64 public IncentiveSocioSpeed get()
65 {
66 return SINGLETON;
67 }
68
69
70
71
72 private IncentiveSocioSpeed()
73 {
74
75 }
76
77 @Override
78 public Desire determineDesire(final Parameters parameters, final LanePerception perception,
79 final CarFollowingModel carFollowingModel, final Desire mandatoryDesire, final Desire voluntaryDesire)
80 throws ParameterException, OperationalPlanException
81 {
82 double dLeft = 0;
83 double dRight = 0;
84 Speed vCong = parameters.getParameter(VCONG);
85 Speed ownSpeed = perception.getPerceptionCategoryOrNull(EgoPerception.class).getSpeed();
86 if (ownSpeed.gt(vCong))
87 {
88 double sigma = parameters.getParameter(SOCIO);
89 NeighborsPerception neighbors = perception.getPerceptionCategory(NeighborsPerception.class);
90 InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
91 boolean leftLane = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.LEFT).si > 0.0;
92 boolean rightLane = infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.RIGHT).si > 0.0;
93
94 if (rightLane && mandatoryDesire.right() >= 0.0)
95 {
96 PerceptionCollectable<PerceivedGtu, LaneBasedGtu> followers = neighbors.getFollowers(RelativeLane.CURRENT);
97 if (!followers.isEmpty())
98 {
99 double rho = parameters.getParameter(RHO);
100 PerceivedGtu follower = followers.first();
101 double rhoFollower = follower.getBehavior().getParameters().getParameter(RHO);
102 if (rhoFollower * sigma > rho)
103 {
104 dRight = rhoFollower * sigma;
105 }
106 }
107 }
108
109 if (leftLane && mandatoryDesire.left() <= 0.0)
110 {
111 PerceptionCollectable<PerceivedGtu, LaneBasedGtu> followers = neighbors.getFollowers(RelativeLane.LEFT);
112 if (followers != null && !followers.isEmpty())
113 {
114 double rho;
115 PerceptionCollectable<PerceivedGtu, LaneBasedGtu> leaders = neighbors.getLeaders(RelativeLane.LEFT);
116 if (leaders != null && !leaders.isEmpty())
117 {
118 PerceivedGtu leader = leaders.first();
119 Speed vDes = Try.assign(() -> perception.getGtu().getDesiredSpeed(),
120 "Could not obtain GTU from perception.");
121 Speed vGain = parameters.getParameter(VGAIN);
122 Length x0 = parameters.getParameter(LOOKAHEAD);
123 rho = Tailgating.socialPressure(ownSpeed, vCong, vDes, leader.getSpeed(), vGain, leader.getDistance(),
124 x0);
125 }
126 else
127 {
128 rho = 0.0;
129 }
130 PerceivedGtu follower = followers.first();
131 Speed vGainFollower = follower.getBehavior().getParameters().getParameter(VGAIN);
132 Length x0Follower = follower.getBehavior().getParameters().getParameter(LOOKAHEAD);
133 double rhoFollower =
134 Tailgating.socialPressure(follower.getSpeed(), vCong, follower.getBehavior().getDesiredSpeed(),
135 ownSpeed, vGainFollower, follower.getDistance(), x0Follower);
136 if (rhoFollower * sigma > rho)
137 {
138 dLeft = -rhoFollower * sigma;
139 }
140 }
141 }
142 }
143 return new Desire(dLeft, dRight);
144 }
145
146 @Override
147 public String toString()
148 {
149 return "IncentiveSocioSpeed";
150 }
151
152 }