View Javadoc
1   /*
2    * Copyright (C) 2019 Alberto Irurueta Carro (alberto@irurueta.com)
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.irurueta.navigation.indoor.fingerprint;
17  
18  import com.irurueta.algebra.Matrix;
19  import com.irurueta.geometry.InhomogeneousPoint2D;
20  import com.irurueta.geometry.Point2D;
21  import com.irurueta.navigation.indoor.IndoorException;
22  import com.irurueta.navigation.indoor.RadioSource;
23  import com.irurueta.navigation.indoor.RadioSourceLocated;
24  import com.irurueta.navigation.indoor.RssiFingerprint;
25  import com.irurueta.navigation.indoor.RssiFingerprintLocated;
26  import com.irurueta.navigation.indoor.RssiReading;
27  import com.irurueta.navigation.indoor.Utils;
28  
29  import java.util.List;
30  
31  /**
32   * Position and radio source estimator in 2D based only on located fingerprints
33   * containing RSSI readings.
34   * This class estimates 2D position of a new fingerprint and the 2D position of all
35   * radio sources associated to fingerprints whose location is known.
36   */
37  public class NonLinearFingerprintPositionAndRadioSourceEstimator2D extends
38          NonLinearFingerprintPositionAndRadioSourceEstimator<Point2D> {
39  
40      /**
41       * Constructor.
42       */
43      public NonLinearFingerprintPositionAndRadioSourceEstimator2D() {
44      }
45  
46      /**
47       * Constructor.
48       *
49       * @param listener listener in charge of handling events.
50       */
51      public NonLinearFingerprintPositionAndRadioSourceEstimator2D(
52              final FingerprintPositionAndRadioSourceEstimatorListener<Point2D> listener) {
53          super(listener);
54      }
55  
56      /**
57       * Constructor.
58       *
59       * @param locatedFingerprints located fingerprints containing RSSI readings.
60       * @param fingerprint         fingerprint containing readings at an unknown location
61       *                            for provided located fingerprints.
62       * @throws IllegalArgumentException if either non located fingerprint or located
63       *                                  fingerprints are null.
64       */
65      public NonLinearFingerprintPositionAndRadioSourceEstimator2D(
66              final List<? extends RssiFingerprintLocated<? extends RadioSource,
67                      ? extends RssiReading<? extends RadioSource>, Point2D>> locatedFingerprints,
68              final RssiFingerprint<? extends RadioSource,
69                      ? extends RssiReading<? extends RadioSource>> fingerprint) {
70          super(locatedFingerprints, fingerprint);
71      }
72  
73      /**
74       * Constructor.
75       *
76       * @param locatedFingerprints located fingerprints containing RSSI readings.
77       * @param fingerprint         fingerprint containing readings at an unknown location
78       *                            for provided located fingerprints.
79       * @param listener            listener in charge of handling events.
80       * @throws IllegalArgumentException if either non located fingerprint or located
81       *                                  fingerprints are null.
82       */
83      public NonLinearFingerprintPositionAndRadioSourceEstimator2D(
84              final List<? extends RssiFingerprintLocated<? extends RadioSource,
85                      ? extends RssiReading<? extends RadioSource>, Point2D>> locatedFingerprints,
86              final RssiFingerprint<? extends RadioSource,
87                      ? extends RssiReading<? extends RadioSource>> fingerprint,
88              final FingerprintPositionAndRadioSourceEstimatorListener<Point2D> listener) {
89          super(locatedFingerprints, fingerprint, listener);
90      }
91  
92      /**
93       * Constructor.
94       *
95       * @param locatedFingerprints located fingerprints containing RSSI readings.
96       * @param fingerprint         fingerprint containing readings at an unknown location
97       *                            for provided located fingerprints.
98       * @param initialPosition     initial position to be assumed on non located fingerprint or
99       *                            null if unknown.
100      * @throws IllegalArgumentException if either non located fingerprint or located
101      *                                  fingerprints are null.
102      */
103     public NonLinearFingerprintPositionAndRadioSourceEstimator2D(
104             final List<? extends RssiFingerprintLocated<? extends RadioSource,
105                     ? extends RssiReading<? extends RadioSource>, Point2D>> locatedFingerprints,
106             final RssiFingerprint<? extends RadioSource,
107                     ? extends RssiReading<? extends RadioSource>> fingerprint,
108             final Point2D initialPosition) {
109         super(locatedFingerprints, fingerprint, initialPosition);
110     }
111 
112     /**
113      * Constructor.
114      *
115      * @param locatedFingerprints located fingerprints containing RSSI readings.
116      * @param fingerprint         fingerprint containing readings at an unknown location
117      *                            for provided located fingerprints.
118      * @param initialPosition     initial position to be assumed on non located fingerprint or
119      *                            null if unknown.
120      * @param listener            listener in charge of handling events.
121      * @throws IllegalArgumentException if either non located fingerprint or located
122      *                                  fingerprints are null.
123      */
124     public NonLinearFingerprintPositionAndRadioSourceEstimator2D(
125             final List<? extends RssiFingerprintLocated<? extends RadioSource,
126                     ? extends RssiReading<? extends RadioSource>, Point2D>> locatedFingerprints,
127             final RssiFingerprint<? extends RadioSource,
128                     ? extends RssiReading<? extends RadioSource>> fingerprint,
129             final Point2D initialPosition,
130             final FingerprintPositionAndRadioSourceEstimatorListener<Point2D> listener) {
131         super(locatedFingerprints, fingerprint, initialPosition, listener);
132     }
133 
134     /**
135      * Constructor.
136      *
137      * @param locatedFingerprints   located fingerprints containing RSSI readings.
138      * @param fingerprint           fingerprint containing readings at an unknown location
139      *                              for provided located fingerprints.
140      * @param initialLocatedSources sources containing initial location to be refined or null
141      *                              if unknown.
142      * @throws IllegalArgumentException if either non located fingerprint or located
143      *                                  fingerprints are null.
144      */
145     public NonLinearFingerprintPositionAndRadioSourceEstimator2D(
146             final List<? extends RssiFingerprintLocated<? extends RadioSource,
147                     ? extends RssiReading<? extends RadioSource>, Point2D>> locatedFingerprints,
148             final RssiFingerprint<? extends RadioSource,
149                     ? extends RssiReading<? extends RadioSource>> fingerprint,
150             final List<? extends RadioSourceLocated<Point2D>> initialLocatedSources) {
151         super(locatedFingerprints, fingerprint, initialLocatedSources);
152     }
153 
154     /**
155      * Constructor.
156      *
157      * @param locatedFingerprints   located fingerprints containing RSSI readings.
158      * @param fingerprint           fingerprint containing readings at an unknown location
159      *                              for provided located fingerprints.
160      * @param initialLocatedSources sources containing initial location to be refined or null
161      *                              if unknown.
162      * @param listener              listener in charge of handling events.
163      * @throws IllegalArgumentException if either non located fingerprint or located
164      *                                  fingerprints are null.
165      */
166     public NonLinearFingerprintPositionAndRadioSourceEstimator2D(
167             final List<? extends RssiFingerprintLocated<? extends RadioSource,
168                     ? extends RssiReading<? extends RadioSource>, Point2D>> locatedFingerprints,
169             final RssiFingerprint<? extends RadioSource,
170                     ? extends RssiReading<? extends RadioSource>> fingerprint,
171             final List<? extends RadioSourceLocated<Point2D>> initialLocatedSources,
172             final FingerprintPositionAndRadioSourceEstimatorListener<Point2D> listener) {
173         super(locatedFingerprints, fingerprint, initialLocatedSources, listener);
174     }
175 
176     /**
177      * Constructor.
178      *
179      * @param locatedFingerprints   located fingerprints containing RSSI readings.
180      * @param fingerprint           fingerprint containing readings at an unknown location
181      *                              for provided located fingerprints.
182      * @param initialPosition       initial position to be assumed on non located fingerprint or
183      *                              null if unknown.
184      * @param initialLocatedSources sources containing initial location to be refined or null
185      *                              if unknown.
186      * @throws IllegalArgumentException if either non located fingerprint or located
187      *                                  fingerprints are null.
188      */
189     public NonLinearFingerprintPositionAndRadioSourceEstimator2D(
190             final List<? extends RssiFingerprintLocated<? extends RadioSource,
191                     ? extends RssiReading<? extends RadioSource>, Point2D>> locatedFingerprints,
192             final RssiFingerprint<? extends RadioSource,
193                     ? extends RssiReading<? extends RadioSource>> fingerprint,
194             final Point2D initialPosition,
195             final List<? extends RadioSourceLocated<Point2D>> initialLocatedSources) {
196         super(locatedFingerprints, fingerprint, initialPosition, initialLocatedSources);
197     }
198 
199     /**
200      * Constructor.
201      *
202      * @param locatedFingerprints   located fingerprints containing RSSI readings.
203      * @param fingerprint           fingerprint containing readings at an unknown location
204      *                              for provided located fingerprints.
205      * @param initialPosition       initial position to be assumed on non located fingerprint or
206      *                              null if unknown.
207      * @param initialLocatedSources sources containing initial location to be refined or null
208      *                              if unknown.
209      * @param listener              listener in charge of handling events.
210      * @throws IllegalArgumentException if either non located fingerprint or located
211      *                                  fingerprints are null.
212      */
213     public NonLinearFingerprintPositionAndRadioSourceEstimator2D(
214             final List<? extends RssiFingerprintLocated<? extends RadioSource,
215                     ? extends RssiReading<? extends RadioSource>, Point2D>> locatedFingerprints,
216             final RssiFingerprint<? extends RadioSource,
217                     ? extends RssiReading<? extends RadioSource>> fingerprint,
218             final Point2D initialPosition,
219             final List<? extends RadioSourceLocated<Point2D>> initialLocatedSources,
220             final FingerprintPositionAndRadioSourceEstimatorListener<Point2D> listener) {
221         super(locatedFingerprints, fingerprint, initialPosition, initialLocatedSources, listener);
222     }
223 
224     /**
225      * Propagates provided variances into RSSI differences.
226      *
227      * @param pathlossExponent              path-loss exponent.
228      * @param fingerprintPosition           position of closest located fingerprint.
229      * @param radioSourcePosition           radio source position associated to fingerprint reading.
230      * @param estimatedPosition             position to be estimated. Usually this is equal to the
231      *                                      initial position used by a non-linear algorithm.
232      * @param pathlossExponentVariance      variance of path-loss exponent or null if unknown.
233      * @param fingerprintPositionCovariance covariance of fingerprint position or null if
234      *                                      unknown.
235      * @param radioSourcePositionCovariance covariance of radio source position or null if
236      *                                      unknown.
237      * @return variance of RSSI difference measured at non located fingerprint reading.
238      */
239     @Override
240     @SuppressWarnings("Duplicates")
241     protected Double propagateVariances(
242             final double pathlossExponent, final Point2D fingerprintPosition, final Point2D radioSourcePosition,
243             final Point2D estimatedPosition, final Double pathlossExponentVariance,
244             final Matrix fingerprintPositionCovariance, final Matrix radioSourcePositionCovariance) {
245         try {
246             final var dist = Utils.propagateVariancesToRssiDifferenceVariance2D(pathlossExponent, fingerprintPosition,
247                     radioSourcePosition, estimatedPosition, pathlossExponentVariance, fingerprintPositionCovariance,
248                     radioSourcePositionCovariance, null);
249             if (dist == null) {
250                 return null;
251             }
252 
253             final var covariance = dist.getCovariance();
254             if (covariance == null) {
255                 return null;
256             }
257 
258             return covariance.getElementAt(0, 0);
259         } catch (final IndoorException e) {
260             return null;
261         }
262     }
263 
264     /**
265      * Gets number of dimensions of points.
266      *
267      * @return number of dimensions of points.
268      */
269     @Override
270     public int getNumberOfDimensions() {
271         return Point2D.POINT2D_INHOMOGENEOUS_COORDINATES_LENGTH;
272     }
273 
274     /**
275      * Create a point.
276      *
277      * @return point to be created.
278      */
279     @Override
280     protected Point2D createPoint() {
281         return new InhomogeneousPoint2D();
282     }
283 }