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.OTSNode;
29 import org.opentrafficsim.core.units.distributions.ContinuousDistMass;
30 import org.opentrafficsim.road.gtu.generator.od.DefaultGTUCharacteristicsGeneratorOD;
31 import org.opentrafficsim.road.gtu.generator.od.ODApplier;
32 import org.opentrafficsim.road.gtu.generator.od.ODOptions;
33 import org.opentrafficsim.road.gtu.generator.od.StrategicalPlannerFactorySupplierOD;
34 import org.opentrafficsim.road.gtu.generator.od.StrategicalPlannerFactorySupplierOD.TacticalPlannerFactorySupplierOD;
35 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
36 import org.opentrafficsim.road.gtu.lane.VehicleModel;
37 import org.opentrafficsim.road.gtu.lane.VehicleModelFactory;
38 import org.opentrafficsim.road.gtu.lane.tactical.AbstractLaneBasedTacticalPlannerFactory;
39 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlannerFactory;
40 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
41 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
42 import org.opentrafficsim.road.gtu.lane.tactical.steering.SteeringLmrs;
43 import org.opentrafficsim.road.gtu.lane.tactical.util.Steering;
44 import org.opentrafficsim.road.gtu.lane.tactical.util.Steering.FeedbackTable;
45 import org.opentrafficsim.road.gtu.lane.tactical.util.Steering.FeedbackTable.FeedbackVector;
46 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
47 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance;
48 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
49 import org.opentrafficsim.road.gtu.strategical.od.Categorization;
50 import org.opentrafficsim.road.gtu.strategical.od.Category;
51 import org.opentrafficsim.road.gtu.strategical.od.Interpolation;
52 import org.opentrafficsim.road.gtu.strategical.od.ODMatrix;
53 import org.opentrafficsim.road.network.OTSRoadNetwork;
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 try
100 {
101 new SteeringSimulation(args).start();
102 }
103 catch (Exception ex)
104 {
105 ex.printStackTrace();
106 }
107 }
108
109
110
111
112 protected SteeringSimulation(final String[] properties)
113 {
114 super("Steering simulation", "Steering simulation", properties);
115 }
116
117
118
119
120
121
122
123
124 protected OTSRoadNetwork setupSimulation(final OTSSimulatorInterface sim) throws Exception
125 {
126 OTSRoadNetwork network = new OTSRoadNetwork("Steering network", true);
127 Length laneWidth = Length.createSI(3.5);
128 Length stripeWidth = Length.createSI(0.2);
129
130
131 OTSPoint3D pointA = new OTSPoint3D(0, 0);
132 OTSPoint3D pointB = new OTSPoint3D(2000, 0);
133 OTSPoint3D pointC = new OTSPoint3D(2250, 0);
134 OTSPoint3D pointD = new OTSPoint3D(3250, 0);
135 OTSPoint3D pointE = new OTSPoint3D(1500, -30);
136
137
138 OTSNode nodeA = new OTSNode(network, "A", pointA);
139 OTSNode nodeB = new OTSNode(network, "B", pointB);
140 OTSNode nodeC = new OTSNode(network, "C", pointC);
141 OTSNode nodeD = new OTSNode(network, "D", pointD);
142 OTSNode nodeE = new OTSNode(network, "E", pointE);
143
144
145 CrossSectionLink linkAB =
146 new CrossSectionLink(network, "AB", nodeA, nodeB, network.getLinkType(LinkType.DEFAULTS.FREEWAY),
147 new OTSLine3D(pointA, pointB), sim, LaneKeepingPolicy.KEEPRIGHT);
148 CrossSectionLink linkBC =
149 new CrossSectionLink(network, "BC", nodeB, nodeC, network.getLinkType(LinkType.DEFAULTS.FREEWAY),
150 new OTSLine3D(pointB, pointC), sim, LaneKeepingPolicy.KEEPRIGHT);
151 CrossSectionLink linkCD =
152 new CrossSectionLink(network, "CD", nodeC, nodeD, network.getLinkType(LinkType.DEFAULTS.FREEWAY),
153 new OTSLine3D(pointC, pointD), sim, LaneKeepingPolicy.KEEPRIGHT);
154 CrossSectionLink linkEB =
155 new CrossSectionLink(network, "EB", nodeE, nodeB, network.getLinkType(LinkType.DEFAULTS.FREEWAY),
156 Bezier.cubic(nodeE.getLocation(), nodeB.getLocation()), sim, LaneKeepingPolicy.KEEPRIGHT);
157
158
159 int n = getIntegerProperty("numberOfLanes");
160 List<Lane> originLanes = new ArrayList<>();
161 for (int i = 0; i < n; i++)
162 {
163 for (CrossSectionLink link : new CrossSectionLink[] {linkAB, linkBC, linkCD})
164 {
165 Lane lane = new Lane(link, "Lane " + (i + 1), laneWidth.multiplyBy((0.5 + i)), laneWidth,
166 network.getLaneType(LaneType.DEFAULTS.FREEWAY), new Speed(120, SpeedUnit.KM_PER_HOUR));
167 Length offset = laneWidth.multiplyBy(i + 1.0);
168 Stripe stripe = new Stripe(link, offset, offset, stripeWidth);
169 if (i < n - 1)
170 {
171 stripe.addPermeability(network.getGtuType(GTUType.DEFAULTS.VEHICLE), Permeable.BOTH);
172 }
173
174 if (lane.getParentLink().getId().equals("CD"))
175 {
176 new SinkSensor(lane, lane.getLength().minus(Length.createSI(100.0)), sim);
177
178 new Detector(lane.getFullId(), lane, Length.createSI(100.0), sim);
179 }
180 if (lane.getParentLink().getId().equals("AB"))
181 {
182 originLanes.add(lane);
183 }
184 }
185 }
186 new Stripe(linkAB, Length.ZERO, Length.ZERO, stripeWidth);
187 Stripe stripe = new Stripe(linkBC, Length.ZERO, Length.ZERO, stripeWidth);
188 stripe.addPermeability(network.getGtuType(GTUType.DEFAULTS.VEHICLE), Permeable.LEFT);
189 new Stripe(linkCD, Length.ZERO, Length.ZERO, stripeWidth);
190 new Lane(linkBC, "Acceleration lane", laneWidth.multiplyBy(-0.5), laneWidth,
191 network.getLaneType(LaneType.DEFAULTS.FREEWAY), new Speed(120, SpeedUnit.KM_PER_HOUR));
192 new Lane(linkEB, "Onramp", laneWidth.multiplyBy(-0.5), laneWidth, network.getLaneType(LaneType.DEFAULTS.FREEWAY),
193 new Speed(120, SpeedUnit.KM_PER_HOUR));
194 new Stripe(linkEB, Length.ZERO, Length.ZERO, stripeWidth);
195 new Stripe(linkEB, laneWidth.neg(), laneWidth.neg(), stripeWidth);
196 new Stripe(linkBC, laneWidth.neg(), laneWidth.neg(), stripeWidth);
197
198
199 List<OTSNode> origins = new ArrayList<>();
200 origins.add(nodeA);
201 origins.add(nodeE);
202 List<OTSNode> destinations = new ArrayList<>();
203 destinations.add(nodeD);
204 TimeVector timeVector = new TimeVector(new double[] {0.0, 0.5, 1.0}, TimeUnit.BASE_HOUR, StorageType.DENSE);
205 Interpolation interpolation = Interpolation.LINEAR;
206 Categorization categorization = new Categorization("GTU type", GTUType.class);
207 Category carCategory = new Category(categorization, network.getGtuType(GTUType.DEFAULTS.CAR));
208 Category truCategory = new Category(categorization, network.getGtuType(GTUType.DEFAULTS.TRUCK));
209 ODMatrix odMatrix = new ODMatrix("Steering OD", origins, destinations, categorization, timeVector, interpolation);
210
211 odMatrix.putDemandVector(nodeA, nodeD, carCategory, freq(new double[] {1000.0, 2000.0, 0.0}));
212 odMatrix.putDemandVector(nodeA, nodeD, truCategory, freq(new double[] {100.0, 200.0, 0.0}));
213 odMatrix.putDemandVector(nodeE, nodeD, carCategory, freq(new double[] {500.0, 1000.0, 0.0}));
214
215
216 AbstractLaneBasedTacticalPlannerFactory<SteeringLmrs> car = new AbstractLaneBasedTacticalPlannerFactory<SteeringLmrs>(
217 new IDMPlusFactory(sim.getReplication().getStream("generation")), new DefaultLMRSPerceptionFactory())
218 {
219 @Override
220 public SteeringLmrs create(final LaneBasedGTU gtu) throws GTUException
221 {
222 return new SteeringLmrs(nextCarFollowingModel(gtu), gtu, getPerceptionFactory().generatePerception(gtu),
223 Synchronization.PASSIVE, Cooperation.PASSIVE, GapAcceptance.INFORMED, FEEDBACK_CAR);
224 }
225
226 @Override
227 public Parameters getParameters() throws ParameterException
228 {
229
230 ParameterSet parameters = new ParameterSet();
231 getCarFollowingParameters().setAllIn(parameters);
232 parameters.setDefaultParameters(Steering.class);
233 return parameters;
234 }
235 };
236 TacticalPlannerFactorySupplierOD tacticalPlannerFactorySupplierOD = new TacticalPlannerFactorySupplierOD()
237 {
238 @Override
239 public LaneBasedTacticalPlannerFactory<SteeringLmrs> getFactory(final Node origin, final Node destination,
240 final Category category, final StreamInterface randomStream)
241 {
242 GTUType gtuType = category.get(GTUType.class);
243 if (gtuType.equals(network.getGtuType(GTUType.DEFAULTS.CAR)))
244 {
245 return car;
246 }
247 else
248 {
249
250 return null;
251 }
252 };
253 };
254
255
256 ContinuousDistMass massDistCar =
257 new ContinuousDistMass(new DistUniform(sim.getReplication().getStream("generation"), 600, 1200), MassUnit.SI);
258 ContinuousDistMass massDistTruck =
259 new ContinuousDistMass(new DistUniform(sim.getReplication().getStream("generation"), 2000, 10000), MassUnit.SI);
260 double momentOfInertiaAboutZ = 100;
261 VehicleModelFactory vehicleModelGenerator = new VehicleModelFactory()
262 {
263 @Override
264 public VehicleModel create(final GTUType gtuType)
265 {
266 Mass mass =
267 gtuType.isOfType(network.getGtuType(GTUType.DEFAULTS.CAR)) ? massDistCar.draw() : massDistTruck.draw();
268 return new VehicleModel.MassBased(mass, momentOfInertiaAboutZ);
269 }
270 };
271
272 DefaultGTUCharacteristicsGeneratorOD characteristicsGenerator = new DefaultGTUCharacteristicsGeneratorOD.Factory()
273 .setFactorySupplier(StrategicalPlannerFactorySupplierOD.route(tacticalPlannerFactorySupplierOD))
274 .setVehicleModelGenerator(vehicleModelGenerator).create();
275
276
277 ODOptions odOptions = new ODOptions().set(ODOptions.NO_LC_DIST, Length.createSI(300.0)).set(ODOptions.GTU_TYPE,
278 characteristicsGenerator);
279 ODApplier.applyOD(network, odMatrix, sim, odOptions);
280
281 return network;
282 }
283
284
285
286
287
288
289
290 private FrequencyVector freq(final double[] array) throws ValueException
291 {
292 return new FrequencyVector(array, FrequencyUnit.PER_HOUR, StorageType.DENSE);
293 }
294
295 }