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