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.position;
17  
18  import com.irurueta.geometry.InhomogeneousPoint2D;
19  import com.irurueta.geometry.Point2D;
20  import com.irurueta.navigation.LockedException;
21  import com.irurueta.navigation.indoor.RadioSource;
22  import com.irurueta.navigation.indoor.RadioSourceLocated;
23  import com.irurueta.navigation.indoor.RangingFingerprint;
24  import com.irurueta.navigation.indoor.RangingReading;
25  import com.irurueta.numerical.robust.RobustEstimatorMethod;
26  
27  import java.util.List;
28  
29  /**
30   * Base class for robust ranging 2D position estimators using located radio sources and
31   * their ranging readings at unknown locations.
32   * These kind of estimators can be used to robustly determine the 2D position of a given
33   * device by getting ranging readings at an unknown location of different radio sources
34   * whose locations are known.
35   * Implementations of this class should be able to detect and discard outliers in order
36   * to find the best solution.
37   */
38  @SuppressWarnings("DuplicatedCode")
39  public abstract class RobustRangingPositionEstimator2D extends
40          RobustRangingPositionEstimator<Point2D> {
41  
42      /**
43       * Constructor.
44       */
45      protected RobustRangingPositionEstimator2D() {
46          super();
47          preliminarySubsetSize = getMinRequiredSources();
48      }
49  
50      /**
51       * Constructor.
52       *
53       * @param listener listener in charge of handling events.
54       */
55      protected RobustRangingPositionEstimator2D(final RobustRangingPositionEstimatorListener<Point2D> listener) {
56          super(listener);
57          preliminarySubsetSize = getMinRequiredSources();
58      }
59  
60      /**
61       * Gets minimum required number of located radio sources to perform lateration.
62       *
63       * @return minimum required number of located radio sources to perform lateration.
64       */
65      @Override
66      public int getMinRequiredSources() {
67          return Point2D.POINT2D_HOMOGENEOUS_COORDINATES_LENGTH;
68      }
69  
70  
71      /**
72       * Creates a robust 2D position estimator.
73       *
74       * @param method robust estimator method.
75       * @return a robust 2D position estimator.
76       */
77      public static RobustRangingPositionEstimator2D create(final RobustEstimatorMethod method) {
78          return switch (method) {
79              case RANSAC -> new RANSACRobustRangingPositionEstimator2D();
80              case LMEDS -> new LMedSRobustRangingPositionEstimator2D();
81              case MSAC -> new MSACRobustRangingPositionEstimator2D();
82              case PROSAC -> new PROSACRobustRangingPositionEstimator2D();
83              default -> new PROMedSRobustRangingPositionEstimator2D();
84          };
85      }
86  
87      /**
88       * Creates a robust 2D position estimator.
89       *
90       * @param sources located radio sources used for lateration.
91       * @param method  robust estimator method.
92       * @return a robust 2D position estimator.
93       * @throws IllegalArgumentException if provided sources is null or the number of
94       *                                  provided sources is less than the required minimum.
95       */
96      public static RobustRangingPositionEstimator2D create(
97              final List<? extends RadioSourceLocated<Point2D>> sources, final RobustEstimatorMethod method) {
98          return switch (method) {
99              case RANSAC -> new RANSACRobustRangingPositionEstimator2D(sources);
100             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(sources);
101             case MSAC -> new MSACRobustRangingPositionEstimator2D(sources);
102             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(sources);
103             default -> new PROMedSRobustRangingPositionEstimator2D(sources);
104         };
105     }
106 
107     /**
108      * Creates a robust 2D position estimator.
109      *
110      * @param fingerprint fingerprint containing ranging readings at an unknown
111      *                    location for provided located radio sources.
112      * @param method      robust estimator method.
113      * @return a robust 2D position estimator.
114      * @throws IllegalArgumentException if provided fingerprint is null.
115      */
116     public static RobustRangingPositionEstimator2D create(
117             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
118                     extends RadioSource>> fingerprint, final RobustEstimatorMethod method) {
119         return switch (method) {
120             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(fingerprint);
121             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(fingerprint);
122             case MSAC -> new MSACRobustRangingPositionEstimator2D(fingerprint);
123             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(fingerprint);
124             default -> new PROMedSRobustRangingPositionEstimator2D(fingerprint);
125         };
126     }
127 
128     /**
129      * Creates a robust 2D position estimator.
130      *
131      * @param sources     located radio sources used for lateration.
132      * @param fingerprint fingerprint containing ranging readings at an unknown
133      *                    location for provided located radio sources.
134      * @param method      robust estimator method.
135      * @return a robust 2D position estimator.
136      * @throws IllegalArgumentException if either provided sources or fingerprint is null
137      *                                  or the number of provided sources is less than the required minimum.
138      */
139     public static RobustRangingPositionEstimator2D create(
140             final List<? extends RadioSourceLocated<Point2D>> sources,
141             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
142                     extends RadioSource>> fingerprint, final RobustEstimatorMethod method) {
143         return switch (method) {
144             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(sources, fingerprint);
145             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(sources, fingerprint);
146             case MSAC -> new MSACRobustRangingPositionEstimator2D(sources, fingerprint);
147             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(sources, fingerprint);
148             default -> new PROMedSRobustRangingPositionEstimator2D(sources, fingerprint);
149         };
150     }
151 
152     /**
153      * Creates a robust 2D position estimator.
154      *
155      * @param listener listener in charge of handling events.
156      * @param method   robust estimator method.
157      * @return a robust 2D position estimator.
158      */
159     public static RobustRangingPositionEstimator2D create(
160             final RobustRangingPositionEstimatorListener<Point2D> listener, final RobustEstimatorMethod method) {
161         return switch (method) {
162             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(listener);
163             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(listener);
164             case MSAC -> new MSACRobustRangingPositionEstimator2D(listener);
165             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(listener);
166             default -> new PROMedSRobustRangingPositionEstimator2D(listener);
167         };
168     }
169 
170     /**
171      * Creates a robust 2D position estimator.
172      *
173      * @param sources  located radio sources used for lateration.
174      * @param listener listener in charge of handling events.
175      * @param method   robust estimator method.
176      * @return a robust 2D position estimator.
177      * @throws IllegalArgumentException if provided sources is null or the number of
178      *                                  provided sources is less than the required minimum.
179      */
180     public static RobustRangingPositionEstimator2D create(
181             final List<? extends RadioSourceLocated<Point2D>> sources,
182             final RobustRangingPositionEstimatorListener<Point2D> listener, final RobustEstimatorMethod method) {
183         return switch (method) {
184             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(sources, listener);
185             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(sources, listener);
186             case MSAC -> new MSACRobustRangingPositionEstimator2D(sources, listener);
187             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(sources, listener);
188             default -> new PROMedSRobustRangingPositionEstimator2D(sources, listener);
189         };
190     }
191 
192     /**
193      * Creates a robust 2D position estimator.
194      *
195      * @param fingerprint fingerprint containing ranging readings at an unknown
196      *                    location for provided located radio sources.
197      * @param listener    listener in charge of handling events.
198      * @param method      robust estimator method.
199      * @return a robust 2D position estimator.
200      * @throws IllegalArgumentException if provided fingerprint is null.
201      */
202     public static RobustRangingPositionEstimator2D create(
203             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
204                     extends RadioSource>> fingerprint,
205             final RobustRangingPositionEstimatorListener<Point2D> listener, final RobustEstimatorMethod method) {
206         return switch (method) {
207             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(fingerprint, listener);
208             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(fingerprint, listener);
209             case MSAC -> new MSACRobustRangingPositionEstimator2D(fingerprint, listener);
210             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(fingerprint, listener);
211             default -> new PROMedSRobustRangingPositionEstimator2D(fingerprint, listener);
212         };
213     }
214 
215     /**
216      * Creates a robust 2D position estimator.
217      *
218      * @param sources     located radio sources used for lateration.
219      * @param fingerprint fingerprint containing ranging readings at an unknown
220      *                    location for provided located radio sources.
221      * @param listener    listener in charge of handling events.
222      * @param method      robust estimator method.
223      * @return a robust 2D position estimator.
224      * @throws IllegalArgumentException if either provided sources or fingerprint is null
225      *                                  or the number of provided sources is less than the required minimum.
226      */
227     public static RobustRangingPositionEstimator2D create(
228             final List<? extends RadioSourceLocated<Point2D>> sources,
229             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
230                     extends RadioSource>> fingerprint,
231             final RobustRangingPositionEstimatorListener<Point2D> listener, final RobustEstimatorMethod method) {
232         return switch (method) {
233             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(sources, fingerprint, listener);
234             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(sources, fingerprint, listener);
235             case MSAC -> new MSACRobustRangingPositionEstimator2D(sources, fingerprint, listener);
236             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(sources, fingerprint, listener);
237             default -> new PROMedSRobustRangingPositionEstimator2D(sources, fingerprint, listener);
238         };
239     }
240 
241     /**
242      * Creates a robust 2D position estimator.
243      *
244      * @param sourceQualityScores             quality scores corresponding to
245      *                                        each provided located radio source.
246      *                                        The larger the score value the better
247      *                                        the quality of the radio source.
248      * @param fingerprintReadingQualityScores quality scores corresponding to readings
249      *                                        within provided fingerprint. The larger
250      *                                        the score the better the quality of the
251      *                                        reading.
252      * @param method                          robust estimator method.
253      * @return a robust 2D position estimator.
254      */
255     public static RobustRangingPositionEstimator2D create(
256             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
257             final RobustEstimatorMethod method) {
258         return switch (method) {
259             case RANSAC -> new RANSACRobustRangingPositionEstimator2D();
260             case LMEDS -> new LMedSRobustRangingPositionEstimator2D();
261             case MSAC -> new MSACRobustRangingPositionEstimator2D();
262             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(sourceQualityScores,
263                     fingerprintReadingQualityScores);
264             default -> new PROMedSRobustRangingPositionEstimator2D(sourceQualityScores,
265                     fingerprintReadingQualityScores);
266         };
267     }
268 
269     /**
270      * Creates a robust 2D position estimator.
271      *
272      * @param sourceQualityScores             quality scores corresponding to
273      *                                        each provided located radio source.
274      *                                        The larger the score value the better
275      *                                        the quality of the radio source.
276      * @param fingerprintReadingQualityScores quality scores corresponding to readings
277      *                                        within provided fingerprint. The larger
278      *                                        the score the better the quality of the
279      *                                        reading.
280      * @param sources                         located radio sources used for
281      *                                        lateration.
282      * @param method                          robust estimator method.
283      * @return a robust 2D position estimator.
284      * @throws IllegalArgumentException if provided sources is null or the number of
285      *                                  provided sources is less than the required minimum.
286      */
287     public static RobustRangingPositionEstimator2D create(
288             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
289             final List<? extends RadioSourceLocated<Point2D>> sources, final RobustEstimatorMethod method) {
290         return switch (method) {
291             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(sources);
292             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(sources);
293             case MSAC -> new MSACRobustRangingPositionEstimator2D(sources);
294             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(sourceQualityScores,
295                     fingerprintReadingQualityScores, sources);
296             default -> new PROMedSRobustRangingPositionEstimator2D(sourceQualityScores, fingerprintReadingQualityScores,
297                     sources);
298         };
299     }
300 
301     /**
302      * Creates a robust 2D position estimator.
303      *
304      * @param sourceQualityScores             quality scores corresponding to
305      *                                        each provided located radio source.
306      *                                        The larger the score value the better
307      *                                        the quality of the radio source.
308      * @param fingerprintReadingQualityScores quality scores corresponding to readings
309      *                                        within provided fingerprint. The larger
310      *                                        the score the better the quality of the
311      *                                        reading.
312      * @param fingerprint                     fingerprint containing ranging
313      *                                        readings at an unknown location for
314      *                                        provided located radio sources.
315      * @param method                          robust estimator method.
316      * @return a robust 2D position estimator.
317      * @throws IllegalArgumentException if provided fingerprint is null.
318      */
319     public static RobustRangingPositionEstimator2D create(
320             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
321             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
322                     extends RadioSource>> fingerprint,
323             final RobustEstimatorMethod method) {
324         return switch (method) {
325             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(fingerprint);
326             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(fingerprint);
327             case MSAC -> new MSACRobustRangingPositionEstimator2D(fingerprint);
328             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(sourceQualityScores,
329                     fingerprintReadingQualityScores, fingerprint);
330             default -> new PROMedSRobustRangingPositionEstimator2D(sourceQualityScores, fingerprintReadingQualityScores,
331                     fingerprint);
332         };
333     }
334 
335     /**
336      * Creates a robust 2D position estimator.
337      *
338      * @param sourceQualityScores             quality scores corresponding to
339      *                                        each provided located radio source.
340      *                                        The larger the score value the better
341      *                                        the quality of the radio source.
342      * @param fingerprintReadingQualityScores quality scores corresponding to readings
343      *                                        within provided fingerprint. The larger
344      *                                        the score the better the quality of the
345      *                                        reading.
346      * @param sources                         located radio sources used for
347      *                                        lateration.
348      * @param fingerprint                     fingerprint containing ranging
349      *                                        readings at an unknown location for
350      *                                        provided located radio sources.
351      * @param method                          robust estimator method.
352      * @return a robust 2D position estimator.
353      * @throws IllegalArgumentException if either provided sources or fingerprint is null
354      *                                  or the number of provided sources is less than the required minimum.
355      */
356     public static RobustRangingPositionEstimator2D create(
357             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
358             final List<? extends RadioSourceLocated<Point2D>> sources,
359             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
360                     extends RadioSource>> fingerprint,
361             final RobustEstimatorMethod method) {
362         return switch (method) {
363             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(sources, fingerprint);
364             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(sources, fingerprint);
365             case MSAC -> new MSACRobustRangingPositionEstimator2D(sources, fingerprint);
366             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(sourceQualityScores,
367                     fingerprintReadingQualityScores, sources, fingerprint);
368             default -> new PROMedSRobustRangingPositionEstimator2D(sourceQualityScores, fingerprintReadingQualityScores,
369                     sources, fingerprint);
370         };
371     }
372 
373     /**
374      * Creates a robust 2D position estimator.
375      *
376      * @param sourceQualityScores             quality scores corresponding to
377      *                                        each provided located radio source.
378      *                                        The larger the score value the better
379      *                                        the quality of the radio source.
380      * @param fingerprintReadingQualityScores quality scores corresponding to readings
381      *                                        within provided fingerprint. The larger
382      *                                        the score the better the quality of the
383      *                                        reading.
384      * @param listener                        listener in charge of handling events.
385      * @param method                          robust estimator method.
386      * @return a robust 2D position estimator.
387      */
388     public static RobustRangingPositionEstimator2D create(
389             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
390             final RobustRangingPositionEstimatorListener<Point2D> listener, final RobustEstimatorMethod method) {
391         return switch (method) {
392             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(listener);
393             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(listener);
394             case MSAC -> new MSACRobustRangingPositionEstimator2D(listener);
395             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(sourceQualityScores,
396                     fingerprintReadingQualityScores, listener);
397             default -> new PROMedSRobustRangingPositionEstimator2D(sourceQualityScores, fingerprintReadingQualityScores,
398                     listener);
399         };
400     }
401 
402     /**
403      * Creates a robust 2D position estimator.
404      *
405      * @param sourceQualityScores             quality scores corresponding to
406      *                                        each provided located radio source.
407      *                                        The larger the score value the better
408      *                                        the quality of the radio source.
409      * @param fingerprintReadingQualityScores quality scores corresponding to readings
410      *                                        within provided fingerprint. The larger
411      *                                        the score the better the quality of the
412      *                                        reading.
413      * @param sources                         located radio sources used for
414      *                                        lateration.
415      * @param listener                        listener in charge of handling events.
416      * @param method                          robust estimator method.
417      * @return a robust 2D position estimator.
418      * @throws IllegalArgumentException if provided sources is null or the number of
419      *                                  provided sources is less than the required minimum.
420      */
421     public static RobustRangingPositionEstimator2D create(
422             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
423             final List<? extends RadioSourceLocated<Point2D>> sources,
424             final RobustRangingPositionEstimatorListener<Point2D> listener, final RobustEstimatorMethod method) {
425         return switch (method) {
426             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(sources, listener);
427             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(sources, listener);
428             case MSAC -> new MSACRobustRangingPositionEstimator2D(sources, listener);
429             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(sourceQualityScores,
430                     fingerprintReadingQualityScores, sources, listener);
431             default -> new PROMedSRobustRangingPositionEstimator2D(sourceQualityScores, fingerprintReadingQualityScores,
432                     sources, listener);
433         };
434     }
435 
436     /**
437      * Creates a robust 2D position estimator.
438      *
439      * @param sourceQualityScores             quality scores corresponding to
440      *                                        each provided located radio source.
441      *                                        The larger the score value the better
442      *                                        the quality of the radio source.
443      * @param fingerprintReadingQualityScores quality scores corresponding to readings
444      *                                        within provided fingerprint. The larger
445      *                                        the score the better the quality of the
446      *                                        reading.
447      * @param fingerprint                     fingerprint containing ranging
448      *                                        readings at an unknown location for
449      *                                        provided located radio sources.
450      * @param listener                        listener in charge of handling events.
451      * @param method                          robust estimator method.
452      * @return a robust 2D position estimator.
453      * @throws IllegalArgumentException if provided fingerprint is null.
454      */
455     public static RobustRangingPositionEstimator2D create(
456             final double[] sourceQualityScores,
457             final double[] fingerprintReadingQualityScores,
458             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
459                     extends RadioSource>> fingerprint,
460             final RobustRangingPositionEstimatorListener<Point2D> listener,
461             final RobustEstimatorMethod method) {
462         return switch (method) {
463             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(fingerprint, listener);
464             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(fingerprint, listener);
465             case MSAC -> new MSACRobustRangingPositionEstimator2D(fingerprint, listener);
466             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(sourceQualityScores,
467                     fingerprintReadingQualityScores, fingerprint, listener);
468             default -> new PROMedSRobustRangingPositionEstimator2D(sourceQualityScores, fingerprintReadingQualityScores,
469                     fingerprint, listener);
470         };
471     }
472 
473     /**
474      * Creates a robust 2D position estimator.
475      *
476      * @param sourceQualityScores             quality scores corresponding to
477      *                                        each provided located radio source.
478      *                                        The larger the score value the better
479      *                                        the quality of the radio source.
480      * @param fingerprintReadingQualityScores quality scores corresponding to readings
481      *                                        within provided fingerprint. The larger
482      *                                        the score the better the quality of the
483      *                                        reading.
484      * @param sources                         located radio sources used for
485      *                                        lateration.
486      * @param fingerprint                     fingerprint containing ranging
487      *                                        readings at an unknown location for
488      *                                        provided located radio sources.
489      * @param listener                        listener in charge of handling events.
490      * @param method                          robust estimator method.
491      * @return a robust 2D position estimator.
492      * @throws IllegalArgumentException if either provided sources or fingerprint is null
493      *                                  or the number of provided sources is less than the required minimum.
494      */
495     public static RobustRangingPositionEstimator2D create(
496             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
497             final List<? extends RadioSourceLocated<Point2D>> sources,
498             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
499                     extends RadioSource>> fingerprint,
500             final RobustRangingPositionEstimatorListener<Point2D> listener,
501             final RobustEstimatorMethod method) {
502         return switch (method) {
503             case RANSAC -> new RANSACRobustRangingPositionEstimator2D(sources, fingerprint, listener);
504             case LMEDS -> new LMedSRobustRangingPositionEstimator2D(sources, fingerprint, listener);
505             case MSAC -> new MSACRobustRangingPositionEstimator2D(sources, fingerprint, listener);
506             case PROSAC -> new PROSACRobustRangingPositionEstimator2D(sourceQualityScores,
507                     fingerprintReadingQualityScores, sources, fingerprint, listener);
508             default -> new PROMedSRobustRangingPositionEstimator2D(sourceQualityScores, fingerprintReadingQualityScores,
509                     sources, fingerprint, listener);
510         };
511     }
512 
513     /**
514      * Creates a robust 2D position estimator.
515      *
516      * @return a robust 2D position estimator.
517      */
518     public static RobustRangingPositionEstimator2D create() {
519         return create(DEFAULT_ROBUST_METHOD);
520     }
521 
522     /**
523      * Creates a robust 2D position estimator.
524      *
525      * @param sources located radio sources used for lateration.
526      * @return a robust 2D position estimator.
527      * @throws IllegalArgumentException if provided sources is null or the number of
528      *                                  provided sources is less than the required minimum.
529      */
530     public static RobustRangingPositionEstimator2D create(final List<? extends RadioSourceLocated<Point2D>> sources) {
531         return create(sources, DEFAULT_ROBUST_METHOD);
532     }
533 
534     /**
535      * Creates a robust 2D position estimator.
536      *
537      * @param fingerprint fingerprint containing ranging readings at an unknown
538      *                    location for provided located radio sources.
539      * @return a robust 2D position estimator.
540      * @throws IllegalArgumentException if provided fingerprint is null.
541      */
542     public static RobustRangingPositionEstimator2D create(
543             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
544                     extends RadioSource>> fingerprint) {
545         return create(fingerprint, DEFAULT_ROBUST_METHOD);
546     }
547 
548     /**
549      * Creates a robust 2D position estimator.
550      *
551      * @param sources     located radio sources used for lateration.
552      * @param fingerprint fingerprint containing ranging readings at an unknown
553      *                    location for provided located radio sources.
554      * @return a robust 2D position estimator.
555      * @throws IllegalArgumentException if either provided sources or fingerprint is null
556      *                                  or the number of provided sources is less than the required minimum.
557      */
558     public static RobustRangingPositionEstimator2D create(
559             final List<? extends RadioSourceLocated<Point2D>> sources,
560             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
561                     extends RadioSource>> fingerprint) {
562         return create(sources, fingerprint, DEFAULT_ROBUST_METHOD);
563     }
564 
565     /**
566      * Creates a robust 2D position estimator.
567      *
568      * @param listener listener in charge of handling events.
569      * @return a robust 2D position estimator.
570      */
571     public static RobustRangingPositionEstimator2D create(
572             final RobustRangingPositionEstimatorListener<Point2D> listener) {
573         return create(listener, DEFAULT_ROBUST_METHOD);
574     }
575 
576     /**
577      * Creates a robust 2D position estimator.
578      *
579      * @param sources  located radio sources used for lateration.
580      * @param listener listener in charge of handling events.
581      * @return a robust 2D position estimator.
582      * @throws IllegalArgumentException if provided sources is null or the number of
583      *                                  provided sources is less than the required minimum.
584      */
585     public static RobustRangingPositionEstimator2D create(
586             final List<? extends RadioSourceLocated<Point2D>> sources,
587             final RobustRangingPositionEstimatorListener<Point2D> listener) {
588         return create(sources, listener, DEFAULT_ROBUST_METHOD);
589     }
590 
591     /**
592      * Creates a robust 2D position estimator.
593      *
594      * @param fingerprint fingerprint containing ranging readings at an unknown
595      *                    location for provided located radio sources.
596      * @param listener    listener in charge of handling events.
597      * @return a robust 2D position estimator.
598      * @throws IllegalArgumentException if provided fingerprint is null.
599      */
600     public static RobustRangingPositionEstimator2D create(
601             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
602                     extends RadioSource>> fingerprint,
603             final RobustRangingPositionEstimatorListener<Point2D> listener) {
604         return create(fingerprint, listener, DEFAULT_ROBUST_METHOD);
605     }
606 
607     /**
608      * Creates a robust 2D position estimator.
609      *
610      * @param sources     located radio sources used for lateration.
611      * @param fingerprint fingerprint containing ranging readings at an unknown
612      *                    location for provided located radio sources.
613      * @param listener    listener in charge of handling events.
614      * @return a robust 2D position estimator.
615      * @throws IllegalArgumentException if either provided sources or fingerprint is null
616      *                                  or the number of provided sources is less than the required minimum.
617      */
618     public static RobustRangingPositionEstimator2D create(
619             final List<? extends RadioSourceLocated<Point2D>> sources,
620             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
621                     extends RadioSource>> fingerprint,
622             final RobustRangingPositionEstimatorListener<Point2D> listener) {
623         return create(sources, fingerprint, listener, DEFAULT_ROBUST_METHOD);
624     }
625 
626     /**
627      * Creates a robust 2D position estimator.
628      *
629      * @param sourceQualityScores             quality scores corresponding to
630      *                                        each provided located radio source.
631      *                                        The larger the score value the better
632      *                                        the quality of the radio source.
633      * @param fingerprintReadingQualityScores quality scores corresponding to readings
634      *                                        within provided fingerprint. The larger
635      *                                        the score the better the quality of the
636      *                                        reading.
637      * @return a robust 2D position estimator.
638      */
639     public static RobustRangingPositionEstimator2D create(
640             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores) {
641         return create(sourceQualityScores, fingerprintReadingQualityScores, DEFAULT_ROBUST_METHOD);
642     }
643 
644     /**
645      * Creates a robust 2D position estimator.
646      *
647      * @param sourceQualityScores             quality scores corresponding to
648      *                                        each provided located radio source.
649      *                                        The larger the score value the better
650      *                                        the quality of the radio source.
651      * @param fingerprintReadingQualityScores quality scores corresponding to readings
652      *                                        within provided fingerprint. The larger
653      *                                        the score the better the quality of the
654      *                                        reading.
655      * @param sources                         located radio sources used for
656      *                                        lateration.
657      * @return a robust 2D position estimator.
658      * @throws IllegalArgumentException if provided sources is null or the number of
659      *                                  provided sources is less than the required minimum.
660      */
661     public static RobustRangingPositionEstimator2D create(
662             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
663             final List<? extends RadioSourceLocated<Point2D>> sources) {
664         return create(sourceQualityScores, fingerprintReadingQualityScores, sources, DEFAULT_ROBUST_METHOD);
665     }
666 
667     /**
668      * Creates a robust 2D position estimator.
669      *
670      * @param sourceQualityScores             quality scores corresponding to
671      *                                        each provided located radio source.
672      *                                        The larger the score value the better
673      *                                        the quality of the radio source.
674      * @param fingerprintReadingQualityScores quality scores corresponding to readings
675      *                                        within provided fingerprint. The larger
676      *                                        the score the better the quality of the
677      *                                        reading.
678      * @param fingerprint                     fingerprint containing ranging
679      *                                        readings at an unknown location for
680      *                                        provided located radio sources.
681      * @return a robust 2D position estimator.
682      * @throws IllegalArgumentException if provided fingerprint is null.
683      */
684     public static RobustRangingPositionEstimator2D create(
685             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
686             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
687                     extends RadioSource>> fingerprint) {
688         return create(sourceQualityScores, fingerprintReadingQualityScores, fingerprint, DEFAULT_ROBUST_METHOD);
689     }
690 
691     /**
692      * Creates a robust 2D position estimator.
693      *
694      * @param sourceQualityScores             quality scores corresponding to
695      *                                        each provided located radio source.
696      *                                        The larger the score value the better
697      *                                        the quality of the radio source.
698      * @param fingerprintReadingQualityScores quality scores corresponding to readings
699      *                                        within provided fingerprint. The larger
700      *                                        the score the better the quality of the
701      *                                        reading.
702      * @param sources                         located radio sources used for
703      *                                        lateration.
704      * @param fingerprint                     fingerprint containing ranging
705      *                                        readings at an unknown location for
706      *                                        provided located radio sources.
707      * @return a robust 2D position estimator.
708      * @throws IllegalArgumentException if either provided sources or fingerprint is null
709      *                                  or the number of provided sources is less than the required minimum.
710      */
711     public static RobustRangingPositionEstimator2D create(
712             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
713             final List<? extends RadioSourceLocated<Point2D>> sources,
714             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
715                     extends RadioSource>> fingerprint) {
716         return create(sourceQualityScores, fingerprintReadingQualityScores, sources, fingerprint,
717                 DEFAULT_ROBUST_METHOD);
718     }
719 
720     /**
721      * Creates a robust 2D position estimator.
722      *
723      * @param sourceQualityScores             quality scores corresponding to
724      *                                        each provided located radio source.
725      *                                        The larger the score value the better
726      *                                        the quality of the radio source.
727      * @param fingerprintReadingQualityScores quality scores corresponding to readings
728      *                                        within provided fingerprint. The larger
729      *                                        the score the better the quality of the
730      *                                        reading.
731      * @param listener                        listener in charge of handling events.
732      * @return a robust 2D position estimator.
733      */
734     public static RobustRangingPositionEstimator2D create(
735             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
736             final RobustRangingPositionEstimatorListener<Point2D> listener) {
737         return create(sourceQualityScores, fingerprintReadingQualityScores, listener, DEFAULT_ROBUST_METHOD);
738     }
739 
740     /**
741      * Creates a robust 2D position estimator.
742      *
743      * @param sourceQualityScores             quality scores corresponding to
744      *                                        each provided located radio source.
745      *                                        The larger the score value the better
746      *                                        the quality of the radio source.
747      * @param fingerprintReadingQualityScores quality scores corresponding to readings
748      *                                        within provided fingerprint. The larger
749      *                                        the score the better the quality of the
750      *                                        reading.
751      * @param sources                         located radio sources used for
752      *                                        lateration.
753      * @param listener                        listener in charge of handling events.
754      * @return a robust 2D position estimator.
755      * @throws IllegalArgumentException if provided sources is null or the number of
756      *                                  provided sources is less than the required minimum.
757      */
758     public static RobustRangingPositionEstimator2D create(
759             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
760             final List<? extends RadioSourceLocated<Point2D>> sources,
761             final RobustRangingPositionEstimatorListener<Point2D> listener) {
762         return create(sourceQualityScores, fingerprintReadingQualityScores, sources, listener, DEFAULT_ROBUST_METHOD);
763     }
764 
765     /**
766      * Creates a robust 2D position estimator.
767      *
768      * @param sourceQualityScores             quality scores corresponding to
769      *                                        each provided located radio source.
770      *                                        The larger the score value the better
771      *                                        the quality of the radio source.
772      * @param fingerprintReadingQualityScores quality scores corresponding to readings
773      *                                        within provided fingerprint. The larger
774      *                                        the score the better the quality of the
775      *                                        reading.
776      * @param fingerprint                     fingerprint containing ranging
777      *                                        readings at an unknown location for
778      *                                        provided located radio sources.
779      * @param listener                        listener in charge of handling events.
780      * @return a robust 2D position estimator.
781      * @throws IllegalArgumentException if provided fingerprint is null.
782      */
783     public static RobustRangingPositionEstimator2D create(
784             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
785             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
786                     extends RadioSource>> fingerprint,
787             final RobustRangingPositionEstimatorListener<Point2D> listener) {
788         return create(sourceQualityScores, fingerprintReadingQualityScores, fingerprint, listener,
789                 DEFAULT_ROBUST_METHOD);
790     }
791 
792     /**
793      * Creates a robust 2D position estimator.
794      *
795      * @param sourceQualityScores             quality scores corresponding to
796      *                                        each provided located radio source.
797      *                                        The larger the score value the better
798      *                                        the quality of the radio source.
799      * @param fingerprintReadingQualityScores quality scores corresponding to readings
800      *                                        within provided fingerprint. The larger
801      *                                        the score the better the quality of the
802      *                                        reading.
803      * @param sources                         located radio sources used for
804      *                                        lateration.
805      * @param fingerprint                     fingerprint containing ranging
806      *                                        readings at an unknown location for
807      *                                        provided located radio sources.
808      * @param listener                        listener in charge of handling events.
809      * @return a robust 2D position estimator.
810      * @throws IllegalArgumentException if either provided sources or fingerprint is null
811      *                                  or the number of provided sources is less than the required minimum.
812      */
813     public static RobustRangingPositionEstimator2D create(
814             final double[] sourceQualityScores, final double[] fingerprintReadingQualityScores,
815             final List<? extends RadioSourceLocated<Point2D>> sources,
816             final RangingFingerprint<? extends RadioSource, ? extends RangingReading<?
817                     extends RadioSource>> fingerprint,
818             final RobustRangingPositionEstimatorListener<Point2D> listener) {
819         return create(sourceQualityScores, fingerprintReadingQualityScores, sources, fingerprint, listener,
820                 DEFAULT_ROBUST_METHOD);
821     }
822 
823     /**
824      * Sets positions, distances and standard deviations of distances on internal
825      * lateration solver.
826      *
827      * @param positions                  positions to be set.
828      * @param distances                  distances to be set.
829      * @param distanceStandardDeviations standard deviations of distances to be set.
830      * @param distanceQualityScores      distance quality scores or null if not
831      *                                   required.
832      */
833     @Override
834     protected void setPositionsDistancesDistanceStandardDeviationsAndQualityScores(
835             final List<Point2D> positions, List<Double> distances, final List<Double> distanceStandardDeviations,
836             final List<Double> distanceQualityScores) {
837         final var size = positions.size();
838         Point2D[] positionsArray = new InhomogeneousPoint2D[size];
839         positionsArray = positions.toArray(positionsArray);
840 
841         final var distancesArray = new double[size];
842         final var distanceStandardDeviationsArray = new double[size];
843 
844         double[] qualityScoresArray = null;
845         if (distanceQualityScores != null) {
846             qualityScoresArray = new double[size];
847         }
848 
849         for (var i = 0; i < size; i++) {
850             distancesArray[i] = distances.get(i);
851             distanceStandardDeviationsArray[i] = distanceStandardDeviations.get(i);
852 
853             if (qualityScoresArray != null) {
854                 qualityScoresArray[i] = distanceQualityScores.get(i);
855             }
856         }
857 
858         try {
859             laterationSolver.setPositionsDistancesAndStandardDeviations(positionsArray, distancesArray,
860                     distanceStandardDeviationsArray);
861 
862             if (qualityScoresArray != null) {
863                 laterationSolver.setQualityScores(qualityScoresArray);
864             }
865         } catch (final LockedException e) {
866             throw new IllegalArgumentException(e);
867         }
868     }
869 }