1 package org.opentrafficsim.road.network.control.rampmetering;
2
3 import java.util.List;
4
5 import org.djunits.value.vdouble.scalar.Duration;
6 import org.djunits.value.vdouble.scalar.Frequency;
7 import org.djunits.value.vdouble.scalar.Speed;
8 import org.djutils.exceptions.Throw;
9 import org.opentrafficsim.road.network.lane.object.sensor.Detector;
10
11 /**
12 * Super class for feed-forward controller. This class contains some helper methods for sub-classes.
13 * <p>
14 * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
15 * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
16 * <p>
17 * @version $Revision$, $LastChangedDate$, by $Author$, initial version May 29, 2019 <br>
18 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
19 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
20 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
21 */
22 public abstract class SingleCrossSectionSwitch implements RampMeteringSwitch
23 {
24
25 /** Control interval. */
26 private final Duration interval;
27
28 /** Detectors (on downstream section). */
29 private final List<Detector> detectors;
30
31 /**
32 * Constructor.
33 * @param interval Duration; interval
34 * @param detectors List<Detector>; detectors
35 */
36 public SingleCrossSectionSwitch(final Duration interval, final List<Detector> detectors)
37 {
38 Throw.whenNull(interval, "Interval may not be null.");
39 Throw.when(detectors == null || detectors.size() == 0, IllegalArgumentException.class,
40 "At least 1 detector is required.");
41 this.interval = interval;
42 this.detectors = detectors;
43 }
44
45 /** {@inheritDoc} */
46 @Override
47 public Duration getInterval()
48 {
49 return this.interval;
50 }
51
52 /**
53 * Returns the mean speed over the detectors.
54 * @return Speed; mean speed over the detectors
55 */
56 protected final Speed meanSpeed()
57 {
58 int n = 0;
59 double value = 0.0;
60 for (Detector detector : this.detectors)
61 {
62 if (detector.hasLastValue())
63 {
64 value += detector.getLastValue(Detector.MEAN_SPEED).si;
65 n++;
66 }
67 }
68 return Speed.instantiateSI(value / n);
69 }
70
71 /**
72 * Returns the mean flow over the detectors.
73 * @return Frequency; mean flow over the detectors
74 */
75 protected final Frequency meanFlow()
76 {
77 return totalFlow().divide(this.detectors.size());
78 }
79
80 /**
81 * Returns the total flow over the detectors.
82 * @return Frequency; total flow over the detectors
83 */
84 protected final Frequency totalFlow()
85 {
86 double value = 0.0;
87 for (Detector detector : this.detectors)
88 {
89 if (detector.hasLastValue())
90 {
91 value += detector.getLastFlow().si;
92 }
93 }
94 return Frequency.instantiateSI(value);
95 }
96
97 }