1 package org.opentrafficsim.road.network.factory.xml.parser;
2
3 import java.util.ArrayList;
4 import java.util.LinkedHashSet;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.Set;
8
9 import org.djunits.unit.DurationUnit;
10 import org.djunits.value.vdouble.scalar.Duration;
11 import org.djunits.value.vdouble.scalar.Frequency;
12 import org.djunits.value.vdouble.scalar.Length;
13 import org.djunits.value.vdouble.scalar.Speed;
14 import org.opentrafficsim.base.parameters.ParameterException;
15 import org.opentrafficsim.core.distributions.Distribution;
16 import org.opentrafficsim.core.distributions.Distribution.FrequencyAndObject;
17 import org.opentrafficsim.core.distributions.Generator;
18 import org.opentrafficsim.core.distributions.ProbabilityException;
19 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
20 import org.opentrafficsim.core.gtu.GTUDirectionality;
21 import org.opentrafficsim.core.gtu.GTUType;
22 import org.opentrafficsim.core.idgenerator.IdGenerator;
23 import org.opentrafficsim.core.network.NetworkException;
24 import org.opentrafficsim.core.network.route.FixedRouteGenerator;
25 import org.opentrafficsim.core.network.route.Route;
26 import org.opentrafficsim.road.gtu.generator.GeneratorPositions;
27 import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator;
28 import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator.RoomChecker;
29 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedTemplateGTUType;
30 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedTemplateGTUTypeDistribution;
31 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlannerFactory;
32 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModelFactory;
33 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlus;
34 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
35 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
36 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRS;
37 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
38 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
39 import org.opentrafficsim.road.network.OTSRoadNetwork;
40 import org.opentrafficsim.road.network.factory.xml.XmlParserException;
41 import org.opentrafficsim.road.network.factory.xml.utils.Generators;
42 import org.opentrafficsim.road.network.factory.xml.utils.StreamInformation;
43 import org.opentrafficsim.road.network.factory.xml.utils.Transformer;
44 import org.opentrafficsim.road.network.lane.CrossSectionLink;
45 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
46 import org.opentrafficsim.road.network.lane.Lane;
47 import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
48 import org.opentrafficsim.xml.generated.GENERATOR;
49 import org.opentrafficsim.xml.generated.GTUTEMPLATE;
50 import org.opentrafficsim.xml.generated.NETWORKDEMAND;
51 import org.opentrafficsim.xml.generated.SINK;
52
53 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
54 import nl.tudelft.simulation.jstats.streams.StreamInterface;
55
56
57
58
59
60
61
62
63
64 public class GeneratorSinkParser
65 {
66
67
68 private GeneratorSinkParser()
69 {
70
71 }
72
73
74
75
76
77
78
79
80
81
82
83 public static List<LaneBasedGTUGenerator> parseGenerators(final OTSRoadNetwork otsNetwork, final NETWORKDEMAND demand,
84 Map<String, GTUTEMPLATE> gtuTemplates, final OTSSimulatorInterface simulator,
85 Map<String, StreamInformation> streamMap) throws XmlParserException
86 {
87 List<LaneBasedGTUGenerator> generators = new ArrayList<>();
88 try
89 {
90 for (GENERATOR generatorTag : demand.getGENERATOR())
91 {
92
93 if (simulator.getReplication().getStream("generation") == null)
94 {
95 simulator.getReplication().getStreams().put("generation", new MersenneTwister(1L));
96 }
97 StreamInterface stream = simulator.getReplication().getStream("generation");
98
99 Generator<Route> routeGenerator;
100 if (generatorTag.getROUTE() != null)
101 {
102 Route route = otsNetwork.getRoute(generatorTag.getROUTE());
103 if (route == null)
104 throw new XmlParserException("Route " + generatorTag.getROUTE() + " not found");
105 routeGenerator = new FixedRouteGenerator(route);
106 }
107 else if (generatorTag.getROUTEMIX() != null)
108 {
109
110 throw new XmlParserException("RouteMix not implemented yet in GENERATOR");
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132 }
133 else if (generatorTag.getSHORTESTROUTE() != null)
134 {
135 Route shortestRoute = otsNetwork.getRoute(generatorTag.getSHORTESTROUTE());
136 if (shortestRoute == null)
137 throw new XmlParserException("ShortestRoute " + generatorTag.getSHORTESTROUTE() + " not found");
138 routeGenerator = new FixedRouteGenerator(shortestRoute);
139 }
140 else if (generatorTag.getSHORTESTROUTE() != null)
141 {
142
143 throw new XmlParserException("ShortestRouteMix not implemented yet in GENERATOR");
144 }
145 else
146 {
147 throw new XmlParserException("No route information in GENERATOR");
148 }
149
150 CarFollowingModelFactory<IDMPlus> idmPlusFactory = new IDMPlusFactory(streamMap.get("generation").getStream());
151 LaneBasedTacticalPlannerFactory<LMRS> tacticalFactory =
152 new LMRSFactory(idmPlusFactory, new DefaultLMRSPerceptionFactory());
153 LaneBasedStrategicalRoutePlannerFactory strategicalFactory =
154 new LaneBasedStrategicalRoutePlannerFactory(tacticalFactory);
155
156
157 Distribution<LaneBasedTemplateGTUType> gtuTypeDistribution =
158 new Distribution<>(streamMap.get("generation").getStream());
159 if (generatorTag.getGTUTEMPLATE() != null)
160 {
161 GTUTEMPLATE templateTag = gtuTemplates.get(generatorTag.getGTUTEMPLATE());
162 if (templateTag == null)
163 throw new XmlParserException(
164 "GTUTEMPLATE " + generatorTag.getGTUTEMPLATE() + " in generator not defined");
165 GTUType gtuType = otsNetwork.getGtuType(templateTag.getGTUTYPE());
166 if (gtuType == null)
167 throw new XmlParserException("GTUTYPE " + templateTag.getGTUTYPE() + " in GTUTEMPLATE "
168 + generatorTag.getGTUTEMPLATE() + " not defined");
169 Generator<Length> lengthGenerator = Generators.makeLengthGenerator(streamMap, templateTag.getLENGTHDIST());
170 Generator<Length> widthGenerator = Generators.makeLengthGenerator(streamMap, templateTag.getWIDTHDIST());
171 Generator<Speed> maximumSpeedGenerator =
172 Generators.makeSpeedGenerator(streamMap, templateTag.getMAXSPEEDDIST());
173 LaneBasedTemplateGTUType templateGTUType = new LaneBasedTemplateGTUType(gtuType, lengthGenerator,
174 widthGenerator, maximumSpeedGenerator, strategicalFactory, routeGenerator);
175 gtuTypeDistribution.add(new FrequencyAndObject<>(1.0, templateGTUType));
176 }
177 else if (generatorTag.getGTUTEMPLATEMIX() != null)
178 {
179
180 throw new XmlParserException("GtuTemplateMix not implemented yet in GENERATOR");
181 }
182 else
183 {
184 throw new XmlParserException("No GTU information in GENERATOR");
185 }
186
187 RoomChecker roomChecker = Transformer.parseRoomChecker(generatorTag.getROOMCHECKER());
188
189 Generator<Duration> headwayGenerator =
190 new HeadwayGenerator(generatorTag.getFREQUENCY(), streamMap.get("generation").getStream());
191
192 CrossSectionLink link = (CrossSectionLink) otsNetwork.getLink(generatorTag.getLINK());
193 Lane lane = (Lane) link.getCrossSectionElement(generatorTag.getLANE());
194
195 Length position = Length.createSI(5.0);
196 GTUDirectionality direction = GTUDirectionality.valueOf(generatorTag.getDIRECTION());
197 Set<DirectedLanePosition> initialLongitudinalPositions = new LinkedHashSet<>();
198 initialLongitudinalPositions
199 .add(new DirectedLanePosition(lane, position, direction));
200
201 IdGenerator idGenerator = new IdGenerator(lane.getFullId());
202
203 LaneBasedTemplateGTUTypeDistribution characteristicsGenerator =
204 new LaneBasedTemplateGTUTypeDistribution(gtuTypeDistribution);
205 generators.add(new LaneBasedGTUGenerator(lane.getFullId(), headwayGenerator, characteristicsGenerator,
206 GeneratorPositions.create(initialLongitudinalPositions, stream), otsNetwork, simulator, roomChecker,
207 idGenerator));
208 }
209 }
210 catch (Exception exception)
211 {
212 throw new XmlParserException(exception);
213 }
214 return generators;
215 }
216
217
218
219
220
221
222
223
224 public static void parseSinks(final OTSRoadNetwork otsNetwork, final NETWORKDEMAND demand,
225 final OTSSimulatorInterface simulator) throws NetworkException
226 {
227 for (SINK sinkTag : demand.getSINK())
228 {
229 CrossSectionLink link = (CrossSectionLink) otsNetwork.getLink(sinkTag.getLINK());
230 Lane lane = (Lane) link.getCrossSectionElement(sinkTag.getLANE());
231 Length position = Transformer.parseLengthBeginEnd(sinkTag.getPOSITION(), lane.getLength());
232 new SinkSensor(lane, position, simulator);
233 }
234 }
235
236
237
238
239
240
241
242
243
244
245
246
247 private static class HeadwayGenerator implements Generator<Duration>
248 {
249
250 private final Frequency demand;
251
252
253 private final StreamInterface stream;
254
255
256
257
258
259 HeadwayGenerator(final Frequency demand, final StreamInterface stream)
260 {
261 this.demand = demand;
262 this.stream = stream;
263 }
264
265
266 @Override
267 public Duration draw() throws ProbabilityException, ParameterException
268 {
269 return new Duration(-Math.log(this.stream.nextDouble()) / this.demand.si, DurationUnit.SI);
270 }
271
272 }
273 }