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