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