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 }