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.Point;
19 import com.irurueta.navigation.LockedException;
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 * Base class for position estimators based on located fingerprints containing only
30 * RSSI readings and having as well prior knowledge of the location of radio sources
31 * associated to those readings.
32 *
33 * @param <P> a {@link Point} type.
34 */
35 public abstract class FingerprintPositionEstimator<P extends Point<?>> extends
36 BaseFingerprintPositionEstimator<P, FingerprintPositionEstimatorListener<P>> {
37
38 /**
39 * Located radio sources.
40 */
41 protected List<? extends RadioSourceLocated<P>> sources;
42
43 /**
44 * Indicates whether path loss exponent of provided sources must be used when
45 * available (if true), or if fallback path loss exponent must be used instead.
46 */
47 protected boolean useSourcesPathLossExponentWhenAvailable = true;
48
49 /**
50 * True indicates that mean effects are removed to find nearest located fingerprints
51 * based on RSSI readings. False indicates that RSSI readings are directly used, which
52 * might be inaccurate due to bias effects on new fingerprint readings for unknown
53 * locations.
54 * By default, mean effects are removed to remove possible bias effects due to
55 * readings measured by different devices with different hardware.
56 */
57 protected boolean useNoMeanNearestFingerprintFinder = true;
58
59 /**
60 * True indicates that mean effects are removed from located fingerprints and from
61 * new fingerprints whose location is unknown.
62 * By default, this is disabled.
63 */
64 protected boolean removeMeansFromFingerprintReadings;
65
66 /**
67 * Constructor.
68 */
69 protected FingerprintPositionEstimator() {
70 }
71
72 /**
73 * Constructor.
74 *
75 * @param listener listener in charge of handling events.
76 */
77 protected FingerprintPositionEstimator(final FingerprintPositionEstimatorListener<P> listener) {
78 super(listener);
79 }
80
81 /**
82 * Constructor.
83 *
84 * @param locatedFingerprints located fingerprints containing RSSI readings.
85 * @param fingerprint fingerprint containing readings at an unknown location
86 * for provided located fingerprints.
87 * @param sources located radio sources.
88 * @throws IllegalArgumentException if provided non located fingerprint is null,
89 * located fingerprints value is null or there are not enough fingerprints or
90 * readings within provided fingerprints (for 2D position estimation at least 2
91 * located total readings are required among all fingerprints, for example 2
92 * readings are required in a single fingerprint, or at least 2 fingerprints at
93 * different locations containing a single reading are required. For 3D position
94 * estimation 3 located total readings are required among all fingerprints).
95 */
96 protected FingerprintPositionEstimator(
97 final List<? extends RssiFingerprintLocated<? extends RadioSource,
98 ? extends RssiReading<? extends RadioSource>, P>> locatedFingerprints,
99 final RssiFingerprint<? extends RadioSource,
100 ? extends RssiReading<? extends RadioSource>> fingerprint,
101 final List<? extends RadioSourceLocated<P>> sources) {
102 super(locatedFingerprints, fingerprint);
103 internalSetSources(sources);
104 }
105
106 /**
107 * Constructor.
108 *
109 * @param locatedFingerprints located fingerprints containing RSSI readings.
110 * @param fingerprint fingerprint containing readings at an unknown location
111 * for provided located fingerprints.
112 * @param sources located radio sources.
113 * @param listener listener in charge of handling events.
114 * @throws IllegalArgumentException if provided non located fingerprint is null,
115 * located fingerprints value is null or there are not enough fingerprints or
116 * readings within provided fingerprints (for 2D position estimation at least 2
117 * located total readings are required among all fingerprints, for example 2
118 * readings are required in a single fingerprint, or at least 2 fingerprints at
119 * different locations containing a single reading are required. For 3D position
120 * estimation 3 located total readings are required among all fingerprints).
121 */
122 protected FingerprintPositionEstimator(
123 final List<? extends RssiFingerprintLocated<? extends RadioSource,
124 ? extends RssiReading<? extends RadioSource>, P>> locatedFingerprints,
125 final RssiFingerprint<? extends RadioSource,
126 ? extends RssiReading<? extends RadioSource>> fingerprint,
127 final List<? extends RadioSourceLocated<P>> sources,
128 final FingerprintPositionEstimatorListener<P> listener) {
129 super(locatedFingerprints, fingerprint, listener);
130 internalSetSources(sources);
131 }
132
133 /**
134 * Gets located radio sources.
135 *
136 * @return located radio sources.
137 */
138 public List<RadioSourceLocated<P>> getSources() {
139 //noinspection unchecked
140 return (List<RadioSourceLocated<P>>) sources;
141 }
142
143 /**
144 * Sets located radio sources.
145 *
146 * @param sources located radio sources.
147 * @throws LockedException if estimator is locked.
148 */
149 public void setSources(final List<? extends RadioSourceLocated<P>> sources) throws LockedException {
150 if (isLocked()) {
151 throw new LockedException();
152 }
153
154 internalSetSources(sources);
155 }
156
157 /**
158 * Indicates whether path loss exponent of provided sources must be used when
159 * available (if true), or if fallback path loss exponent must be used instead.
160 *
161 * @return true to use path loss exponent of provided sources when available,
162 * false otherwise.
163 */
164 public boolean getUseSourcesPathLossExponentWhenAvailable() {
165 return useSourcesPathLossExponentWhenAvailable;
166 }
167
168 /**
169 * Specifies whether path loss exponent of provided sources must be used when
170 * available (if true), or if fallback path loss exponent must be used instead.
171 *
172 * @param useSourcesPathLossExponentWhenAvailable true to use path loss exponent of
173 * provided sources when available,
174 * false otherwise.
175 * @throws LockedException if estimator is locked.
176 */
177 public void setUseSourcesPathLossExponentWhenAvailable(final boolean useSourcesPathLossExponentWhenAvailable)
178 throws LockedException {
179 if (isLocked()) {
180 throw new LockedException();
181 }
182 this.useSourcesPathLossExponentWhenAvailable = useSourcesPathLossExponentWhenAvailable;
183 }
184
185 /**
186 * Indicates which fingerprint finder is used.
187 * True indicates that mean effects are removed to find nearest located fingerprints
188 * based on RSSI readings. False indicates that RSSI readings are directly used, which
189 * might be inaccurate due to bias effects on new fingerprint readings for unknown
190 * locations.
191 * By default, mean effects are removed to remove possible bias effects due to
192 * readings measured by different devices with different hardware.
193 *
194 * @return indicates which fingerprint finder is used.
195 */
196 public boolean getUseNoMeanNearestFingerprintFinder() {
197 return useNoMeanNearestFingerprintFinder;
198 }
199
200 /**
201 * Specifies which fingerprint finder is used.
202 * True indicates that mean effects are removed to find nearest located fingerprints
203 * based on RSSI readings. False indicates that RSSI readings are directly used, which
204 * might be inaccurate due to bias effects on new fingerprint readings for unknown
205 * locations.
206 * By default, mean effects are removed to remove possible bias effects due to
207 * readings measured by different devices with different hardware.
208 *
209 * @param useNoMeanNearestFingerprintFinder indicates which fingerprint finder is used.
210 * @throws LockedException if estimator is locked.
211 */
212 public void setUseNoMeanNearestFingerprintFinder(final boolean useNoMeanNearestFingerprintFinder)
213 throws LockedException {
214 if (isLocked()) {
215 throw new LockedException();
216 }
217 this.useNoMeanNearestFingerprintFinder = useNoMeanNearestFingerprintFinder;
218 }
219
220 /**
221 * Indicates whether mean effects are removed from fingerprints.
222 * True indicates that mean effects are removed from located fingerprints and from
223 * new fingerprints whose location is unknown.
224 * By default, this is disabled.
225 *
226 * @return true to remove mean effects, false otherwise.
227 */
228 public boolean isMeansFromFingerprintReadingsRemoved() {
229 return removeMeansFromFingerprintReadings;
230 }
231
232 /**
233 * Specifies whether mean effects are removed from fingerprints.
234 * True indicates that mean effects are removed from located fingerprints and from
235 * new fingerprints whose location is unknown.
236 * By default, this is disabled.
237 *
238 * @param removeMeansFromFingerprintReadings true to remove mean effects, false otherwise.
239 * @throws LockedException if estimator is locked.
240 */
241 public void setMeansFromFingerprintReadingsRemoved(final boolean removeMeansFromFingerprintReadings)
242 throws LockedException {
243 if (isLocked()) {
244 throw new LockedException();
245 }
246 this.removeMeansFromFingerprintReadings = removeMeansFromFingerprintReadings;
247 }
248
249 /**
250 * Indicates whether estimator is ready to find a solution.
251 *
252 * @return true if estimator is ready, false otherwise.
253 */
254 @Override
255 public boolean isReady() {
256 return sources != null && locatedFingerprints != null && fingerprint != null;
257 }
258
259 /**
260 * Internally sets located radio sources.
261 *
262 * @param sources located radio sources.
263 * @throws IllegalArgumentException if provided value is null.
264 */
265 private void internalSetSources(final List<? extends RadioSourceLocated<P>> sources) {
266 if (sources == null) {
267 throw new IllegalArgumentException();
268 }
269
270 this.sources = sources;
271 }
272 }