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.fingerprint;
17
18 import com.irurueta.geometry.InhomogeneousPoint3D;
19 import com.irurueta.geometry.Point3D;
20 import com.irurueta.navigation.indoor.RadioSource;
21 import com.irurueta.navigation.indoor.RadioSourceLocated;
22 import com.irurueta.navigation.indoor.RssiFingerprint;
23 import com.irurueta.navigation.indoor.RssiFingerprintLocated;
24 import com.irurueta.navigation.indoor.RssiReading;
25
26 import java.util.List;
27
28 /**
29 * 3D position estimator based on located fingerprints containing only RSSI readings and
30 * having as well prior knowledge of the location of radio sources associated to those
31 * readings.
32 * This is a base implementation for all implementations using different orders of
33 * Taylor approximation to estimate position.
34 */
35 @SuppressWarnings("DuplicatedCode")
36 public abstract class NonLinearFingerprintPositionEstimator3D extends NonLinearFingerprintPositionEstimator<Point3D> {
37
38 /**
39 * Constructor.
40 */
41 protected NonLinearFingerprintPositionEstimator3D() {
42 }
43
44 /**
45 * Constructor.
46 *
47 * @param listener listener in charge of handling events.
48 */
49 protected NonLinearFingerprintPositionEstimator3D(final FingerprintPositionEstimatorListener<Point3D> listener) {
50 super(listener);
51 }
52
53 /**
54 * Constructor.
55 *
56 * @param locatedFingerprints located fingerprints containing RSSI readings.
57 * @param fingerprint fingerprint containing readings at an unknown location
58 * for provided located fingerprints.
59 * @param sources located radio sources.
60 * @throws IllegalArgumentException if provided non located fingerprint is null,
61 * located fingerprints value is null or there are not enough fingerprints or
62 * readings within provided fingerprints (for 3D position estimation 3 located
63 * total readings are required among all fingerprints).
64 */
65 protected NonLinearFingerprintPositionEstimator3D(
66 final List<? extends RssiFingerprintLocated<? extends RadioSource,
67 ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
68 final RssiFingerprint<? extends RadioSource,
69 ? extends RssiReading<? extends RadioSource>> fingerprint,
70 final List<? extends RadioSourceLocated<Point3D>> sources) {
71 super(locatedFingerprints, fingerprint, sources);
72 }
73
74 /**
75 * Constructor.
76 *
77 * @param locatedFingerprints located fingerprints containing RSSI readings.
78 * @param fingerprint fingerprint containing readings at an unknown location
79 * for provided located fingerprints.
80 * @param sources located radio sources.
81 * @param listener listener in charge of handling events.
82 * @throws IllegalArgumentException if provided non located fingerprint is null,
83 * located fingerprints value is null or there are not enough fingerprints or
84 * readings within provided fingerprints (for 3D position estimation 3 located
85 * total readings are required among all fingerprints).
86 */
87 protected NonLinearFingerprintPositionEstimator3D(
88 final List<? extends RssiFingerprintLocated<? extends RadioSource,
89 ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
90 final RssiFingerprint<? extends RadioSource,
91 ? extends RssiReading<? extends RadioSource>> fingerprint,
92 final List<? extends RadioSourceLocated<Point3D>> sources,
93 final FingerprintPositionEstimatorListener<Point3D> listener) {
94 super(locatedFingerprints, fingerprint, sources, listener);
95 }
96
97 /**
98 * Constructor.
99 *
100 * @param locatedFingerprints located fingerprints containing RSSI readings.
101 * @param fingerprint fingerprint containing readings at an unknown location
102 * for provided located fingerprints.
103 * @param sources located radio sources.
104 * @param initialPosition initial position to start the solving algorithm or null.
105 * @throws IllegalArgumentException if provided non located fingerprint is null,
106 * located fingerprints value is null or there are not enough fingerprints or
107 * readings within provided fingerprints (for 3D position estimation 3 located
108 * total readings are required among all fingerprints).
109 */
110 protected NonLinearFingerprintPositionEstimator3D(
111 final List<? extends RssiFingerprintLocated<? extends RadioSource,
112 ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
113 final RssiFingerprint<? extends RadioSource,
114 ? extends RssiReading<? extends RadioSource>> fingerprint,
115 final List<? extends RadioSourceLocated<Point3D>> sources, Point3D initialPosition) {
116 super(locatedFingerprints, fingerprint, sources, initialPosition);
117 }
118
119 /**
120 * Constructor.
121 *
122 * @param locatedFingerprints located fingerprints containing RSSI readings.
123 * @param fingerprint fingerprint containing readings at an unknown location
124 * for provided located fingerprints.
125 * @param sources located radio sources.
126 * @param initialPosition initial position to start the solving algorithm or null.
127 * @param listener listener in charge of handling events.
128 * @throws IllegalArgumentException if provided non located fingerprint is null,
129 * located fingerprints value is null or there are not enough fingerprints or
130 * readings within provided fingerprints (for 2D position estimation at least 2
131 * located total readings are required among all fingerprints, for example 2
132 * readings are required in a single fingerprint, or at least 2 fingerprints at
133 * different locations containing a single reading are required. For 3D position
134 * estimation 3 located total readings are required among all fingerprints).
135 */
136 protected NonLinearFingerprintPositionEstimator3D(
137 final List<? extends RssiFingerprintLocated<
138 ? extends RadioSource, ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
139 final RssiFingerprint<? extends RadioSource,
140 ? extends RssiReading<? extends RadioSource>> fingerprint,
141 final List<? extends RadioSourceLocated<Point3D>> sources, Point3D initialPosition,
142 final FingerprintPositionEstimatorListener<Point3D> listener) {
143 super(locatedFingerprints, fingerprint, sources, initialPosition, listener);
144 }
145
146 /**
147 * Gets number of dimensions of points.
148 *
149 * @return number of dimensions of points.
150 */
151 @Override
152 public int getNumberOfDimensions() {
153 return Point3D.POINT3D_INHOMOGENEOUS_COORDINATES_LENGTH;
154 }
155
156 /**
157 * Gets estimated position or null if not available yet.
158 *
159 * @return estimated position or null.
160 */
161 @Override
162 public Point3D getEstimatedPosition() {
163 if (estimatedPositionCoordinates == null) {
164 return null;
165 }
166
167 final var result = new InhomogeneousPoint3D();
168 getEstimatedPosition(result);
169 return result;
170 }
171
172 /**
173 * Creates an instance of a non-linear 3D position estimator using provided type.
174 *
175 * @param type type to be used.
176 * @return a non-linear 3D position estimator.
177 */
178 public static NonLinearFingerprintPositionEstimator3D create(final NonLinearFingerprintPositionEstimatorType type) {
179 return switch (type) {
180 case THIRD_ORDER -> new ThirdOrderNonLinearFingerprintPositionEstimator3D();
181 case SECOND_ORDER -> new SecondOrderNonLinearFingerprintPositionEstimator3D();
182 default -> new FirstOrderNonLinearFingerprintPositionEstimator3D();
183 };
184 }
185
186 /**
187 * Creates an instance of a non-linear 3D position estimator using provided type.
188 *
189 * @param listener listener in charge of handling events.
190 * @param type a non-linear 3D position estimator.
191 * @return a non-linear 3D position estimator.
192 */
193 public static NonLinearFingerprintPositionEstimator3D create(
194 final FingerprintPositionEstimatorListener<Point3D> listener,
195 final NonLinearFingerprintPositionEstimatorType type) {
196 return switch (type) {
197 case THIRD_ORDER -> new ThirdOrderNonLinearFingerprintPositionEstimator3D(listener);
198 case SECOND_ORDER -> new SecondOrderNonLinearFingerprintPositionEstimator3D(listener);
199 default -> new FirstOrderNonLinearFingerprintPositionEstimator3D(listener);
200 };
201 }
202
203 /**
204 * Creates an instance of a non-linear 3D position estimator using provided type.
205 *
206 * @param locatedFingerprints located fingerprints containing RSSI readings.
207 * @param fingerprint fingerprint containing readings at an unknown location
208 * for provided located fingerprints.
209 * @param sources located radio sources.
210 * @param type a non-linear 3D position estimator.
211 * @return a non-linear 3D position estimator.
212 * @throws IllegalArgumentException if provided non located fingerprint is null,
213 * located fingerprints value is null or there are not enough fingerprints or
214 * readings within provided fingerprints (for 3D position estimation 3 located
215 * total readings are required among all fingerprints).
216 */
217 public static NonLinearFingerprintPositionEstimator3D create(
218 final List<? extends RssiFingerprintLocated<? extends RadioSource,
219 ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
220 final RssiFingerprint<? extends RadioSource,
221 ? extends RssiReading<? extends RadioSource>> fingerprint,
222 final List<? extends RadioSourceLocated<Point3D>> sources,
223 final NonLinearFingerprintPositionEstimatorType type) {
224 return switch (type) {
225 case THIRD_ORDER -> new ThirdOrderNonLinearFingerprintPositionEstimator3D(
226 locatedFingerprints, fingerprint, sources);
227 case SECOND_ORDER -> new SecondOrderNonLinearFingerprintPositionEstimator3D(
228 locatedFingerprints, fingerprint, sources);
229 default -> new FirstOrderNonLinearFingerprintPositionEstimator3D(
230 locatedFingerprints, fingerprint, sources);
231 };
232 }
233
234 /**
235 * Creates an instance of a non-linear 3D position estimator using provided type.
236 *
237 * @param locatedFingerprints located fingerprints containing RSSI readings.
238 * @param fingerprint fingerprint containing readings at an unknown location
239 * for provided located fingerprints.
240 * @param sources located radio sources.
241 * @param listener listener in charge of handling events.
242 * @param type a non-linear 3D position estimator.
243 * @return a non-linear 3D position estimator.
244 * @throws IllegalArgumentException if provided non located fingerprint is null,
245 * located fingerprints value is null or there are not enough fingerprints or
246 * readings within provided fingerprints (for 3D position estimation 3 located
247 * total readings are required among all fingerprints).
248 */
249 public static NonLinearFingerprintPositionEstimator3D create(
250 final List<? extends RssiFingerprintLocated<? extends RadioSource,
251 ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
252 final RssiFingerprint<? extends RadioSource,
253 ? extends RssiReading<? extends RadioSource>> fingerprint,
254 final List<? extends RadioSourceLocated<Point3D>> sources,
255 final FingerprintPositionEstimatorListener<Point3D> listener,
256 final NonLinearFingerprintPositionEstimatorType type) {
257 return switch (type) {
258 case THIRD_ORDER -> new ThirdOrderNonLinearFingerprintPositionEstimator3D(
259 locatedFingerprints, fingerprint, sources, listener);
260 case SECOND_ORDER -> new SecondOrderNonLinearFingerprintPositionEstimator3D(
261 locatedFingerprints, fingerprint, sources, listener);
262 default -> new FirstOrderNonLinearFingerprintPositionEstimator3D(
263 locatedFingerprints, fingerprint, sources, listener);
264 };
265 }
266
267 /**
268 * Creates an instance of a non-linear 3D position estimator using provided type.
269 *
270 * @param locatedFingerprints located fingerprints containing RSSI readings.
271 * @param fingerprint fingerprint containing readings at an unknown location
272 * for provided located fingerprints.
273 * @param sources located radio sources.
274 * @param initialPosition initial position to start the solving algorithm or null.
275 * @param type a non-linear 3D position estimator.
276 * @return a non-linear 3D position estimator.
277 * @throws IllegalArgumentException if provided non located fingerprint is null,
278 * located fingerprints value is null or there are not enough fingerprints or
279 * readings within provided fingerprints (for 3D position estimation 3 located
280 * total readings are required among all fingerprints).
281 */
282 public static NonLinearFingerprintPositionEstimator3D create(
283 final List<? extends RssiFingerprintLocated<? extends RadioSource,
284 ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
285 final RssiFingerprint<? extends RadioSource,
286 ? extends RssiReading<? extends RadioSource>> fingerprint,
287 final List<? extends RadioSourceLocated<Point3D>> sources,
288 final Point3D initialPosition, NonLinearFingerprintPositionEstimatorType type) {
289 return switch (type) {
290 case THIRD_ORDER -> new ThirdOrderNonLinearFingerprintPositionEstimator3D(
291 locatedFingerprints, fingerprint, sources, initialPosition);
292 case SECOND_ORDER -> new SecondOrderNonLinearFingerprintPositionEstimator3D(
293 locatedFingerprints, fingerprint, sources, initialPosition);
294 default -> new FirstOrderNonLinearFingerprintPositionEstimator3D(
295 locatedFingerprints, fingerprint, sources, initialPosition);
296 };
297 }
298
299 /**
300 * Creates an instance of a non-linear 3D position estimator using provided type.
301 *
302 * @param locatedFingerprints located fingerprints containing RSSI readings.
303 * @param fingerprint fingerprint containing readings at an unknown location
304 * for provided located fingerprints.
305 * @param sources located radio sources.
306 * @param initialPosition initial position to start the solving algorithm or null.
307 * @param listener listener in charge of handling events.
308 * @param type a non-linear 3D position estimator.
309 * @return a non-linear 3D position estimator.
310 * @throws IllegalArgumentException if provided non located fingerprint is null,
311 * located fingerprints value is null or there are not enough fingerprints or
312 * readings within provided fingerprints (for 3D position estimation 3 located
313 * total readings are required among all fingerprints).
314 */
315 public static NonLinearFingerprintPositionEstimator3D create(
316 final List<? extends RssiFingerprintLocated<
317 ? extends RadioSource, ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
318 final RssiFingerprint<? extends RadioSource,
319 ? extends RssiReading<? extends RadioSource>> fingerprint,
320 final List<? extends RadioSourceLocated<Point3D>> sources, Point3D initialPosition,
321 final FingerprintPositionEstimatorListener<Point3D> listener,
322 final NonLinearFingerprintPositionEstimatorType type) {
323 return switch (type) {
324 case THIRD_ORDER -> new ThirdOrderNonLinearFingerprintPositionEstimator3D(
325 locatedFingerprints, fingerprint, sources, initialPosition, listener);
326 case SECOND_ORDER -> new SecondOrderNonLinearFingerprintPositionEstimator3D(
327 locatedFingerprints, fingerprint, sources, initialPosition, listener);
328 default -> new FirstOrderNonLinearFingerprintPositionEstimator3D(
329 locatedFingerprints, fingerprint, sources, initialPosition, listener);
330 };
331 }
332
333 /**
334 * Creates an instance of a non-linear 3D position estimator using provided type.
335 *
336 * @return a non-linear 3D position estimator.
337 */
338 public static NonLinearFingerprintPositionEstimator3D create() {
339 return create(DEFAULT_TYPE);
340 }
341
342 /**
343 * Creates an instance of a non-linear 3D position estimator using provided type.
344 *
345 * @param listener listener in charge of handling events.
346 * @return a non-linear 3D position estimator.
347 */
348 public static NonLinearFingerprintPositionEstimator3D create(
349 final FingerprintPositionEstimatorListener<Point3D> listener) {
350 return create(listener, DEFAULT_TYPE);
351 }
352
353 /**
354 * Creates an instance of a non-linear 3D position estimator using provided type.
355 *
356 * @param locatedFingerprints located fingerprints containing RSSI readings.
357 * @param fingerprint fingerprint containing readings at an unknown location
358 * for provided located fingerprints.
359 * @param sources located radio sources.
360 * @return a non-linear 3D position estimator.
361 * @throws IllegalArgumentException if provided non located fingerprint is null,
362 * located fingerprints value is null or there are not enough fingerprints or
363 * readings within provided fingerprints (for 3D position estimation 3 located
364 * total readings are required among all fingerprints).
365 */
366 public static NonLinearFingerprintPositionEstimator3D create(
367 final List<? extends RssiFingerprintLocated<? extends RadioSource,
368 ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
369 final RssiFingerprint<? extends RadioSource,
370 ? extends RssiReading<? extends RadioSource>> fingerprint,
371 final List<? extends RadioSourceLocated<Point3D>> sources) {
372 return create(locatedFingerprints, fingerprint, sources, DEFAULT_TYPE);
373 }
374
375 /**
376 * Creates an instance of a non-linear 3D position estimator using provided type.
377 *
378 * @param locatedFingerprints located fingerprints containing RSSI readings.
379 * @param fingerprint fingerprint containing readings at an unknown location
380 * for provided located fingerprints.
381 * @param sources located radio sources.
382 * @param listener listener in charge of handling events.
383 * @return a non-linear 3D position estimator.
384 * @throws IllegalArgumentException if provided non located fingerprint is null,
385 * located fingerprints value is null or there are not enough fingerprints or
386 * readings within provided fingerprints (for 3D position estimation 3 located
387 * total readings are required among all fingerprints).
388 */
389 public static NonLinearFingerprintPositionEstimator3D create(
390 final List<? extends RssiFingerprintLocated<? extends RadioSource,
391 ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
392 final RssiFingerprint<? extends RadioSource,
393 ? extends RssiReading<? extends RadioSource>> fingerprint,
394 final List<? extends RadioSourceLocated<Point3D>> sources,
395 final FingerprintPositionEstimatorListener<Point3D> listener) {
396 return create(locatedFingerprints, fingerprint, sources, listener, DEFAULT_TYPE);
397 }
398
399 /**
400 * Creates an instance of a non-linear 3D position estimator using provided type.
401 *
402 * @param locatedFingerprints located fingerprints containing RSSI readings.
403 * @param fingerprint fingerprint containing readings at an unknown location
404 * for provided located fingerprints.
405 * @param sources located radio sources.
406 * @param initialPosition initial position to start the solving algorithm or null.
407 * @return a non-linear 3D position estimator.
408 * @throws IllegalArgumentException if provided non located fingerprint is null,
409 * located fingerprints value is null or there are not enough fingerprints or
410 * readings within provided fingerprints (for 3D position estimation 3 located
411 * total readings are required among all fingerprints).
412 */
413 public static NonLinearFingerprintPositionEstimator3D create(
414 final List<? extends RssiFingerprintLocated<? extends RadioSource,
415 ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
416 final RssiFingerprint<? extends RadioSource,
417 ? extends RssiReading<? extends RadioSource>> fingerprint,
418 final List<? extends RadioSourceLocated<Point3D>> sources,
419 final Point3D initialPosition) {
420 return create(locatedFingerprints, fingerprint, sources, initialPosition, DEFAULT_TYPE);
421 }
422
423 /**
424 * Creates an instance of a non-linear 3D position estimator using provided type.
425 *
426 * @param locatedFingerprints located fingerprints containing RSSI readings.
427 * @param fingerprint fingerprint containing readings at an unknown location
428 * for provided located fingerprints.
429 * @param sources located radio sources.
430 * @param initialPosition initial position to start the solving algorithm or null.
431 * @param listener listener in charge of handling events.
432 * @return a non-linear 3D position estimator.
433 * @throws IllegalArgumentException if provided non located fingerprint is null,
434 * located fingerprints value is null or there are not enough fingerprints or
435 * readings within provided fingerprints (for 3D position estimation 3 located
436 * total readings are required among all fingerprints).
437 */
438 public static NonLinearFingerprintPositionEstimator3D create(
439 final List<? extends RssiFingerprintLocated<
440 ? extends RadioSource, ? extends RssiReading<? extends RadioSource>, Point3D>> locatedFingerprints,
441 final RssiFingerprint<? extends RadioSource,
442 ? extends RssiReading<? extends RadioSource>> fingerprint,
443 final List<? extends RadioSourceLocated<Point3D>> sources, Point3D initialPosition,
444 final FingerprintPositionEstimatorListener<Point3D> listener) {
445 return create(locatedFingerprints, fingerprint, sources, initialPosition, listener, DEFAULT_TYPE);
446 }
447 }