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