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