View Javadoc
1   package org.opentrafficsim.road.network.lane;
2   
3   import javax.media.j3d.Bounds;
4   import javax.vecmath.Point3d;
5   
6   import nl.tudelft.simulation.language.d3.BoundingBox;
7   import nl.tudelft.simulation.language.d3.DirectedPoint;
8   
9   import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
10  import org.opentrafficsim.core.gtu.RelativePosition;
11  import org.opentrafficsim.core.network.NetworkException;
12  
13  /**
14   * <p>
15   * Copyright (c) 2013-2015 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
16   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
17   * <p>
18   * $LastChangedDate: 2015-09-14 01:33:02 +0200 (Mon, 14 Sep 2015) $, @version $Revision: 1401 $, by $Author: averbraeck $,
19   * initial version Dec 31, 2014 <br>
20   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
21   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
22   */
23  public abstract class AbstractSensor implements Sensor
24  {
25      /** */
26      private static final long serialVersionUID = 20141231L;
27  
28      /** The lane for which this is a sensor. */
29      private final Lane lane;
30  
31      /** The position (between 0.0 and the length of the Lane) of the sensor on the design line of the lane in SI units. */
32      private final double longitudinalPositionSI;
33  
34      /** the relative position of the vehicle that triggers the sensor. */
35      private final RelativePosition.TYPE positionType;
36  
37      /** the name of the sensor. */
38      private final String name;
39  
40      /** the cached location for animation. */
41      private DirectedPoint location = null;
42  
43      /** the cached bounds for animation. */
44      private Bounds bounds = null;
45  
46      /** the simulator for being able to generate an animation. */
47      private final OTSDEVSSimulatorInterface simulator;
48  
49      /**
50       * @param lane The lane for which this is a sensor.
51       * @param longitudinalPosition DoubleScalar.Rel&lt;LengthUnit&gt;; the position (between 0.0 and the length of the Lane) of
52       *            the sensor on the design line of the lane.
53       * @param positionType RelativePosition.TYPE; the relative position type (e.g., FRONT, BACK) of the vehicle that triggers
54       *            the sensor.
55       * @param name the name of the sensor.
56       * @param simulator the simulator for being able to generate the animation.
57       */
58      public AbstractSensor(final Lane lane, final Length.Rel longitudinalPosition, final RelativePosition.TYPE positionType,
59          final String name, final OTSDEVSSimulatorInterface simulator)
60      {
61          this.lane = lane;
62          this.longitudinalPositionSI = longitudinalPosition.getSI();
63          this.positionType = positionType;
64          this.name = name;
65          this.simulator = simulator;
66      }
67  
68      /** {@inheritDoc} */
69      @Override
70      public final Lane getLane()
71      {
72          return this.lane;
73      }
74  
75      /** {@inheritDoc} */
76      @Override
77      public final Length.Rel getLongitudinalPosition()
78      {
79          return new Length.Rel(this.longitudinalPositionSI, METER);
80      }
81  
82      /** {@inheritDoc} */
83      @Override
84      public final RelativePosition.TYPE getPositionType()
85      {
86          return this.positionType;
87      }
88  
89      /** {@inheritDoc} */
90      @Override
91      public final double getLongitudinalPositionSI()
92      {
93          return this.longitudinalPositionSI;
94      }
95  
96      /** {@inheritDoc} */
97      @Override
98      public final DirectedPoint getLocation() 
99      {
100         if (this.location == null)
101         {
102             try
103             {
104                 this.location = this.lane.getCenterLine().getLocationSI(this.longitudinalPositionSI);
105                 this.location.z = this.lane.getLocation().z + 0.01;
106             }
107             catch (NetworkException exception)
108             {
109                 exception.printStackTrace();
110                 return null;
111             }
112         }
113         return this.location;
114     }
115 
116     /** {@inheritDoc} */
117     @Override
118     public final Bounds getBounds() 
119     {
120         if (this.bounds == null)
121         {
122             this.bounds =
123                 new BoundingBox(new Point3d(-0.4, -this.lane.getWidth(0.0).getSI() * 0.4, 0.0), new Point3d(0.4, this.lane
124                     .getWidth(0.0).getSI() * 0.4, this.lane.getLocation().z + 0.01));
125         }
126         return this.bounds;
127     }
128 
129     /**
130      * @return name.
131      */
132     public final String getName()
133     {
134         return this.name;
135     }
136 
137     /**
138      * @return simulator
139      */
140     public final OTSDEVSSimulatorInterface getSimulator()
141     {
142         return this.simulator;
143     }
144 
145     /** {@inheritDoc} */
146     @SuppressWarnings("checkstyle:designforextension")
147     @Override
148     public int hashCode()
149     {
150         final int prime = 31;
151         int result = 1;
152         result = prime * result + ((this.lane == null) ? 0 : this.lane.hashCode());
153         long temp;
154         temp = Double.doubleToLongBits(this.longitudinalPositionSI);
155         result = prime * result + (int) (temp ^ (temp >>> 32));
156         result = prime * result + ((this.positionType == null) ? 0 : this.positionType.hashCode());
157         return result;
158     }
159 
160     /** {@inheritDoc} */
161     @SuppressWarnings({"checkstyle:needbraces", "checkstyle:designforextension"})
162     @Override
163     public boolean equals(final Object obj)
164     {
165         if (this == obj)
166             return true;
167         if (obj == null)
168             return false;
169         if (getClass() != obj.getClass())
170             return false;
171         AbstractSensor other = (AbstractSensor) obj;
172         if (this.lane == null)
173         {
174             if (other.lane != null)
175                 return false;
176         }
177         else if (!this.lane.equals(other.lane))
178             return false;
179         if (Double.doubleToLongBits(this.longitudinalPositionSI) != Double.doubleToLongBits(other.longitudinalPositionSI))
180             return false;
181         if (this.positionType == null)
182         {
183             if (other.positionType != null)
184                 return false;
185         }
186         else if (!this.positionType.equals(other.positionType))
187             return false;
188         return true;
189     }
190 
191     /** {@inheritDoc} */
192     @SuppressWarnings("checkstyle:designforextension")
193     @Override
194     public int compareTo(final Sensor o)
195     {
196         if (this.lane != o.getLane())
197         {
198             return this.lane.hashCode() < o.getLane().hashCode() ? -1 : 1;
199         }
200         if (this.longitudinalPositionSI != o.getLongitudinalPositionSI())
201         {
202             return this.longitudinalPositionSI < o.getLongitudinalPositionSI() ? -1 : 1;
203         }
204         if (!this.positionType.equals(o.getPositionType()))
205         {
206             return this.positionType.hashCode() < o.getPositionType().hashCode() ? -1 : 1;
207         }
208         if (!this.equals(o))
209         {
210             return this.hashCode() < o.hashCode() ? -1 : 1;
211         }
212         return 0;
213     }
214 
215 }