1 package org.opentrafficsim.demo;
2
3 import java.rmi.RemoteException;
4 import java.util.ArrayList;
5 import java.util.List;
6 import java.util.Map;
7
8 import javax.naming.NamingException;
9
10 import org.djunits.unit.FrequencyUnit;
11 import org.djunits.unit.SpeedUnit;
12 import org.djunits.value.vdouble.scalar.Duration;
13 import org.djunits.value.vdouble.scalar.Length;
14 import org.djunits.value.vdouble.scalar.Speed;
15 import org.djunits.value.vdouble.vector.DurationVector;
16 import org.djunits.value.vdouble.vector.FrequencyVector;
17 import org.djutils.draw.function.ContinuousPiecewiseLinearFunction;
18 import org.djutils.draw.line.Polygon2d;
19 import org.djutils.draw.point.DirectedPoint2d;
20 import org.opentrafficsim.animation.Colors;
21 import org.opentrafficsim.animation.colorer.Colorer;
22 import org.opentrafficsim.animation.colorer.FixedColorer;
23 import org.opentrafficsim.animation.data.gtu.AccelerationGtuColorer;
24 import org.opentrafficsim.animation.data.gtu.AttentionGtuColorer;
25 import org.opentrafficsim.animation.data.gtu.IncentiveGtuColorer;
26 import org.opentrafficsim.animation.data.gtu.SocialPressureGtuColorer;
27 import org.opentrafficsim.animation.data.gtu.SpeedGtuColorer;
28 import org.opentrafficsim.animation.data.gtu.TaskSaturationGtuColorer;
29 import org.opentrafficsim.base.geometry.OtsLine2d;
30 import org.opentrafficsim.base.parameters.ParameterException;
31 import org.opentrafficsim.core.definitions.DefaultsNl;
32 import org.opentrafficsim.core.dsol.AbstractOtsModel;
33 import org.opentrafficsim.core.dsol.OtsAnimator;
34 import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
35 import org.opentrafficsim.core.gtu.Gtu;
36 import org.opentrafficsim.core.gtu.GtuType;
37 import org.opentrafficsim.core.network.LateralDirectionality;
38 import org.opentrafficsim.core.network.Network;
39 import org.opentrafficsim.core.network.NetworkException;
40 import org.opentrafficsim.core.network.Node;
41 import org.opentrafficsim.core.perception.HistoryManagerDevs;
42 import org.opentrafficsim.demo.HumanFactorsDemo.HumanFactorsModel;
43 import org.opentrafficsim.road.definitions.DefaultsRoadNl;
44 import org.opentrafficsim.road.gtu.generator.characteristics.DefaultLaneBasedGtuCharacteristicsGeneratorOd;
45 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedGtuCharacteristicsGeneratorOd;
46 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalRoutePlannerFactory;
47 import org.opentrafficsim.road.gtu.tactical.lmrs.IncentiveSocioSpeed;
48 import org.opentrafficsim.road.gtu.tactical.lmrs.Lmrs;
49 import org.opentrafficsim.road.gtu.tactical.lmrs.LmrsFactory;
50 import org.opentrafficsim.road.gtu.tactical.lmrs.LmrsFactory.FullerImplementation;
51 import org.opentrafficsim.road.gtu.tactical.lmrs.LmrsFactory.IdmPlusMultiFunction;
52 import org.opentrafficsim.road.gtu.tactical.lmrs.LmrsFactory.Setting;
53 import org.opentrafficsim.road.network.CrossSectionGeometry;
54 import org.opentrafficsim.road.network.CrossSectionLink;
55 import org.opentrafficsim.road.network.Lane;
56 import org.opentrafficsim.road.network.LaneGeometryUtil;
57 import org.opentrafficsim.road.network.LaneKeepingPolicy;
58 import org.opentrafficsim.road.network.RoadNetwork;
59 import org.opentrafficsim.road.network.Stripe;
60 import org.opentrafficsim.road.network.object.RoadSideDistraction;
61 import org.opentrafficsim.road.network.object.RoadSideDistraction.TrapezoidProfile;
62 import org.opentrafficsim.road.network.speed.LaneSpeedLimits;
63 import org.opentrafficsim.road.od.Categorization;
64 import org.opentrafficsim.road.od.Category;
65 import org.opentrafficsim.road.od.Interpolation;
66 import org.opentrafficsim.road.od.OdApplier;
67 import org.opentrafficsim.road.od.OdMatrix;
68 import org.opentrafficsim.road.od.OdOptions;
69 import org.opentrafficsim.swing.gui.OtsSimulationApplication;
70 import org.opentrafficsim.swing.gui.OtsSimulationPanel;
71 import org.opentrafficsim.swing.gui.OtsSimulationPanelDecorator;
72
73 import nl.tudelft.simulation.dsol.SimRuntimeException;
74 import nl.tudelft.simulation.language.DsolException;
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 public final class HumanFactorsDemo extends OtsSimulationApplication<HumanFactorsModel>
94 {
95
96
97 private static final long serialVersionUID = 20241012L;
98
99
100
101
102
103
104 private HumanFactorsDemo(final HumanFactorsModel model, final OtsSimulationPanel panel)
105 {
106 super(model, panel);
107 }
108
109
110
111
112
113 public static void main(final String[] args)
114 {
115 try
116 {
117 OtsAnimator simulator = new OtsAnimator("HFDemo");
118 final HumanFactorsModel junctionModel = new HumanFactorsModel(simulator);
119 simulator.initialize(Duration.ZERO, Duration.ZERO, Duration.ofSI(3600.0), junctionModel,
120 new HistoryManagerDevs(simulator, Duration.ofSI(3.0), Duration.ofSI(10.0)));
121
122 OtsSimulationPanel simulationPanel =
123 new OtsSimulationPanel(junctionModel.getNetwork(), new OtsSimulationPanelDecorator()
124 {
125 @Override
126 public List<Colorer<? super Gtu>> getGtuColorers()
127 {
128 return List.of(new FixedColorer<>(Colors.OTS_BLUE, "Blue"), new SpeedGtuColorer(),
129 new AccelerationGtuColorer(), new SocialPressureGtuColorer(),
130 new IncentiveGtuColorer(IncentiveSocioSpeed.class), new AttentionGtuColorer(),
131 new TaskSaturationGtuColorer());
132 }
133 });
134 new HumanFactorsDemo(junctionModel, simulationPanel);
135 simulationPanel.enableSimulationControlButtons();
136 }
137 catch (SimRuntimeException | NamingException | RemoteException | DsolException exception)
138 {
139 exception.printStackTrace();
140 }
141 }
142
143
144
145
146 public static class HumanFactorsModel extends AbstractOtsModel
147 {
148
149
150 private RoadNetwork network;
151
152
153 private LaneBasedGtuCharacteristicsGeneratorOd characteristics;
154
155
156
157
158
159 public HumanFactorsModel(final OtsSimulatorInterface simulator)
160 {
161 super(simulator);
162 }
163
164 @Override
165 public Network getNetwork()
166 {
167 return this.network;
168 }
169
170 @Override
171 public void constructModel() throws SimRuntimeException
172 {
173 try
174 {
175 buildNetwork();
176 buildHumanFactorsModel();
177 setDemand();
178 }
179 catch (NetworkException | ParameterException exception)
180 {
181 throw new SimRuntimeException(exception);
182 }
183 }
184
185
186
187
188
189 private void buildHumanFactorsModel() throws ParameterException
190 {
191
192 boolean social = true;
193 boolean perception = true;
194
195 LmrsFactory<Lmrs> tacticalFactory = new LmrsFactory<>(List.of(DefaultsNl.CAR, DefaultsNl.TRUCK), Lmrs::new);
196 tacticalFactory.setStream(getSimulator().getModel().getStream("generation"));
197 tacticalFactory.set(Setting.CAR_FOLLOWING_MODEL, IdmPlusMultiFunction.SINGLETON);
198
199 if (social)
200 {
201 tacticalFactory.set(Setting.SOCIO_PRESSURE, true);
202 tacticalFactory.set(Setting.SOCIO_TAILGATING, true);
203 tacticalFactory.set(Setting.SOCIO_LANE_CHANGE, true);
204 tacticalFactory.set(Setting.SOCIO_SPEED, true);
205 }
206 if (perception)
207 {
208 tacticalFactory.set(Setting.FULLER_IMPLEMENTATION, FullerImplementation.ATTENTION_MATRIX);
209 tacticalFactory.set(Setting.TASK_ROADSIDE_DISTRACTION, true);
210 }
211
212
213 LaneBasedStrategicalRoutePlannerFactory strategicalPlannerFactory =
214 new LaneBasedStrategicalRoutePlannerFactory(tacticalFactory, tacticalFactory);
215 this.characteristics =
216 new DefaultLaneBasedGtuCharacteristicsGeneratorOd.Factory(strategicalPlannerFactory).create();
217 }
218
219
220
221
222
223 private void buildNetwork() throws NetworkException
224 {
225 this.network = new RoadNetwork("HF network", getSimulator());
226
227 DirectedPoint2d p1 = new DirectedPoint2d(0.0, 0.0, 0.0);
228 DirectedPoint2d p2 = new DirectedPoint2d(3000.0, 0.0, 0.0);
229
230 Node nodeA = new Node(this.network, "A", p1);
231 Node nodeB = new Node(this.network, "B", p2);
232
233 LaneSpeedLimits speedLimits = new LaneSpeedLimits(new Speed(130, SpeedUnit.KM_PER_HOUR),
234 Map.of(DefaultsNl.TRUCK, new Speed(80, SpeedUnit.KM_PER_HOUR)));
235
236 OtsLine2d centerLine = new OtsLine2d(p1, p2);
237 CrossSectionLink link = new CrossSectionLink(this.network, "AB", nodeA, nodeB, DefaultsNl.HIGHWAY, centerLine,
238 ContinuousPiecewiseLinearFunction.of(0.0, 0.0), LaneKeepingPolicy.KEEPRIGHT);
239
240 double offset1 = 3.5;
241 double width1 = 0.2;
242 OtsLine2d offsetLine1 = centerLine.offsetLine(offset1);
243 new Stripe("1", DefaultsRoadNl.SOLID, link, new CrossSectionGeometry(offsetLine1, getContour(offsetLine1, width1),
244 ContinuousPiecewiseLinearFunction.of(0.0, offset1), ContinuousPiecewiseLinearFunction.of(0.0, width1)));
245
246 double offset2 = 1.75;
247 double width2 = 3.5;
248 OtsLine2d offsetLine2 = centerLine.offsetLine(offset2);
249 Lane left = new Lane(link, "LEFT", new CrossSectionGeometry(offsetLine2, getContour(offsetLine2, width2),
250 ContinuousPiecewiseLinearFunction.of(0.0, offset2), ContinuousPiecewiseLinearFunction.of(0.0, width2)),
251 DefaultsRoadNl.HIGHWAY, speedLimits);
252
253 double offset3 = 0.0;
254 double width3 = 0.2;
255 OtsLine2d offsetLine3 = centerLine.offsetLine(offset3);
256 new Stripe("2", DefaultsRoadNl.DASHED, link, new CrossSectionGeometry(offsetLine3, getContour(offsetLine3, width3),
257 ContinuousPiecewiseLinearFunction.of(0.0, offset3), ContinuousPiecewiseLinearFunction.of(0.0, width3)));
258
259 double offset4 = -1.75;
260 double width4 = 3.5;
261 OtsLine2d offsetLine4 = centerLine.offsetLine(offset4);
262 Lane right = new Lane(link, "RIGHT", new CrossSectionGeometry(offsetLine4, getContour(offsetLine4, width4),
263 ContinuousPiecewiseLinearFunction.of(0.0, offset4), ContinuousPiecewiseLinearFunction.of(0.0, width4)),
264 DefaultsRoadNl.HIGHWAY, speedLimits);
265
266 double offset5 = -3.5;
267 double width5 = 0.2;
268 OtsLine2d offsetLine5 = centerLine.offsetLine(offset5);
269 new Stripe("3", DefaultsRoadNl.SOLID, link, new CrossSectionGeometry(offsetLine5, getContour(offsetLine5, width5),
270 ContinuousPiecewiseLinearFunction.of(0.0, offset5), ContinuousPiecewiseLinearFunction.of(0.0, width5)));
271
272
273 new RoadSideDistraction("distractionLeft", left, Length.ofSI(1500.0),
274 new TrapezoidProfile(0.7, Length.ofSI(-100.0), Length.ofSI(50.0), Length.ofSI(150.0)),
275 LateralDirectionality.LEFT);
276 new RoadSideDistraction("distractionRight", right, Length.ofSI(1500.0),
277 new TrapezoidProfile(0.5, Length.ofSI(-100.0), Length.ofSI(50.0), Length.ofSI(150.0)),
278 LateralDirectionality.LEFT);
279 }
280
281
282
283
284
285
286
287 private Polygon2d getContour(final OtsLine2d line, final double width)
288 {
289 return LaneGeometryUtil.getContour(line.offsetLine(width / 2, width / 2), line.offsetLine(-width / 2, -width / 2));
290 }
291
292
293
294
295
296
297 private void setDemand() throws SimRuntimeException, ParameterException
298 {
299 Node nodeA = this.network.getNode("A").get();
300 Node nodeB = this.network.getNode("B").get();
301 Categorization categorization = new Categorization("GTU type", GtuType.class);
302 List<Node> origins = new ArrayList<>();
303 origins.add(nodeA);
304 List<Node> destinations = new ArrayList<>();
305 destinations.add(nodeB);
306 OdMatrix od = new OdMatrix("OD", origins, destinations, categorization,
307 new DurationVector(new double[] {0.0, 1800.0, 3600.0}), Interpolation.LINEAR);
308 FrequencyVector demand = new FrequencyVector(new double[] {2000.0, 4000.0, 1000.0}, FrequencyUnit.PER_HOUR);
309 double truckFraction = 0.1;
310 od.putDemandVector(nodeA, nodeB, new Category(categorization, DefaultsNl.CAR), demand, 1.0 - truckFraction);
311 od.putDemandVector(nodeA, nodeB, new Category(categorization, DefaultsNl.TRUCK), demand, truckFraction);
312 OdOptions odOptions = new OdOptions();
313 odOptions.set(OdOptions.NO_LC_DIST, Length.ofSI(150.0));
314 odOptions.set(OdOptions.GTU_TYPE, this.characteristics);
315 odOptions.set(OdOptions.LANE_BIAS, DefaultsRoadNl.LANE_BIAS_CAR_TRUCK);
316 OdApplier.applyOd(this.network, od, odOptions, DefaultsNl.VEHICLES);
317 }
318 }
319
320 }