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