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