View Javadoc
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 }