1 package org.opentrafficsim.road.gtu.generator.characteristics;
2
3 import java.util.LinkedHashMap;
4 import java.util.LinkedHashSet;
5 import java.util.Map;
6 import java.util.Optional;
7 import java.util.Set;
8 import java.util.function.BiFunction;
9 import java.util.function.Supplier;
10
11 import org.djutils.exceptions.Throw;
12 import org.djutils.exceptions.Try;
13 import org.opentrafficsim.core.definitions.Defaults;
14 import org.opentrafficsim.core.definitions.DefaultsNl;
15 import org.opentrafficsim.core.gtu.GtuCharacteristics;
16 import org.opentrafficsim.core.gtu.GtuException;
17 import org.opentrafficsim.core.gtu.GtuTemplate;
18 import org.opentrafficsim.core.gtu.GtuType;
19 import org.opentrafficsim.core.network.Node;
20 import org.opentrafficsim.core.network.route.Route;
21 import org.opentrafficsim.road.gtu.lane.VehicleModel;
22 import org.opentrafficsim.road.gtu.lane.VehicleModelFactory;
23 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.Lmrs;
24 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LmrsFactory;
25 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LmrsFactory.Setting;
26 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
27 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalRoutePlannerFactory;
28 import org.opentrafficsim.road.od.Categorization;
29 import org.opentrafficsim.road.od.Category;
30
31 import nl.tudelft.simulation.jstats.streams.StreamInterface;
32
33
34
35
36
37
38
39
40
41
42
43 public final class DefaultLaneBasedGtuCharacteristicsGeneratorOd implements LaneBasedGtuCharacteristicsGeneratorOd
44 {
45
46 private Supplier<GtuType> gtuTypeGenerator = null;
47
48
49 private final Map<GtuType, GtuTemplate> templates = new LinkedHashMap<>();
50
51
52 private final LaneBasedStrategicalPlannerFactory<?> factory;
53
54
55 private VehicleModelFactory vehicleModelFactory = VehicleModelFactory.MINMAX;
56
57
58 private BiFunction<GtuType, StreamInterface, Optional<GtuTemplate>> templateFunction;
59
60
61
62
63
64
65
66
67
68 private DefaultLaneBasedGtuCharacteristicsGeneratorOd(final Supplier<GtuType> gtuTypeGenerator,
69 final Set<GtuTemplate> templates, final LaneBasedStrategicalPlannerFactory<?> factory,
70 final VehicleModelFactory vehicleModelFactory,
71 final BiFunction<GtuType, StreamInterface, Optional<GtuTemplate>> templateFunction)
72 {
73 Throw.whenNull(factory, "Strategical planner factory may not be null.");
74 this.gtuTypeGenerator = gtuTypeGenerator;
75 if (templates != null)
76 {
77 for (GtuTemplate template : templates)
78 {
79 this.templates.put(template.getGtuType(), template);
80 }
81 }
82 this.factory = factory;
83 if (vehicleModelFactory == null)
84 {
85 this.vehicleModelFactory = VehicleModelFactory.MINMAX;
86 }
87 else
88 {
89 this.vehicleModelFactory = vehicleModelFactory;
90 }
91 this.templateFunction = templateFunction;
92 }
93
94 @Override
95 public LaneBasedGtuCharacteristics draw(final Node origin, final Node destination, final Category category,
96 final StreamInterface randomStream) throws GtuException
97 {
98 Categorization categorization = category.getCategorization();
99
100 GtuType gtuType;
101 if (categorization.entails(GtuType.class))
102 {
103 gtuType = category.get(GtuType.class);
104 }
105 else if (this.gtuTypeGenerator != null)
106 {
107 gtuType = Try.assign(() -> this.gtuTypeGenerator.get(), GtuException.class, "Parameter while drawing GTU type.");
108 }
109 else
110 {
111 gtuType = DefaultsNl.CAR;
112 }
113 GtuCharacteristics gtuCharacteristics;
114 if (this.templates.containsKey(gtuType))
115 {
116 gtuCharacteristics =
117 Try.assign(() -> this.templates.get(gtuType).get(), "Exception while drawing GTU characteristics.");
118 }
119 else
120 {
121 gtuCharacteristics = this.templateFunction.apply(gtuType, randomStream).get().get();
122 }
123 Route route = categorization.entails(Route.class) ? category.get(Route.class) : null;
124 VehicleModel vehicleModel = this.vehicleModelFactory.create(gtuType);
125
126 return new LaneBasedGtuCharacteristics(gtuCharacteristics, this.factory, route, origin, destination, vehicleModel);
127 }
128
129
130
131
132
133
134 public static LaneBasedStrategicalRoutePlannerFactory defaultLmrs(final StreamInterface stream)
135 {
136 return new LaneBasedStrategicalRoutePlannerFactory(new LmrsFactory<>(Lmrs::new).setStream(stream)
137 .set(Setting.ACCELERATION_TRAFFIC_LIGHTS, true).set(Setting.ACCELERATION_CONFLICTS, true));
138 }
139
140
141
142
143
144
145
146
147
148
149
150
151 @SuppressWarnings("hiddenfield")
152 public static class Factory
153 {
154
155 private Supplier<GtuType> gtuTypeGenerator = null;
156
157
158 private Set<GtuTemplate> templates = new LinkedHashSet<>();
159
160
161 private final LaneBasedStrategicalPlannerFactory<?> factory;
162
163
164 private VehicleModelFactory vehicleModelFactory = VehicleModelFactory.MINMAX;
165
166
167 private BiFunction<GtuType, StreamInterface, Optional<GtuTemplate>> templateFunction = Defaults.NL;
168
169
170
171
172
173 public Factory(final LaneBasedStrategicalPlannerFactory<?> factory)
174 {
175 this.factory = factory;
176 }
177
178
179
180
181
182
183 public Factory setGtuTypeGenerator(final Supplier<GtuType> gtuTypeGenerator)
184 {
185 this.gtuTypeGenerator = gtuTypeGenerator;
186 return this;
187 }
188
189
190
191
192
193
194 public Factory setTemplates(final Set<GtuTemplate> templates)
195 {
196 this.templates = templates;
197 return this;
198 }
199
200
201
202
203
204
205 public Factory setVehicleModelGenerator(final VehicleModelFactory vehicleModelFactory)
206 {
207 this.vehicleModelFactory = vehicleModelFactory;
208 return this;
209 }
210
211
212
213
214
215
216 public Factory setGtuTemplateFunction(
217 final BiFunction<GtuType, StreamInterface, Optional<GtuTemplate>> templateFunction)
218 {
219 this.templateFunction = templateFunction;
220 return this;
221 }
222
223
224
225
226
227 @SuppressWarnings("synthetic-access")
228 public DefaultLaneBasedGtuCharacteristicsGeneratorOd create()
229 {
230 return new DefaultLaneBasedGtuCharacteristicsGeneratorOd(this.gtuTypeGenerator, this.templates, this.factory,
231 this.vehicleModelFactory, this.templateFunction);
232 }
233 }
234
235 }