1 package org.opentrafficsim.demo.steering;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.djunits.unit.FrequencyUnit;
7 import org.djunits.unit.MassUnit;
8 import org.djunits.unit.SpeedUnit;
9 import org.djunits.unit.TimeUnit;
10 import org.djunits.value.StorageType;
11 import org.djunits.value.ValueException;
12 import org.djunits.value.vdouble.scalar.Length;
13 import org.djunits.value.vdouble.scalar.Mass;
14 import org.djunits.value.vdouble.scalar.Speed;
15 import org.djunits.value.vdouble.vector.FrequencyVector;
16 import org.djunits.value.vdouble.vector.TimeVector;
17 import org.opentrafficsim.base.parameters.ParameterException;
18 import org.opentrafficsim.base.parameters.ParameterSet;
19 import org.opentrafficsim.base.parameters.Parameters;
20 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
21 import org.opentrafficsim.core.geometry.Bezier;
22 import org.opentrafficsim.core.geometry.OTSLine3D;
23 import org.opentrafficsim.core.geometry.OTSPoint3D;
24 import org.opentrafficsim.core.gtu.GTUException;
25 import org.opentrafficsim.core.gtu.GTUType;
26 import org.opentrafficsim.core.network.LinkType;
27 import org.opentrafficsim.core.network.Node;
28 import org.opentrafficsim.core.network.OTSNetwork;
29 import org.opentrafficsim.core.network.OTSNode;
30 import org.opentrafficsim.core.units.distributions.ContinuousDistMass;
31 import org.opentrafficsim.road.gtu.generator.od.DefaultGTUCharacteristicsGeneratorOD;
32 import org.opentrafficsim.road.gtu.generator.od.ODApplier;
33 import org.opentrafficsim.road.gtu.generator.od.ODOptions;
34 import org.opentrafficsim.road.gtu.generator.od.StrategicalPlannerFactorySupplierOD;
35 import org.opentrafficsim.road.gtu.generator.od.StrategicalPlannerFactorySupplierOD.TacticalPlannerFactorySupplierOD;
36 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
37 import org.opentrafficsim.road.gtu.lane.VehicleModel;
38 import org.opentrafficsim.road.gtu.lane.VehicleModelFactory;
39 import org.opentrafficsim.road.gtu.lane.tactical.AbstractLaneBasedTacticalPlannerFactory;
40 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlannerFactory;
41 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
42 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
43 import org.opentrafficsim.road.gtu.lane.tactical.steering.SteeringLmrs;
44 import org.opentrafficsim.road.gtu.lane.tactical.util.Steering;
45 import org.opentrafficsim.road.gtu.lane.tactical.util.Steering.FeedbackTable;
46 import org.opentrafficsim.road.gtu.lane.tactical.util.Steering.FeedbackTable.FeedbackVector;
47 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
48 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance;
49 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
50 import org.opentrafficsim.road.gtu.strategical.od.Categorization;
51 import org.opentrafficsim.road.gtu.strategical.od.Category;
52 import org.opentrafficsim.road.gtu.strategical.od.Interpolation;
53 import org.opentrafficsim.road.gtu.strategical.od.ODMatrix;
54 import org.opentrafficsim.road.network.lane.CrossSectionLink;
55 import org.opentrafficsim.road.network.lane.Lane;
56 import org.opentrafficsim.road.network.lane.LaneType;
57 import org.opentrafficsim.road.network.lane.Stripe;
58 import org.opentrafficsim.road.network.lane.Stripe.Permeable;
59 import org.opentrafficsim.road.network.lane.changing.LaneKeepingPolicy;
60 import org.opentrafficsim.road.network.lane.object.sensor.Detector;
61 import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
62 import org.opentrafficsim.swing.script.AbstractSimulationScript;
63
64 import nl.tudelft.simulation.jstats.distributions.DistUniform;
65 import nl.tudelft.simulation.jstats.streams.StreamInterface;
66
67
68
69
70
71
72
73
74
75
76
77
78 public class SteeringSimulation extends AbstractSimulationScript
79 {
80
81
82 static final FeedbackTable FEEDBACK_CAR;
83
84 static
85 {
86
87 List<FeedbackVector> list = new ArrayList<>();
88 list.add(new FeedbackVector(new Speed(25.0, SpeedUnit.KM_PER_HOUR), 0.0, 0.0, 0.0, 0.0));
89 list.add(new FeedbackVector(new Speed(75.0, SpeedUnit.KM_PER_HOUR), 0.0, 0.0, 0.0, 0.0));
90 FEEDBACK_CAR = new FeedbackTable(list);
91 }
92
93
94
95
96
97 public static void main(final String... args)
98 {
99 new SteeringSimulation(args).start();
100 }
101
102
103
104
105 protected SteeringSimulation(final String[] properties)
106 {
107 super("Steering simulation", "Steering simulation", properties);
108 }
109
110
111
112
113
114
115
116
117 protected OTSNetwork setupSimulation(final OTSSimulatorInterface sim) throws Exception
118 {
119 OTSNetwork network = new OTSNetwork("Steering network");
120 Length laneWidth = Length.createSI(3.5);
121 Length stripeWidth = Length.createSI(0.2);
122
123
124 OTSPoint3D pointA = new OTSPoint3D(0, 0);
125 OTSPoint3D pointB = new OTSPoint3D(2000, 0);
126 OTSPoint3D pointC = new OTSPoint3D(2250, 0);
127 OTSPoint3D pointD = new OTSPoint3D(3250, 0);
128 OTSPoint3D pointE = new OTSPoint3D(1500, -30);
129
130
131 OTSNode nodeA = new OTSNode(network, "A", pointA);
132 OTSNode nodeB = new OTSNode(network, "B", pointB);
133 OTSNode nodeC = new OTSNode(network, "C", pointC);
134 OTSNode nodeD = new OTSNode(network, "D", pointD);
135 OTSNode nodeE = new OTSNode(network, "E", pointE);
136
137
138 CrossSectionLink linkAB = new CrossSectionLink(network, "AB", nodeA, nodeB, LinkType.FREEWAY,
139 new OTSLine3D(pointA, pointB), sim, LaneKeepingPolicy.KEEP_RIGHT);
140 CrossSectionLink linkBC = new CrossSectionLink(network, "BC", nodeB, nodeC, LinkType.FREEWAY,
141 new OTSLine3D(pointB, pointC), sim, LaneKeepingPolicy.KEEP_RIGHT);
142 CrossSectionLink linkCD = new CrossSectionLink(network, "CD", nodeC, nodeD, LinkType.FREEWAY,
143 new OTSLine3D(pointC, pointD), sim, LaneKeepingPolicy.KEEP_RIGHT);
144 CrossSectionLink linkEB = new CrossSectionLink(network, "EB", nodeE, nodeB, LinkType.FREEWAY,
145 Bezier.cubic(nodeE.getLocation(), nodeB.getLocation()), sim, LaneKeepingPolicy.KEEP_RIGHT);
146
147
148 int n = getIntegerProperty("numberOfLanes");
149 List<Lane> originLanes = new ArrayList<>();
150 for (int i = 0; i < n; i++)
151 {
152 for (CrossSectionLink link : new CrossSectionLink[] { linkAB, linkBC, linkCD })
153 {
154 Lane lane = new Lane(link, "Lane " + (i + 1), laneWidth.multiplyBy((0.5 + i)), laneWidth, LaneType.FREEWAY,
155 new Speed(120, SpeedUnit.KM_PER_HOUR), null);
156 Length offset = laneWidth.multiplyBy(i + 1.0);
157 Stripe stripe = new Stripe(link, offset, offset, stripeWidth);
158 if (i < n - 1)
159 {
160 stripe.addPermeability(GTUType.VEHICLE, Permeable.BOTH);
161 }
162
163 if (lane.getParentLink().getId().equals("CD"))
164 {
165 new SinkSensor(lane, lane.getLength().minus(Length.createSI(100.0)), sim);
166
167 new Detector(lane.getFullId(), lane, Length.createSI(100.0), sim);
168 }
169 if (lane.getParentLink().getId().equals("AB"))
170 {
171 originLanes.add(lane);
172 }
173 }
174 }
175 new Stripe(linkAB, Length.ZERO, Length.ZERO, stripeWidth);
176 Stripe stripe = new Stripe(linkBC, Length.ZERO, Length.ZERO, stripeWidth);
177 stripe.addPermeability(GTUType.VEHICLE, Permeable.LEFT);
178 new Stripe(linkCD, Length.ZERO, Length.ZERO, stripeWidth);
179 new Lane(linkBC, "Acceleration lane", laneWidth.multiplyBy(-0.5), laneWidth, LaneType.FREEWAY,
180 new Speed(120, SpeedUnit.KM_PER_HOUR), null);
181 new Lane(linkEB, "Onramp", laneWidth.multiplyBy(-0.5), laneWidth, LaneType.FREEWAY,
182 new Speed(120, SpeedUnit.KM_PER_HOUR), null);
183 new Stripe(linkEB, Length.ZERO, Length.ZERO, stripeWidth);
184 new Stripe(linkEB, laneWidth.neg(), laneWidth.neg(), stripeWidth);
185 new Stripe(linkBC, laneWidth.neg(), laneWidth.neg(), stripeWidth);
186
187
188 List<OTSNode> origins = new ArrayList<>();
189 origins.add(nodeA);
190 origins.add(nodeE);
191 List<OTSNode> destinations = new ArrayList<>();
192 destinations.add(nodeD);
193 TimeVector timeVector = new TimeVector(new double[] { 0.0, 0.5, 1.0 }, TimeUnit.BASE_HOUR, StorageType.DENSE);
194 Interpolation interpolation = Interpolation.LINEAR;
195 Categorization categorization = new Categorization("GTU type", GTUType.class);
196 Category carCategory = new Category(categorization, GTUType.CAR);
197 Category truCategory = new Category(categorization, GTUType.TRUCK);
198 ODMatrix odMatrix = new ODMatrix("Steering OD", origins, destinations, categorization, timeVector, interpolation);
199
200 odMatrix.putDemandVector(nodeA, nodeD, carCategory, freq(new double[] { 1000.0, 2000.0, 0.0 }));
201 odMatrix.putDemandVector(nodeA, nodeD, truCategory, freq(new double[] { 100.0, 200.0, 0.0 }));
202 odMatrix.putDemandVector(nodeE, nodeD, carCategory, freq(new double[] { 500.0, 1000.0, 0.0 }));
203
204
205 AbstractLaneBasedTacticalPlannerFactory<SteeringLmrs> car = new AbstractLaneBasedTacticalPlannerFactory<SteeringLmrs>(
206 new IDMPlusFactory(sim.getReplication().getStream("generation")), new DefaultLMRSPerceptionFactory())
207 {
208 @Override
209 public SteeringLmrs create(final LaneBasedGTU gtu) throws GTUException
210 {
211 return new SteeringLmrs(nextCarFollowingModel(gtu), gtu, getPerceptionFactory().generatePerception(gtu),
212 Synchronization.PASSIVE, Cooperation.PASSIVE, GapAcceptance.INFORMED, FEEDBACK_CAR);
213 }
214
215 @Override
216 public Parameters getParameters() throws ParameterException
217 {
218
219 ParameterSet parameters = new ParameterSet();
220 getCarFollowingParameters().setAllIn(parameters);
221 parameters.setDefaultParameters(Steering.class);
222 return parameters;
223 }
224 };
225 TacticalPlannerFactorySupplierOD tacticalPlannerFactorySupplierOD = new TacticalPlannerFactorySupplierOD()
226 {
227 @Override
228 public LaneBasedTacticalPlannerFactory<SteeringLmrs> getFactory(final Node origin, final Node destination,
229 final Category category, final StreamInterface randomStream)
230 {
231 GTUType gtuType = category.get(GTUType.class);
232 if (gtuType.equals(GTUType.CAR))
233 {
234 return car;
235 }
236 else
237 {
238
239 return null;
240 }
241 };
242 };
243
244
245 ContinuousDistMass massDistCar =
246 new ContinuousDistMass(new DistUniform(sim.getReplication().getStream("generation"), 600, 1200), MassUnit.SI);
247 ContinuousDistMass massDistTruck =
248 new ContinuousDistMass(new DistUniform(sim.getReplication().getStream("generation"), 2000, 10000), MassUnit.SI);
249 double momentOfInertiaAboutZ = 100;
250 VehicleModelFactory vehicleModelGenerator = new VehicleModelFactory()
251 {
252 @Override
253 public VehicleModel create(final GTUType gtuType)
254 {
255 Mass mass = gtuType.isOfType(GTUType.CAR) ? massDistCar.draw() : massDistTruck.draw();
256 return new VehicleModel.MassBased(mass, momentOfInertiaAboutZ);
257 }
258 };
259
260 DefaultGTUCharacteristicsGeneratorOD characteristicsGenerator = new DefaultGTUCharacteristicsGeneratorOD.Factory()
261 .setFactorySupplier(StrategicalPlannerFactorySupplierOD.route(tacticalPlannerFactorySupplierOD))
262 .setVehicleModelGenerator(vehicleModelGenerator).create();
263
264
265 ODOptions odOptions = new ODOptions().set(ODOptions.NO_LC_DIST, Length.createSI(300.0)).set(ODOptions.GTU_TYPE,
266 characteristicsGenerator);
267 ODApplier.applyOD(network, odMatrix, sim, odOptions);
268
269 return network;
270 }
271
272
273
274
275
276
277
278 private FrequencyVector freq(final double[] array) throws ValueException
279 {
280 return new FrequencyVector(array, FrequencyUnit.PER_HOUR, StorageType.DENSE);
281 }
282
283 }