1 /*
2 * Copyright (C) 2018 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.radiosource;
17
18 import com.irurueta.geometry.Point3D;
19 import com.irurueta.navigation.LockedException;
20 import com.irurueta.navigation.indoor.*;
21
22 import java.util.List;
23
24 /**
25 * Robustly estimate 3D position, transmitted power and path-loss exponent of a radio
26 * source (e.g. Wi-Fi access point or bluetooth beacon), by discarding
27 * outliers and assuming that the ranging data is available to obtain position with
28 * greater accuracy and that the radio source emits isotropically following the
29 * expression below:
30 * Pr = Pt*Gt*Gr*lambda^2 / (4*pi*d)^2,
31 * where Pr is the received power (expressed in mW),
32 * Gt is the Gain of the transmission antenna
33 * Gr is the Gain of the receiver antenna
34 * d is the distance between emitter and receiver
35 * and lambda is the wavelength and is equal to: lambda = c / f,
36 * where c is the speed of light
37 * and f is the carrier frequency of the radio signal.
38 * <p>
39 * Implementations of this class sequentially estimate position and then remaining
40 * parameters. First ranging data is used to robustly estimate position and then
41 * remaining parameters are robustly estimated using former estimated position as
42 * an initial guess.
43 * <p>
44 * Because usually information about the antenna of the radio source cannot be
45 * retrieved (because many measurements are made on unknown devices where
46 * physical access is not possible), this implementation will estimate the
47 * equivalent transmitted power as: Pte = Pt * Gt * Gr.
48 * If Readings contain RSSI standard deviations, those values will be used,
49 * otherwise it will be assumed an RSSI standard deviation of 1 dB.
50 * <p>
51 * This implementation is like SequentialRobustRangingAndRssiRadioSourceEstimator but
52 * allows mixing different kinds of located radio source readings (ranging, RSSI
53 * and ranging+RSSI).
54 *
55 * @param <S> a {@link RadioSource} type.
56 */
57 public class SequentialRobustMixedRadioSourceEstimator3D<S extends RadioSource> extends
58 SequentialRobustMixedRadioSourceEstimator<S, Point3D> {
59
60 /**
61 * Constructor.
62 */
63 public SequentialRobustMixedRadioSourceEstimator3D() {
64 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
65 }
66
67 /**
68 * Constructor.
69 * Sets signal readings belonging to the same radio source.
70 *
71 * @param readings signal readings belonging to the same radio source.
72 * @throws IllegalArgumentException if readings are not valid.
73 */
74 public SequentialRobustMixedRadioSourceEstimator3D(final List<? extends ReadingLocated<Point3D>> readings) {
75 super(readings);
76 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
77 }
78
79 /**
80 * Constructor.
81 *
82 * @param listener listener in charge of attending events raised by this instance.
83 */
84 public SequentialRobustMixedRadioSourceEstimator3D(
85 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
86 super(listener);
87 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
88 }
89
90 /**
91 * Constructor.
92 * Sets signal readings belonging to the same radio source.
93 *
94 * @param readings signal readings belonging to the same radio source.
95 * @param listener listener in charge of attending events raised by this instance.
96 * @throws IllegalArgumentException if readings are not valid.
97 */
98 public SequentialRobustMixedRadioSourceEstimator3D(
99 final List<? extends ReadingLocated<Point3D>> readings,
100 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
101 super(readings, listener);
102 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
103 }
104
105 /**
106 * Constructor.
107 * Sets signal readings belonging to the same radio source.
108 *
109 * @param readings signal readings belonging to the same radio source.
110 * @param initialPosition initial position to start the estimation of radio
111 * source position.
112 * @throws IllegalArgumentException if readings are not valid.
113 */
114 public SequentialRobustMixedRadioSourceEstimator3D(
115 final List<? extends ReadingLocated<Point3D>> readings, final Point3D initialPosition) {
116 super(readings, initialPosition);
117 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
118 }
119
120 /**
121 * Constructor.
122 *
123 * @param initialPosition initial position to start the estimation of radio
124 * source position.
125 */
126 public SequentialRobustMixedRadioSourceEstimator3D(final Point3D initialPosition) {
127 super(initialPosition);
128 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
129 }
130
131 /**
132 * Constructor.
133 *
134 * @param initialPosition initial position to start the estimation of radio
135 * source position.
136 * @param listener listener in charge of attending events raised by this instance.
137 */
138 public SequentialRobustMixedRadioSourceEstimator3D(
139 final Point3D initialPosition,
140 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
141 super(initialPosition, listener);
142 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
143 }
144
145 /**
146 * Constructor.
147 * Sets signal readings belonging to the same radio source.
148 *
149 * @param readings signal readings belonging to the same radio source.
150 * @param initialPosition initial position to start the estimation of radio
151 * source position.
152 * @param listener listener in charge of attending events raised by this instance.
153 * @throws IllegalArgumentException if readings are not valid.
154 */
155 public SequentialRobustMixedRadioSourceEstimator3D(
156 final List<? extends ReadingLocated<Point3D>> readings, final Point3D initialPosition,
157 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
158 super(readings, initialPosition, listener);
159 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
160 }
161
162 /**
163 * Constructor.
164 *
165 * @param initialTransmittedPowerdBm initial transmitted power to start the
166 * estimation of radio source transmitted power
167 * (expressed in dBm's).
168 */
169 public SequentialRobustMixedRadioSourceEstimator3D(final Double initialTransmittedPowerdBm) {
170 super(initialTransmittedPowerdBm);
171 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
172 }
173
174 /**
175 * Constructor.
176 * Sets signal readings belonging to the same radio source.
177 *
178 * @param readings signal readings belonging to the same radio source.
179 * @param initialTransmittedPowerdBm initial transmitted power to start the
180 * estimation of radio source transmitted power
181 * (expressed in dBm's).
182 * @throws IllegalArgumentException if readings are not valid.
183 */
184 public SequentialRobustMixedRadioSourceEstimator3D(
185 final List<? extends ReadingLocated<Point3D>> readings, final Double initialTransmittedPowerdBm) {
186 super(readings, initialTransmittedPowerdBm);
187 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
188 }
189
190 /**
191 * Constructor.
192 *
193 * @param initialTransmittedPowerdBm initial transmitted power to start the
194 * estimation of radio source transmitted power
195 * (expressed in dBm's).
196 * @param listener listener in charge of attending events raised by this instance.
197 */
198 public SequentialRobustMixedRadioSourceEstimator3D(
199 final Double initialTransmittedPowerdBm,
200 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
201 super(initialTransmittedPowerdBm, listener);
202 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
203 }
204
205 /**
206 * Constructor.
207 * Sets signal readings belonging to the same radio source.
208 *
209 * @param readings signal readings belonging to the same radio source.
210 * @param initialTransmittedPowerdBm initial transmitted power to start the
211 * estimation of radio source transmitted power
212 * (expressed in dBm's).
213 * @param listener listener in charge of attending events raised by this instance.
214 * @throws IllegalArgumentException if readings are not valid.
215 */
216 public SequentialRobustMixedRadioSourceEstimator3D(
217 final List<? extends ReadingLocated<Point3D>> readings, final Double initialTransmittedPowerdBm,
218 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
219 super(readings, initialTransmittedPowerdBm, listener);
220 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
221 }
222
223 /**
224 * Constructor.
225 * Sets signal readings belonging to the same radio source.
226 *
227 * @param readings signal readings belonging to the same radio source.
228 * @param initialPosition initial position to start the estimation of radio
229 * source position.
230 * @param initialTransmittedPowerdBm initial transmitted power to start the
231 * estimation of radio source transmitted power
232 * (expressed in dBm's).
233 * @throws IllegalArgumentException if readings are not valid.
234 */
235 public SequentialRobustMixedRadioSourceEstimator3D(
236 final List<? extends ReadingLocated<Point3D>> readings, final Point3D initialPosition,
237 final Double initialTransmittedPowerdBm) {
238 super(readings, initialPosition, initialTransmittedPowerdBm);
239 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
240 }
241
242 /**
243 * Constructor.
244 *
245 * @param initialPosition initial position to start the estimation of radio
246 * source position.
247 * @param initialTransmittedPowerdBm initial transmitted power to start the
248 * estimation of radio source transmitted power
249 * (expressed in dBm's).
250 */
251 public SequentialRobustMixedRadioSourceEstimator3D(
252 final Point3D initialPosition, final Double initialTransmittedPowerdBm) {
253 super(initialPosition, initialTransmittedPowerdBm);
254 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
255 }
256
257 /**
258 * Constructor.
259 *
260 * @param initialPosition initial position to start the estimation of radio
261 * source position.
262 * @param initialTransmittedPowerdBm initial transmitted power to start the
263 * estimation of radio source transmitted power
264 * (expressed in dBm's).
265 * @param listener in charge of attending events raised by this instance.
266 */
267 public SequentialRobustMixedRadioSourceEstimator3D(
268 final Point3D initialPosition, final Double initialTransmittedPowerdBm,
269 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
270 super(initialPosition, initialTransmittedPowerdBm, listener);
271 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
272 }
273
274 /**
275 * Constructor.
276 * Sets signal readings belonging to the same radio source.
277 *
278 * @param readings signal readings belonging to the same radio source.
279 * @param initialPosition initial position to start the estimation of radio
280 * source position.
281 * @param initialTransmittedPowerdBm initial transmitted power to start the
282 * estimation of radio source transmitted power
283 * (expressed in dBm's).
284 * @param listener listener in charge of attending events raised by this instance.
285 * @throws IllegalArgumentException if readings are not valid.
286 */
287 public SequentialRobustMixedRadioSourceEstimator3D(
288 final List<? extends ReadingLocated<Point3D>> readings, final Point3D initialPosition,
289 final Double initialTransmittedPowerdBm,
290 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
291 super(readings, initialPosition, initialTransmittedPowerdBm, listener);
292 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
293 }
294
295 /**
296 * Constructor.
297 * Sets signal readings belonging to the same radio source.
298 *
299 * @param readings signal readings belonging to the same radio source.
300 * @param initialPosition initial position to start the estimation of radio
301 * source position.
302 * @param initialTransmittedPowerdBm initial transmitted power to start the
303 * estimation of radio source transmitted power
304 * (expressed in dBm's).
305 * @param initialPathLossExponent initial path loss exponent. A typical value is 2.0.
306 * @throws IllegalArgumentException if readings are not valid.
307 */
308 public SequentialRobustMixedRadioSourceEstimator3D(
309 final List<? extends ReadingLocated<Point3D>> readings, final Point3D initialPosition,
310 final Double initialTransmittedPowerdBm, final double initialPathLossExponent) {
311 super(readings, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent);
312 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
313 }
314
315 /**
316 * Constructor.
317 *
318 * @param initialPosition initial position to start the estimation of radio
319 * source position.
320 * @param initialTransmittedPowerdBm initial transmitted power to start the
321 * estimation of radio source transmitted power
322 * (expressed in dBm's).
323 * @param initialPathLossExponent initial path loss exponent. A typical value is 2.0.
324 */
325 public SequentialRobustMixedRadioSourceEstimator3D(
326 final Point3D initialPosition, final Double initialTransmittedPowerdBm,
327 final double initialPathLossExponent) {
328 super(initialPosition, initialTransmittedPowerdBm, initialPathLossExponent);
329 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
330 }
331
332 /**
333 * Constructor.
334 *
335 * @param initialPosition initial position to start the estimation of radio
336 * source position.
337 * @param initialTransmittedPowerdBm initial transmitted power to start the
338 * estimation of radio source transmitted power
339 * (expressed in dBm's).
340 * @param initialPathLossExponent initial path loss exponent. A typical value is 2.0.
341 * @param listener listener in charge of attending events raised by this instance.
342 */
343 public SequentialRobustMixedRadioSourceEstimator3D(
344 final Point3D initialPosition, final Double initialTransmittedPowerdBm,
345 final double initialPathLossExponent,
346 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
347 super(initialPosition, initialTransmittedPowerdBm, initialPathLossExponent, listener);
348 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
349 }
350
351 /**
352 * Constructors.
353 * Sets signal readings belonging to the same radio source.
354 *
355 * @param readings signal readings belonging to the same radio source.
356 * @param initialPosition initial position to start the estimation of radio
357 * source position.
358 * @param initialTransmittedPowerdBm initial transmitted power to start the
359 * estimation of radio source transmitted power
360 * (expressed in dBm's).
361 * @param initialPathLossExponent initial path loss exponent. A typical value is 2.0.
362 * @param listener listener in charge of attending events raised by this instance.
363 * @throws IllegalArgumentException if readings are not valid.
364 */
365 public SequentialRobustMixedRadioSourceEstimator3D(
366 final List<? extends ReadingLocated<Point3D>> readings, final Point3D initialPosition,
367 final Double initialTransmittedPowerdBm, final double initialPathLossExponent,
368 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
369 super(readings, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent, listener);
370 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
371 }
372
373 /**
374 * Constructor.
375 *
376 * @param qualityScores quality scores corresponding to each provided sample.
377 * The larger the score value the better the quality of
378 * the sample.
379 * @throws IllegalArgumentException if quality scores is null, or length of
380 * quality scores is less than required minimum.
381 */
382 public SequentialRobustMixedRadioSourceEstimator3D(final double[] qualityScores) {
383 super(qualityScores);
384 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
385 }
386
387 /**
388 * Constructor.
389 * Sets signal readings belonging to the same radio source.
390 *
391 * @param qualityScores quality scores corresponding to each provided sample.
392 * The larger the score value the better the quality of
393 * the sample.
394 * @param readings signal readings belonging to the same radio source.
395 * @throws IllegalArgumentException if readings are not valid, quality scores is
396 * null, or length of quality scores is less than required minimum.
397 */
398 public SequentialRobustMixedRadioSourceEstimator3D(
399 final double[] qualityScores, final List<? extends ReadingLocated<Point3D>> readings) {
400 super(qualityScores, readings);
401 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
402 }
403
404 /**
405 * Constructor.
406 *
407 * @param qualityScores quality scores corresponding to each provided sample.
408 * The larger the score value the better the quality of
409 * the sample.
410 * @param listener listener in charge of attending events raised by this instance.
411 * @throws IllegalArgumentException if quality scores is null, or length
412 * of quality scores is less than required minimum.
413 */
414 public SequentialRobustMixedRadioSourceEstimator3D(
415 final double[] qualityScores,
416 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
417 super(qualityScores, listener);
418 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
419 }
420
421 /**
422 * Constructor.
423 * Sets signal readings belonging to the same radio source.
424 *
425 * @param qualityScores quality scores corresponding to each provided sample.
426 * The larger the score value the better the quality of
427 * the sample.
428 * @param readings signal readings belonging to the same radio source.
429 * @param listener listener in charge of attending events raised by this instance.
430 * @throws IllegalArgumentException if readings are not valid, quality scores is
431 * null, or length of quality scores is less than required minimum.
432 */
433 public SequentialRobustMixedRadioSourceEstimator3D(
434 final double[] qualityScores, final List<? extends ReadingLocated<Point3D>> readings,
435 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
436 super(qualityScores, readings, listener);
437 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
438 }
439
440 /**
441 * Constructor.
442 * Sets signal readings belonging to the same radio source.
443 *
444 * @param qualityScores quality scores corresponding to each provided sample.
445 * The larger the score value the better the quality of
446 * the sample.
447 * @param readings signal readings belonging to the same radio source.
448 * @param initialPosition initial position to start the estimation of radio
449 * source position.
450 * @throws IllegalArgumentException if readings are not valid, quality scores is
451 * null, or length of quality scores is less than required minimum.
452 */
453 public SequentialRobustMixedRadioSourceEstimator3D(
454 final double[] qualityScores, final List<? extends ReadingLocated<Point3D>> readings,
455 final Point3D initialPosition) {
456 super(qualityScores, readings, initialPosition);
457 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
458 }
459
460 /**
461 * Constructor.
462 *
463 * @param qualityScores quality scores corresponding to each provided sample.
464 * The larger the score value the better the quality of
465 * the sample.
466 * @param initialPosition initial position to start the estimation of radio
467 * source position.
468 * @throws IllegalArgumentException if quality scores is null, or length
469 * of quality scores is less than required minimum.
470 */
471 public SequentialRobustMixedRadioSourceEstimator3D(final double[] qualityScores, final Point3D initialPosition) {
472 super(qualityScores, initialPosition);
473 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
474 }
475
476 /**
477 * Constructor.
478 *
479 * @param qualityScores quality scores corresponding to each provided sample.
480 * The larger the score value the better the quality of
481 * the sample.
482 * @param initialPosition initial position to start the estimation of radio
483 * source position.
484 * @param listener listener in charge of attending events raised by this instance.
485 * @throws IllegalArgumentException if quality scores is null, or length
486 * of quality scores is less than required minimum.
487 */
488 public SequentialRobustMixedRadioSourceEstimator3D(
489 final double[] qualityScores, final Point3D initialPosition,
490 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
491 super(qualityScores, initialPosition, listener);
492 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
493 }
494
495 /**
496 * Constructor.
497 * Sets signal readings belonging to the same radio source.
498 *
499 * @param qualityScores quality scores corresponding to each provided sample.
500 * The larger the score value the better the quality of
501 * the sample.
502 * @param readings signal readings belonging to the same radio source.
503 * @param initialPosition initial position to start the estimation of radio
504 * source position.
505 * @param listener listener in charge of attending events raised by this instance.
506 * @throws IllegalArgumentException if readings are not valid, quality scores
507 * is null, or length of quality scores is less than required minimum.
508 */
509 public SequentialRobustMixedRadioSourceEstimator3D(
510 final double[] qualityScores, final List<? extends ReadingLocated<Point3D>> readings,
511 final Point3D initialPosition,
512 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
513 super(qualityScores, readings, initialPosition, listener);
514 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
515 }
516
517 /**
518 * Constructor.
519 *
520 * @param qualityScores quality scores corresponding to each provided sample.
521 * The larger the score value the better the quality of
522 * the sample.
523 * @param initialTransmittedPowerdBm initial transmitted power to start the
524 * estimation of radio source transmitted power
525 * (expressed in dBm's).
526 * @throws IllegalArgumentException if quality scores is null, or length
527 * of quality scores is less than required minimum.
528 */
529 public SequentialRobustMixedRadioSourceEstimator3D(
530 final double[] qualityScores, final Double initialTransmittedPowerdBm) {
531 super(qualityScores, initialTransmittedPowerdBm);
532 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
533 }
534
535 /**
536 * Constructor.
537 * Sets signal readings belonging to the same radio source.
538 *
539 * @param qualityScores quality scores corresponding to each provided sample.
540 * The larger the score value the better the quality of
541 * the sample.
542 * @param readings signal readings belonging to the same radio source.
543 * @param initialTransmittedPowerdBm initial transmitted power to start the
544 * estimation of radio source transmitted power
545 * (expressed in dBm's).
546 * @throws IllegalArgumentException if readings are not valid, quality scores
547 * is null, or length of quality scores is less than required minimum.
548 */
549 public SequentialRobustMixedRadioSourceEstimator3D(
550 final double[] qualityScores, final List<? extends ReadingLocated<Point3D>> readings,
551 final Double initialTransmittedPowerdBm) {
552 super(qualityScores, readings, initialTransmittedPowerdBm);
553 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
554 }
555
556 /**
557 * Constructor.
558 *
559 * @param qualityScores quality scores corresponding to each provided sample.
560 * The larger the score value the better the quality of
561 * the sample.
562 * @param initialTransmittedPowerdBm initial transmitted power to start the
563 * estimation of radio source transmitted power
564 * (expressed in dBm's).
565 * @param listener listener in charge of attending events raised by this instance.
566 * @throws IllegalArgumentException if quality scores is null, or length
567 * of quality scores is less than required minimum.
568 */
569 public SequentialRobustMixedRadioSourceEstimator3D(
570 final double[] qualityScores, final Double initialTransmittedPowerdBm,
571 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
572 super(qualityScores, initialTransmittedPowerdBm, listener);
573 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
574 }
575
576 /**
577 * Constructor.
578 * Sets signal readings belonging to the same radio source.
579 *
580 * @param qualityScores quality scores corresponding to each provided
581 * sample. The larger the score value the better
582 * the quality of the sample.
583 * @param readings signal readings belonging to the same radio source.
584 * @param initialTransmittedPowerdBm initial transmitted power to start the
585 * estimation of radio source transmitted power
586 * (expressed in dBm's).
587 * @param listener listener in charge of attending events raised by this instance.
588 * @throws IllegalArgumentException if readings are not valid, quality scores
589 * is null, or length of quality scores is less than required minimum.
590 */
591 public SequentialRobustMixedRadioSourceEstimator3D(
592 final double[] qualityScores, final List<? extends ReadingLocated<Point3D>> readings,
593 final Double initialTransmittedPowerdBm,
594 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
595 super(qualityScores, readings, initialTransmittedPowerdBm, listener);
596 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
597 }
598
599 /**
600 * Constructor.
601 * Sets signal readings belonging to the same radio source.
602 *
603 * @param qualityScores quality scores corresponding to each provided
604 * sample. The larger the score value the better
605 * the quality of the sample.
606 * @param readings signal readings belonging to the same radio source.
607 * @param initialPosition initial position to start the estimation of radio
608 * source position.
609 * @param initialTransmittedPowerdBm initial transmitted power to start the
610 * estimation of radio source transmitted power
611 * (expressed in dBm's).
612 * @throws IllegalArgumentException if readings are not valid, quality scores
613 * is null, or length of quality scores is less than required minimum.
614 */
615 public SequentialRobustMixedRadioSourceEstimator3D(
616 final double[] qualityScores, final List<? extends ReadingLocated<Point3D>> readings,
617 final Point3D initialPosition, final Double initialTransmittedPowerdBm) {
618 super(qualityScores, readings, initialPosition, initialTransmittedPowerdBm);
619 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
620 }
621
622 /**
623 * Constructor.
624 *
625 * @param qualityScores quality scores corresponding to each provided
626 * sample. The larger the score value the better
627 * the quality of the sample.
628 * @param initialPosition initial position to start the estimation of radio
629 * source position.
630 * @param initialTransmittedPowerdBm initial transmitted power to start the
631 * estimation of radio source transmitted power
632 * (expressed in dBm's).
633 * @throws IllegalArgumentException if quality scores is null, or length
634 * of quality scores is less than required minimum.
635 */
636 public SequentialRobustMixedRadioSourceEstimator3D(
637 final double[] qualityScores, final Point3D initialPosition, final Double initialTransmittedPowerdBm) {
638 super(qualityScores, initialPosition, initialTransmittedPowerdBm);
639 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
640 }
641
642 /**
643 * Constructor.
644 *
645 * @param qualityScores quality scores corresponding to each provided
646 * sample. The larger the score value the better
647 * the quality of the sample.
648 * @param initialPosition initial position to start the estimation of radio
649 * source position.
650 * @param initialTransmittedPowerdBm initial transmitted power to start the
651 * estimation of radio source transmitted power
652 * (expressed in dBm's).
653 * @param listener in charge of attending events raised by this instance.
654 * @throws IllegalArgumentException if quality scores is null, or length
655 * of quality scores is less than required minimum.
656 */
657 public SequentialRobustMixedRadioSourceEstimator3D(
658 final double[] qualityScores, final Point3D initialPosition, final Double initialTransmittedPowerdBm,
659 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
660 super(qualityScores, initialPosition, initialTransmittedPowerdBm, listener);
661 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
662 }
663
664 /**
665 * Constructor.
666 * Sets signal readings belonging to the same radio source.
667 *
668 * @param qualityScores quality scores corresponding to each provided
669 * sample. The larger the score value the better
670 * the quality of the sample.
671 * @param readings signal readings belonging to the same radio source.
672 * @param initialPosition initial position to start the estimation of radio
673 * source position.
674 * @param initialTransmittedPowerdBm initial transmitted power to start the
675 * estimation of radio source transmitted power
676 * (expressed in dBm's).
677 * @param listener listener in charge of attending events raised by this instance.
678 * @throws IllegalArgumentException if readings are not valid, quality scores
679 * is null, or length of quality scores is less than required minimum.
680 */
681 public SequentialRobustMixedRadioSourceEstimator3D(
682 final double[] qualityScores, final List<? extends ReadingLocated<Point3D>> readings,
683 final Point3D initialPosition, final Double initialTransmittedPowerdBm,
684 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
685 super(qualityScores, readings, initialPosition, initialTransmittedPowerdBm, listener);
686 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
687 }
688
689 /**
690 * Constructor.
691 * Sets signal readings belonging to the same radio source.
692 *
693 * @param qualityScores quality scores corresponding to each provided
694 * sample. The larger the score value the better
695 * the quality of the sample.
696 * @param readings signal readings belonging to the same radio source.
697 * @param initialPosition initial position to start the estimation of radio
698 * source position.
699 * @param initialTransmittedPowerdBm initial transmitted power to start the
700 * estimation of radio source transmitted power
701 * (expressed in dBm's).
702 * @param initialPathLossExponent initial path loss exponent. A typical value is 2.0.
703 * @throws IllegalArgumentException if readings are not valid, quality scores
704 * is null, or length of quality scores is less than required minimum.
705 */
706 public SequentialRobustMixedRadioSourceEstimator3D(
707 final double[] qualityScores, final List<? extends ReadingLocated<Point3D>> readings,
708 final Point3D initialPosition, final Double initialTransmittedPowerdBm,
709 final double initialPathLossExponent) {
710 super(qualityScores, readings, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent);
711 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
712 }
713
714 /**
715 * Constructor.
716 *
717 * @param qualityScores quality scores corresponding to each provided
718 * sample. The larger the score value the better
719 * the quality of the sample.
720 * @param initialPosition initial position to start the estimation of radio
721 * source position.
722 * @param initialTransmittedPowerdBm initial transmitted power to start the
723 * estimation of radio source transmitted power
724 * (expressed in dBm's).
725 * @param initialPathLossExponent initial path loss exponent. A typical value is 2.0.
726 * @throws IllegalArgumentException if quality scores is null, or length
727 * of quality scores is less than required minimum.
728 */
729 public SequentialRobustMixedRadioSourceEstimator3D(
730 final double[] qualityScores, final Point3D initialPosition, final Double initialTransmittedPowerdBm,
731 final double initialPathLossExponent) {
732 super(qualityScores, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent);
733 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
734 }
735
736 /**
737 * Constructor.
738 *
739 * @param qualityScores quality scores corresponding to each provided
740 * sample. The larger the score value the better
741 * the quality of the sample.
742 * @param initialPosition initial position to start the estimation of radio
743 * source position.
744 * @param initialTransmittedPowerdBm initial transmitted power to start the
745 * estimation of radio source transmitted power
746 * (expressed in dBm's).
747 * @param initialPathLossExponent initial path loss exponent. A typical value is 2.0.
748 * @param listener listener in charge of attending events raised by this instance.
749 * @throws IllegalArgumentException if quality scores is null, or length
750 * of quality scores is less than required minimum.
751 */
752 public SequentialRobustMixedRadioSourceEstimator3D(
753 final double[] qualityScores, final Point3D initialPosition, final Double initialTransmittedPowerdBm,
754 final double initialPathLossExponent,
755 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
756 super(qualityScores, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent, listener);
757 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
758 }
759
760 /**
761 * Constructors.
762 * Sets signal readings belonging to the same radio source.
763 *
764 * @param qualityScores quality scores corresponding to each provided
765 * sample. The larger the score value the better
766 * the quality of the sample.
767 * @param readings signal readings belonging to the same radio source.
768 * @param initialPosition initial position to start the estimation of radio
769 * source position.
770 * @param initialTransmittedPowerdBm initial transmitted power to start the
771 * estimation of radio source transmitted power
772 * (expressed in dBm's).
773 * @param initialPathLossExponent initial path loss exponent. A typical value is 2.0.
774 * @param listener listener in charge of attending events raised by this instance.
775 * @throws IllegalArgumentException if readings are not valid, quality scores
776 * is null, or length of quality scores is less than required minimum.
777 */
778 public SequentialRobustMixedRadioSourceEstimator3D(
779 final double[] qualityScores, final List<? extends ReadingLocated<Point3D>> readings,
780 final Point3D initialPosition, final Double initialTransmittedPowerdBm,
781 final double initialPathLossExponent,
782 final SequentialRobustMixedRadioSourceEstimatorListener<S, Point3D> listener) {
783 super(qualityScores, readings, initialPosition, initialTransmittedPowerdBm, initialPathLossExponent, listener);
784 rangingPreliminarySubsetSize = rssiPreliminarySubsetSize = getMinReadings();
785 }
786
787 /**
788 * Gets minimum required number of readings to estimate
789 * power, position and path-loss exponent.
790 * This value depends on the number of parameters to
791 * be estimated, but for position only, this is 3
792 * readings.
793 *
794 * @return minimum required number of readings.
795 */
796 @Override
797 public int getMinReadings() {
798 var minReadings = Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH;
799 if (isTransmittedPowerEstimationEnabled()) {
800 minReadings++;
801 }
802 if (isPathLossEstimationEnabled()) {
803 minReadings++;
804 }
805 return ++minReadings;
806 }
807
808 /**
809 * Gets number of dimensions of position points.
810 *
811 * @return always returns 2 dimensions.
812 */
813 @Override
814 public int getNumberOfDimensions() {
815 return Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH;
816 }
817
818 /**
819 * Gets estimated located radio source with estimated transmitted power.
820 *
821 * @return estimated located radio source with estimated transmitted power or null.
822 */
823 @Override
824 @SuppressWarnings({"unchecked", "DuplicatedCode"})
825 public RadioSourceLocated<Point3D> getEstimatedRadioSource() {
826 final var readings = getReadings();
827 if (readings == null || readings.isEmpty()) {
828 return null;
829 }
830
831 final S source;
832 final var reading = readings.get(0);
833 if (reading instanceof RangingReadingLocated) {
834 source = ((RangingReadingLocated<S, Point3D>) reading).getSource();
835 } else if (reading instanceof RssiReadingLocated) {
836 source = ((RssiReadingLocated<S, Point3D>) reading).getSource();
837 } else if (reading instanceof RangingAndRssiReadingLocated) {
838 source = ((RangingAndRssiReadingLocated<S, Point3D>) reading).getSource();
839 } else {
840 return null;
841 }
842
843 final var estimatedPosition = getEstimatedPosition();
844 if (estimatedPosition == null) {
845 return null;
846 }
847
848 final var estimatedPositionCovariance = getEstimatedPositionCovariance();
849
850 final var transmittedPowerdBm = getEstimatedTransmittedPowerdBm();
851
852 final var transmittedPowerVariance = getEstimatedTransmittedPowerVariance();
853 final var transmittedPowerStandardDeviation = transmittedPowerVariance != null
854 ? Math.sqrt(transmittedPowerVariance) : null;
855
856 final var pathlossExponentVariance = getEstimatedPathLossExponentVariance();
857 final var pathlossExponentStandardDeviation = pathlossExponentVariance != null
858 ? Math.sqrt(pathlossExponentVariance) : null;
859
860 if (source instanceof WifiAccessPoint accessPoint) {
861 if (transmittedPowerdBm != null) {
862 return new WifiAccessPointWithPowerAndLocated3D(accessPoint.getBssid(), source.getFrequency(),
863 accessPoint.getSsid(), transmittedPowerdBm, transmittedPowerStandardDeviation,
864 getEstimatedPathLossExponent(), pathlossExponentStandardDeviation, estimatedPosition,
865 estimatedPositionCovariance);
866 } else {
867 return new WifiAccessPointLocated3D(accessPoint.getBssid(), source.getFrequency(),
868 accessPoint.getSsid(), estimatedPosition, estimatedPositionCovariance);
869 }
870 } else if (source instanceof Beacon beacon) {
871 return new BeaconWithPowerAndLocated3D(beacon.getIdentifiers(), beacon.getTransmittedPower(),
872 beacon.getFrequency(), beacon.getBluetoothAddress(), beacon.getBeaconTypeCode(),
873 beacon.getManufacturer(), beacon.getServiceUuid(), beacon.getBluetoothName(),
874 getEstimatedPathLossExponent(), transmittedPowerStandardDeviation,
875 pathlossExponentStandardDeviation, estimatedPosition, estimatedPositionCovariance);
876 } else {
877 return null;
878 }
879 }
880
881 /**
882 * Builds ranging estimator.
883 */
884 @Override
885 protected void buildRangingEstimatorIfNeeded() {
886 if (rangingEstimator == null || rangingEstimator.getMethod() != rangingRobustMethod) {
887 rangingEstimator = RobustRangingRadioSourceEstimator3D.create(rangingRobustMethod);
888 }
889 }
890
891 /**
892 * Build RSSI estimator.
893 *
894 * @throws LockedException if estimator is locked.
895 */
896 @Override
897 protected void buildRssiEstimatorIfNeeded() throws LockedException {
898 if (rssiEstimator == null || rssiEstimator.getMethod() != rssiRobustMethod) {
899 rssiEstimator = RobustRssiRadioSourceEstimator3D.create(rssiRobustMethod);
900
901 // rssi estimator will never need position estimator, but to
902 // ensure it is ready we need to provide an initial position
903 rssiEstimator.setPositionEstimationEnabled(false);
904 rssiEstimator.setInitialPosition(Point3D.create());
905 }
906 }
907 }