View Javadoc
1   /*
2    * Copyright (C) 2018 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.geometry.InhomogeneousPoint3D;
19  import com.irurueta.geometry.Point3D;
20  import com.irurueta.navigation.indoor.RadioSource;
21  import com.irurueta.navigation.indoor.RadioSourceLocated;
22  import com.irurueta.navigation.indoor.RssiFingerprint;
23  import com.irurueta.navigation.indoor.RssiFingerprintLocated;
24  import com.irurueta.navigation.indoor.RssiReading;
25  
26  import java.util.List;
27  
28  /**
29   * 3D position estimator based on located fingerprints containing only RSSI readings and
30   * having as well prior knowledge of the location of radio sources associated to those
31   * readings.
32   * This is a base implementation for all implementations using different orders of
33   * Taylor approximation to estimate position.
34   */
35  @SuppressWarnings("DuplicatedCode")
36  public abstract class NonLinearFingerprintPositionEstimator3D extends NonLinearFingerprintPositionEstimator<Point3D> {
37  
38      /**
39       * Constructor.
40       */
41      protected NonLinearFingerprintPositionEstimator3D() {
42      }
43  
44      /**
45       * Constructor.
46       *
47       * @param listener listener in charge of handling events.
48       */
49      protected NonLinearFingerprintPositionEstimator3D(final FingerprintPositionEstimatorListener<Point3D> listener) {
50          super(listener);
51      }
52  
53      /**
54       * Constructor.
55       *
56       * @param locatedFingerprints located fingerprints containing RSSI readings.
57       * @param fingerprint         fingerprint containing readings at an unknown location
58       *                            for provided located fingerprints.
59       * @param sources             located radio sources.
60       * @throws IllegalArgumentException if provided non located fingerprint is null,
61       *                                  located fingerprints value is null or there are not enough fingerprints or
62       *                                  readings within provided fingerprints (for 3D position estimation 3 located
63       *                                  total readings are required among all fingerprints).
64       */
65      protected NonLinearFingerprintPositionEstimator3D(
66              final List<? extends RssiFingerprintLocated<? extends RadioSource,
67                      ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
68              final RssiFingerprint<? extends RadioSource,
69                      ? extends RssiReading<? extends RadioSource>> fingerprint,
70              final List<? extends RadioSourceLocated<Point3D>> sources) {
71          super(locatedFingerprints, fingerprint, sources);
72      }
73  
74      /**
75       * Constructor.
76       *
77       * @param locatedFingerprints located fingerprints containing RSSI readings.
78       * @param fingerprint         fingerprint containing readings at an unknown location
79       *                            for provided located fingerprints.
80       * @param sources             located radio sources.
81       * @param listener            listener in charge of handling events.
82       * @throws IllegalArgumentException if provided non located fingerprint is null,
83       *                                  located fingerprints value is null or there are not enough fingerprints or
84       *                                  readings within provided fingerprints (for 3D position estimation 3 located
85       *                                  total readings are required among all fingerprints).
86       */
87      protected NonLinearFingerprintPositionEstimator3D(
88              final List<? extends RssiFingerprintLocated<? extends RadioSource,
89                      ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
90              final RssiFingerprint<? extends RadioSource,
91                      ? extends RssiReading<? extends RadioSource>> fingerprint,
92              final List<? extends RadioSourceLocated<Point3D>> sources,
93              final FingerprintPositionEstimatorListener<Point3D> listener) {
94          super(locatedFingerprints, fingerprint, sources, listener);
95      }
96  
97      /**
98       * Constructor.
99       *
100      * @param locatedFingerprints located fingerprints containing RSSI readings.
101      * @param fingerprint         fingerprint containing readings at an unknown location
102      *                            for provided located fingerprints.
103      * @param sources             located radio sources.
104      * @param initialPosition     initial position to start the solving algorithm or null.
105      * @throws IllegalArgumentException if provided non located fingerprint is null,
106      *                                  located fingerprints value is null or there are not enough fingerprints or
107      *                                  readings within provided fingerprints (for 3D position estimation 3 located
108      *                                  total readings are required among all fingerprints).
109      */
110     protected NonLinearFingerprintPositionEstimator3D(
111             final List<? extends RssiFingerprintLocated<? extends RadioSource,
112                     ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
113             final RssiFingerprint<? extends RadioSource,
114                     ? extends RssiReading<? extends RadioSource>> fingerprint,
115             final List<? extends RadioSourceLocated<Point3D>> sources, Point3D initialPosition) {
116         super(locatedFingerprints, fingerprint, sources, initialPosition);
117     }
118 
119     /**
120      * Constructor.
121      *
122      * @param locatedFingerprints located fingerprints containing RSSI readings.
123      * @param fingerprint         fingerprint containing readings at an unknown location
124      *                            for provided located fingerprints.
125      * @param sources             located radio sources.
126      * @param initialPosition     initial position to start the solving algorithm or null.
127      * @param listener            listener in charge of handling events.
128      * @throws IllegalArgumentException if provided non located fingerprint is null,
129      *                                  located fingerprints value is null or there are not enough fingerprints or
130      *                                  readings within provided fingerprints (for 2D position estimation at least 2
131      *                                  located total readings are required among all fingerprints, for example 2
132      *                                  readings are required in a single fingerprint, or at least 2 fingerprints at
133      *                                  different locations containing a single reading are required. For 3D position
134      *                                  estimation 3 located total readings are required among all fingerprints).
135      */
136     protected NonLinearFingerprintPositionEstimator3D(
137             final List<? extends RssiFingerprintLocated<
138                     ? extends RadioSource, ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
139             final RssiFingerprint<? extends RadioSource,
140                     ? extends RssiReading<? extends RadioSource>> fingerprint,
141             final List<? extends RadioSourceLocated<Point3D>> sources, Point3D initialPosition,
142             final FingerprintPositionEstimatorListener<Point3D> listener) {
143         super(locatedFingerprints, fingerprint, sources, initialPosition, listener);
144     }
145 
146     /**
147      * Gets number of dimensions of points.
148      *
149      * @return number of dimensions of points.
150      */
151     @Override
152     public int getNumberOfDimensions() {
153         return Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH;
154     }
155 
156     /**
157      * Gets estimated position or null if not available yet.
158      *
159      * @return estimated position or null.
160      */
161     @Override
162     public Point3D getEstimatedPosition() {
163         if (estimatedPositionCoordinates == null) {
164             return null;
165         }
166 
167         final var result = new InhomogeneousPoint3D();
168         getEstimatedPosition(result);
169         return result;
170     }
171 
172     /**
173      * Creates an instance of a non-linear 3D position estimator using provided type.
174      *
175      * @param type type to be used.
176      * @return a non-linear 3D position estimator.
177      */
178     public static NonLinearFingerprintPositionEstimator3D create(final NonLinearFingerprintPositionEstimatorType type) {
179         return switch (type) {
180             case THIRD_ORDER -> new ThirdOrderNonLinearFingerprintPositionEstimator3D();
181             case SECOND_ORDER -> new SecondOrderNonLinearFingerprintPositionEstimator3D();
182             default -> new FirstOrderNonLinearFingerprintPositionEstimator3D();
183         };
184     }
185 
186     /**
187      * Creates an instance of a non-linear 3D position estimator using provided type.
188      *
189      * @param listener listener in charge of handling events.
190      * @param type     a non-linear 3D position estimator.
191      * @return a non-linear 3D position estimator.
192      */
193     public static NonLinearFingerprintPositionEstimator3D create(
194             final FingerprintPositionEstimatorListener<Point3D> listener,
195             final NonLinearFingerprintPositionEstimatorType type) {
196         return switch (type) {
197             case THIRD_ORDER -> new ThirdOrderNonLinearFingerprintPositionEstimator3D(listener);
198             case SECOND_ORDER -> new SecondOrderNonLinearFingerprintPositionEstimator3D(listener);
199             default -> new FirstOrderNonLinearFingerprintPositionEstimator3D(listener);
200         };
201     }
202 
203     /**
204      * Creates an instance of a non-linear 3D position estimator using provided type.
205      *
206      * @param locatedFingerprints located fingerprints containing RSSI readings.
207      * @param fingerprint         fingerprint containing readings at an unknown location
208      *                            for provided located fingerprints.
209      * @param sources             located radio sources.
210      * @param type                a non-linear 3D position estimator.
211      * @return a non-linear 3D position estimator.
212      * @throws IllegalArgumentException if provided non located fingerprint is null,
213      *                                  located fingerprints value is null or there are not enough fingerprints or
214      *                                  readings within provided fingerprints (for 3D position estimation 3 located
215      *                                  total readings are required among all fingerprints).
216      */
217     public static NonLinearFingerprintPositionEstimator3D create(
218             final List<? extends RssiFingerprintLocated<? extends RadioSource,
219                     ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
220             final RssiFingerprint<? extends RadioSource,
221                     ? extends RssiReading<? extends RadioSource>> fingerprint,
222             final List<? extends RadioSourceLocated<Point3D>> sources,
223             final NonLinearFingerprintPositionEstimatorType type) {
224         return switch (type) {
225             case THIRD_ORDER -> new ThirdOrderNonLinearFingerprintPositionEstimator3D(
226                     locatedFingerprints, fingerprint, sources);
227             case SECOND_ORDER -> new SecondOrderNonLinearFingerprintPositionEstimator3D(
228                     locatedFingerprints, fingerprint, sources);
229             default -> new FirstOrderNonLinearFingerprintPositionEstimator3D(
230                     locatedFingerprints, fingerprint, sources);
231         };
232     }
233 
234     /**
235      * Creates an instance of a non-linear 3D position estimator using provided type.
236      *
237      * @param locatedFingerprints located fingerprints containing RSSI readings.
238      * @param fingerprint         fingerprint containing readings at an unknown location
239      *                            for provided located fingerprints.
240      * @param sources             located radio sources.
241      * @param listener            listener in charge of handling events.
242      * @param type                a non-linear 3D position estimator.
243      * @return a non-linear 3D position estimator.
244      * @throws IllegalArgumentException if provided non located fingerprint is null,
245      *                                  located fingerprints value is null or there are not enough fingerprints or
246      *                                  readings within provided fingerprints (for 3D position estimation 3 located
247      *                                  total readings are required among all fingerprints).
248      */
249     public static NonLinearFingerprintPositionEstimator3D create(
250             final List<? extends RssiFingerprintLocated<? extends RadioSource,
251                     ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
252             final RssiFingerprint<? extends RadioSource,
253                     ? extends RssiReading<? extends RadioSource>> fingerprint,
254             final List<? extends RadioSourceLocated<Point3D>> sources,
255             final FingerprintPositionEstimatorListener<Point3D> listener,
256             final NonLinearFingerprintPositionEstimatorType type) {
257         return switch (type) {
258             case THIRD_ORDER -> new ThirdOrderNonLinearFingerprintPositionEstimator3D(
259                     locatedFingerprints, fingerprint, sources, listener);
260             case SECOND_ORDER -> new SecondOrderNonLinearFingerprintPositionEstimator3D(
261                     locatedFingerprints, fingerprint, sources, listener);
262             default -> new FirstOrderNonLinearFingerprintPositionEstimator3D(
263                     locatedFingerprints, fingerprint, sources, listener);
264         };
265     }
266 
267     /**
268      * Creates an instance of a non-linear 3D position estimator using provided type.
269      *
270      * @param locatedFingerprints located fingerprints containing RSSI readings.
271      * @param fingerprint         fingerprint containing readings at an unknown location
272      *                            for provided located fingerprints.
273      * @param sources             located radio sources.
274      * @param initialPosition     initial position to start the solving algorithm or null.
275      * @param type                a non-linear 3D position estimator.
276      * @return a non-linear 3D position estimator.
277      * @throws IllegalArgumentException if provided non located fingerprint is null,
278      *                                  located fingerprints value is null or there are not enough fingerprints or
279      *                                  readings within provided fingerprints (for 3D position estimation 3 located
280      *                                  total readings are required among all fingerprints).
281      */
282     public static NonLinearFingerprintPositionEstimator3D create(
283             final List<? extends RssiFingerprintLocated<? extends RadioSource,
284                     ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
285             final RssiFingerprint<? extends RadioSource,
286                     ? extends RssiReading<? extends RadioSource>> fingerprint,
287             final List<? extends RadioSourceLocated<Point3D>> sources,
288             final Point3D initialPosition, NonLinearFingerprintPositionEstimatorType type) {
289         return switch (type) {
290             case THIRD_ORDER -> new ThirdOrderNonLinearFingerprintPositionEstimator3D(
291                     locatedFingerprints, fingerprint, sources, initialPosition);
292             case SECOND_ORDER -> new SecondOrderNonLinearFingerprintPositionEstimator3D(
293                     locatedFingerprints, fingerprint, sources, initialPosition);
294             default -> new FirstOrderNonLinearFingerprintPositionEstimator3D(
295                     locatedFingerprints, fingerprint, sources, initialPosition);
296         };
297     }
298 
299     /**
300      * Creates an instance of a non-linear 3D position estimator using provided type.
301      *
302      * @param locatedFingerprints located fingerprints containing RSSI readings.
303      * @param fingerprint         fingerprint containing readings at an unknown location
304      *                            for provided located fingerprints.
305      * @param sources             located radio sources.
306      * @param initialPosition     initial position to start the solving algorithm or null.
307      * @param listener            listener in charge of handling events.
308      * @param type                a non-linear 3D position estimator.
309      * @return a non-linear 3D position estimator.
310      * @throws IllegalArgumentException if provided non located fingerprint is null,
311      *                                  located fingerprints value is null or there are not enough fingerprints or
312      *                                  readings within provided fingerprints (for 3D position estimation 3 located
313      *                                  total readings are required among all fingerprints).
314      */
315     public static NonLinearFingerprintPositionEstimator3D create(
316             final List<? extends RssiFingerprintLocated<
317                     ? extends RadioSource, ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
318             final RssiFingerprint<? extends RadioSource,
319                     ? extends RssiReading<? extends RadioSource>> fingerprint,
320             final List<? extends RadioSourceLocated<Point3D>> sources, Point3D initialPosition,
321             final FingerprintPositionEstimatorListener<Point3D> listener,
322             final NonLinearFingerprintPositionEstimatorType type) {
323         return switch (type) {
324             case THIRD_ORDER -> new ThirdOrderNonLinearFingerprintPositionEstimator3D(
325                     locatedFingerprints, fingerprint, sources, initialPosition, listener);
326             case SECOND_ORDER -> new SecondOrderNonLinearFingerprintPositionEstimator3D(
327                     locatedFingerprints, fingerprint, sources, initialPosition, listener);
328             default -> new FirstOrderNonLinearFingerprintPositionEstimator3D(
329                     locatedFingerprints, fingerprint, sources, initialPosition, listener);
330         };
331     }
332 
333     /**
334      * Creates an instance of a non-linear 3D position estimator using provided type.
335      *
336      * @return a non-linear 3D position estimator.
337      */
338     public static NonLinearFingerprintPositionEstimator3D create() {
339         return create(DEFAULT_TYPE);
340     }
341 
342     /**
343      * Creates an instance of a non-linear 3D position estimator using provided type.
344      *
345      * @param listener listener in charge of handling events.
346      * @return a non-linear 3D position estimator.
347      */
348     public static NonLinearFingerprintPositionEstimator3D create(
349             final FingerprintPositionEstimatorListener<Point3D> listener) {
350         return create(listener, DEFAULT_TYPE);
351     }
352 
353     /**
354      * Creates an instance of a non-linear 3D position estimator using provided type.
355      *
356      * @param locatedFingerprints located fingerprints containing RSSI readings.
357      * @param fingerprint         fingerprint containing readings at an unknown location
358      *                            for provided located fingerprints.
359      * @param sources             located radio sources.
360      * @return a non-linear 3D position estimator.
361      * @throws IllegalArgumentException if provided non located fingerprint is null,
362      *                                  located fingerprints value is null or there are not enough fingerprints or
363      *                                  readings within provided fingerprints (for 3D position estimation 3 located
364      *                                  total readings are required among all fingerprints).
365      */
366     public static NonLinearFingerprintPositionEstimator3D create(
367             final List<? extends RssiFingerprintLocated<? extends RadioSource,
368                     ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
369             final RssiFingerprint<? extends RadioSource,
370                     ? extends RssiReading<? extends RadioSource>> fingerprint,
371             final List<? extends RadioSourceLocated<Point3D>> sources) {
372         return create(locatedFingerprints, fingerprint, sources, DEFAULT_TYPE);
373     }
374 
375     /**
376      * Creates an instance of a non-linear 3D position estimator using provided type.
377      *
378      * @param locatedFingerprints located fingerprints containing RSSI readings.
379      * @param fingerprint         fingerprint containing readings at an unknown location
380      *                            for provided located fingerprints.
381      * @param sources             located radio sources.
382      * @param listener            listener in charge of handling events.
383      * @return a non-linear 3D position estimator.
384      * @throws IllegalArgumentException if provided non located fingerprint is null,
385      *                                  located fingerprints value is null or there are not enough fingerprints or
386      *                                  readings within provided fingerprints (for 3D position estimation 3 located
387      *                                  total readings are required among all fingerprints).
388      */
389     public static NonLinearFingerprintPositionEstimator3D create(
390             final List<? extends RssiFingerprintLocated<? extends RadioSource,
391                     ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
392             final RssiFingerprint<? extends RadioSource,
393                     ? extends RssiReading<? extends RadioSource>> fingerprint,
394             final List<? extends RadioSourceLocated<Point3D>> sources,
395             final FingerprintPositionEstimatorListener<Point3D> listener) {
396         return create(locatedFingerprints, fingerprint, sources, listener, DEFAULT_TYPE);
397     }
398 
399     /**
400      * Creates an instance of a non-linear 3D position estimator using provided type.
401      *
402      * @param locatedFingerprints located fingerprints containing RSSI readings.
403      * @param fingerprint         fingerprint containing readings at an unknown location
404      *                            for provided located fingerprints.
405      * @param sources             located radio sources.
406      * @param initialPosition     initial position to start the solving algorithm or null.
407      * @return a non-linear 3D position estimator.
408      * @throws IllegalArgumentException if provided non located fingerprint is null,
409      *                                  located fingerprints value is null or there are not enough fingerprints or
410      *                                  readings within provided fingerprints (for 3D position estimation 3 located
411      *                                  total readings are required among all fingerprints).
412      */
413     public static NonLinearFingerprintPositionEstimator3D create(
414             final List<? extends RssiFingerprintLocated<? extends RadioSource,
415                     ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
416             final RssiFingerprint<? extends RadioSource,
417                     ? extends RssiReading<? extends RadioSource>> fingerprint,
418             final List<? extends RadioSourceLocated<Point3D>> sources,
419             final Point3D initialPosition) {
420         return create(locatedFingerprints, fingerprint, sources, initialPosition, DEFAULT_TYPE);
421     }
422 
423     /**
424      * Creates an instance of a non-linear 3D position estimator using provided type.
425      *
426      * @param locatedFingerprints located fingerprints containing RSSI readings.
427      * @param fingerprint         fingerprint containing readings at an unknown location
428      *                            for provided located fingerprints.
429      * @param sources             located radio sources.
430      * @param initialPosition     initial position to start the solving algorithm or null.
431      * @param listener            listener in charge of handling events.
432      * @return a non-linear 3D position estimator.
433      * @throws IllegalArgumentException if provided non located fingerprint is null,
434      *                                  located fingerprints value is null or there are not enough fingerprints or
435      *                                  readings within provided fingerprints (for 3D position estimation 3 located
436      *                                  total readings are required among all fingerprints).
437      */
438     public static NonLinearFingerprintPositionEstimator3D create(
439             final List<? extends RssiFingerprintLocated<
440                     ? extends RadioSource, ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
441             final RssiFingerprint<? extends RadioSource,
442                     ? extends RssiReading<? extends RadioSource>> fingerprint,
443             final List<? extends RadioSourceLocated<Point3D>> sources, Point3D initialPosition,
444             final FingerprintPositionEstimatorListener<Point3D> listener) {
445         return create(locatedFingerprints, fingerprint, sources, initialPosition, listener, DEFAULT_TYPE);
446     }
447 }