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