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