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