1 package org.opentrafficsim.road.network.lane.object;
2
3 import org.djunits.value.vdouble.scalar.Length;
4 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
5 import org.opentrafficsim.core.geometry.OTSLine3D;
6 import org.opentrafficsim.core.gtu.GTUDirectionality;
7 import org.opentrafficsim.core.network.LongitudinalDirectionality;
8 import org.opentrafficsim.core.network.Network;
9 import org.opentrafficsim.core.network.NetworkException;
10 import org.opentrafficsim.core.object.StaticObject;
11 import org.opentrafficsim.road.network.lane.CrossSectionElement;
12 import org.opentrafficsim.road.network.lane.Lane;
13 import org.opentrafficsim.road.network.lane.object.sensor.SingleSensor;
14
15 import nl.tudelft.simulation.language.Throw;
16 import nl.tudelft.simulation.language.d3.DirectedPoint;
17
18 /**
19 * An abstract implementation of the LaneBasedObject interface with the required fields being initialized and getters for those
20 * fields. All StaticObjects are EventProducers, allowing them to provide state changes to subscribers.
21 * <p>
22 * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
23 * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
24 * </p>
25 * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
26 * initial version Sep 10, 2016 <br>
27 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
28 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
29 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
30 */
31 public abstract class AbstractLaneBasedObject extends StaticObject implements LaneBasedObject
32 {
33 /** */
34 private static final long serialVersionUID = 20160909L;
35
36 /** The lane for which this is a sensor. */
37 private final Lane lane;
38
39 /** The direction in which this is valid. */
40 private final LongitudinalDirectionality direction;
41
42 /** The position (between 0.0 and the length of the Lane) of the sensor on the design line of the lane. */
43 private final Length longitudinalPosition;
44
45 /** The DirectedPoint that indicates the location on the lane. */
46 private final DirectedPoint location;
47
48 /**
49 * Construct a new AbstractLanebasedObject with the required fields.
50 * @param id String; the id of the new object
51 * @param lane Lane; The lane on which the new object resides. If the new object is a Sensor; it is automatically registered
52 * on the lane
53 * @param direction LongitudinalDirectionality; the directionality in which this is valid.
54 * @param longitudinalPosition Length; The position (between 0.0 and the length of the Lane) of the sensor on the design
55 * line of the lane
56 * @param geometry OTSLine3D; the geometry of the object, which provides its location and bounds as well
57 * @param height Length; the height of the object, in case it is a 3D object
58 * @throws NetworkException when the position on the lane is out of bounds
59 */
60 public AbstractLaneBasedObject(final String id, final Lane lane, final LongitudinalDirectionality direction,
61 final Length longitudinalPosition, final OTSLine3D geometry, final Length height) throws NetworkException
62 {
63 super(id, geometry, height);
64
65 Throw.whenNull(lane, "lane is null");
66 Throw.whenNull(direction, "Longitudinal direction is null");
67 Throw.whenNull(longitudinalPosition, "longitudinal position is null");
68 Throw.when(longitudinalPosition.si < 0.0 || longitudinalPosition.si > lane.getCenterLine().getLengthSI(),
69 NetworkException.class, "Position of the object on the lane is out of bounds");
70
71 this.lane = lane;
72 this.direction = direction;
73 this.longitudinalPosition = longitudinalPosition;
74 DirectedPoint p = lane.getCenterLine().getLocationExtended(this.longitudinalPosition);
75 this.location = new DirectedPoint(p.x, p.y, p.z + 0.01, p.getRotX(), p.getRotY(), p.getRotZ());
76
77 if (!(this instanceof SingleSensor))
78 {
79 this.lane.addLaneBasedObject(this); // implements OTS-218
80 }
81 }
82
83 /**
84 * Construct a new AbstractLanebasedObject with the required fields.
85 * @param id String; the id of the new object
86 * @param lane Lane; The lane on which the new object resides. If the new object is a Sensor; it is automatically registered
87 * on the lane
88 * @param longitudinalPosition Length; The position (between 0.0 and the length of the Lane) of the sensor on the design
89 * line of the lane
90 * @param geometry OTSLine3D; the geometry of the object, which provides its location and bounds as well
91 * @param height Length; the height of the object, in case it is a 3D object
92 * @throws NetworkException when the position on the lane is out of bounds
93 */
94 public AbstractLaneBasedObject(final String id, final Lane lane, final Length longitudinalPosition,
95 final OTSLine3D geometry, final Length height) throws NetworkException
96 {
97 this(id, lane, LongitudinalDirectionality.DIR_BOTH, longitudinalPosition, geometry, height);
98 }
99
100 /**
101 * Construct a new LaneBasedObject with the required fields.
102 * @param id String; the id of the new AbstractLaneBasedObject
103 * @param lane Lane; The lane for which this is a sensor
104 * @param direction LongitudinalDirectionality; the directionality in which this is valid.
105 * @param longitudinalPosition Length; The position (between 0.0 and the length of the Lane) of the sensor on the design
106 * line of the lane
107 * @param geometry OTSLine3D; the geometry of the object, which provides its location and bounds as well
108 * @throws NetworkException when the position on the lane is out of bounds
109 */
110 public AbstractLaneBasedObject(final String id, final Lane lane, final LongitudinalDirectionality direction,
111 final Length longitudinalPosition, final OTSLine3D geometry) throws NetworkException
112 {
113 this(id, lane, direction, longitudinalPosition, geometry, Length.ZERO);
114 }
115
116 /**
117 * Construct a new LaneBasedObject with the required fields.
118 * @param id String; the id of the new AbstractLaneBasedObject
119 * @param lane Lane; The lane for which this is a sensor
120 * @param longitudinalPosition Length; The position (between 0.0 and the length of the Lane) of the sensor on the design
121 * line of the lane
122 * @param geometry OTSLine3D; the geometry of the object, which provides its location and bounds as well
123 * @throws NetworkException when the position on the lane is out of bounds
124 */
125 public AbstractLaneBasedObject(final String id, final Lane lane, final Length longitudinalPosition,
126 final OTSLine3D geometry) throws NetworkException
127 {
128 this(id, lane, longitudinalPosition, geometry, Length.ZERO);
129 }
130
131 /** {@inheritDoc} */
132 @Override
133 public final Lane getLane()
134 {
135 return this.lane;
136 }
137
138 /** {@inheritDoc} */
139 public final LongitudinalDirectionality getDirection()
140 {
141 return this.direction;
142 }
143
144 /** {@inheritDoc} */
145 @Override
146 public final Length getLongitudinalPosition()
147 {
148 return this.longitudinalPosition;
149 }
150
151 /** {@inheritDoc} */
152 @Override
153 @SuppressWarnings("checkstyle:designforextension")
154 public DirectedPoint getLocation()
155 {
156 return this.location;
157 }
158
159 /** {@inheritDoc} */
160 @Override
161 public final StaticObject clone(final Network newNetwork, final OTSSimulatorInterface newSimulator, final boolean animation)
162 throws NetworkException
163 {
164 throw new NetworkException("LaneBasedObjects should be cloned with the clone(lane, simulator, animation) method");
165 }
166
167 /**
168 * Clone the LaneBasedObject for e.g., copying a network.
169 * @param newCSE CrossSectionElement; the new cross section element to which the clone belongs
170 * @param newSimulator OTSSimulatorInterface; the new simulator for this network
171 * @param animation boolean; whether to (re)create animation or not
172 * @return AbstractLaneBasedObject; a clone of this object
173 * @throws NetworkException in case the cloning fails
174 */
175 @SuppressWarnings("checkstyle:designforextension")
176 public abstract AbstractLaneBasedObject clone(final CrossSectionElement newCSE, final OTSSimulatorInterface newSimulator,
177 final boolean animation) throws NetworkException;
178
179 }