FingerprintPositionEstimator.java
/*
* Copyright (C) 2018 Alberto Irurueta Carro (alberto@irurueta.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.irurueta.navigation.indoor.fingerprint;
import com.irurueta.geometry.Point;
import com.irurueta.navigation.LockedException;
import com.irurueta.navigation.indoor.RadioSource;
import com.irurueta.navigation.indoor.RadioSourceLocated;
import com.irurueta.navigation.indoor.RssiFingerprint;
import com.irurueta.navigation.indoor.RssiFingerprintLocated;
import com.irurueta.navigation.indoor.RssiReading;
import java.util.List;
/**
* Base class for position estimators based on located fingerprints containing only
* RSSI readings and having as well prior knowledge of the location of radio sources
* associated to those readings.
*
* @param <P> a {@link Point} type.
*/
public abstract class FingerprintPositionEstimator<P extends Point<?>> extends
BaseFingerprintPositionEstimator<P, FingerprintPositionEstimatorListener<P>> {
/**
* Located radio sources.
*/
protected List<? extends RadioSourceLocated<P>> sources;
/**
* Indicates whether path loss exponent of provided sources must be used when
* available (if true), or if fallback path loss exponent must be used instead.
*/
protected boolean useSourcesPathLossExponentWhenAvailable = true;
/**
* True indicates that mean effects are removed to find nearest located fingerprints
* based on RSSI readings. False indicates that RSSI readings are directly used, which
* might be inaccurate due to bias effects on new fingerprint readings for unknown
* locations.
* By default, mean effects are removed to remove possible bias effects due to
* readings measured by different devices with different hardware.
*/
protected boolean useNoMeanNearestFingerprintFinder = true;
/**
* True indicates that mean effects are removed from located fingerprints and from
* new fingerprints whose location is unknown.
* By default, this is disabled.
*/
protected boolean removeMeansFromFingerprintReadings;
/**
* Constructor.
*/
protected FingerprintPositionEstimator() {
}
/**
* Constructor.
*
* @param listener listener in charge of handling events.
*/
protected FingerprintPositionEstimator(final FingerprintPositionEstimatorListener<P> listener) {
super(listener);
}
/**
* Constructor.
*
* @param locatedFingerprints located fingerprints containing RSSI readings.
* @param fingerprint fingerprint containing readings at an unknown location
* for provided located fingerprints.
* @param sources located radio sources.
* @throws IllegalArgumentException if provided non located fingerprint is null,
* located fingerprints value is null or there are not enough fingerprints or
* readings within provided fingerprints (for 2D position estimation at least 2
* located total readings are required among all fingerprints, for example 2
* readings are required in a single fingerprint, or at least 2 fingerprints at
* different locations containing a single reading are required. For 3D position
* estimation 3 located total readings are required among all fingerprints).
*/
protected FingerprintPositionEstimator(
final List<? extends RssiFingerprintLocated<? extends RadioSource,
? extends RssiReading<? extends RadioSource>, P>> locatedFingerprints,
final RssiFingerprint<? extends RadioSource,
? extends RssiReading<? extends RadioSource>> fingerprint,
final List<? extends RadioSourceLocated<P>> sources) {
super(locatedFingerprints, fingerprint);
internalSetSources(sources);
}
/**
* Constructor.
*
* @param locatedFingerprints located fingerprints containing RSSI readings.
* @param fingerprint fingerprint containing readings at an unknown location
* for provided located fingerprints.
* @param sources located radio sources.
* @param listener listener in charge of handling events.
* @throws IllegalArgumentException if provided non located fingerprint is null,
* located fingerprints value is null or there are not enough fingerprints or
* readings within provided fingerprints (for 2D position estimation at least 2
* located total readings are required among all fingerprints, for example 2
* readings are required in a single fingerprint, or at least 2 fingerprints at
* different locations containing a single reading are required. For 3D position
* estimation 3 located total readings are required among all fingerprints).
*/
protected FingerprintPositionEstimator(
final List<? extends RssiFingerprintLocated<? extends RadioSource,
? extends RssiReading<? extends RadioSource>, P>> locatedFingerprints,
final RssiFingerprint<? extends RadioSource,
? extends RssiReading<? extends RadioSource>> fingerprint,
final List<? extends RadioSourceLocated<P>> sources,
final FingerprintPositionEstimatorListener<P> listener) {
super(locatedFingerprints, fingerprint, listener);
internalSetSources(sources);
}
/**
* Gets located radio sources.
*
* @return located radio sources.
*/
public List<RadioSourceLocated<P>> getSources() {
//noinspection unchecked
return (List<RadioSourceLocated<P>>) sources;
}
/**
* Sets located radio sources.
*
* @param sources located radio sources.
* @throws LockedException if estimator is locked.
*/
public void setSources(final List<? extends RadioSourceLocated<P>> sources) throws LockedException {
if (isLocked()) {
throw new LockedException();
}
internalSetSources(sources);
}
/**
* Indicates whether path loss exponent of provided sources must be used when
* available (if true), or if fallback path loss exponent must be used instead.
*
* @return true to use path loss exponent of provided sources when available,
* false otherwise.
*/
public boolean getUseSourcesPathLossExponentWhenAvailable() {
return useSourcesPathLossExponentWhenAvailable;
}
/**
* Specifies whether path loss exponent of provided sources must be used when
* available (if true), or if fallback path loss exponent must be used instead.
*
* @param useSourcesPathLossExponentWhenAvailable true to use path loss exponent of
* provided sources when available,
* false otherwise.
* @throws LockedException if estimator is locked.
*/
public void setUseSourcesPathLossExponentWhenAvailable(final boolean useSourcesPathLossExponentWhenAvailable)
throws LockedException {
if (isLocked()) {
throw new LockedException();
}
this.useSourcesPathLossExponentWhenAvailable = useSourcesPathLossExponentWhenAvailable;
}
/**
* Indicates which fingerprint finder is used.
* True indicates that mean effects are removed to find nearest located fingerprints
* based on RSSI readings. False indicates that RSSI readings are directly used, which
* might be inaccurate due to bias effects on new fingerprint readings for unknown
* locations.
* By default, mean effects are removed to remove possible bias effects due to
* readings measured by different devices with different hardware.
*
* @return indicates which fingerprint finder is used.
*/
public boolean getUseNoMeanNearestFingerprintFinder() {
return useNoMeanNearestFingerprintFinder;
}
/**
* Specifies which fingerprint finder is used.
* True indicates that mean effects are removed to find nearest located fingerprints
* based on RSSI readings. False indicates that RSSI readings are directly used, which
* might be inaccurate due to bias effects on new fingerprint readings for unknown
* locations.
* By default, mean effects are removed to remove possible bias effects due to
* readings measured by different devices with different hardware.
*
* @param useNoMeanNearestFingerprintFinder indicates which fingerprint finder is used.
* @throws LockedException if estimator is locked.
*/
public void setUseNoMeanNearestFingerprintFinder(final boolean useNoMeanNearestFingerprintFinder)
throws LockedException {
if (isLocked()) {
throw new LockedException();
}
this.useNoMeanNearestFingerprintFinder = useNoMeanNearestFingerprintFinder;
}
/**
* Indicates whether mean effects are removed from fingerprints.
* True indicates that mean effects are removed from located fingerprints and from
* new fingerprints whose location is unknown.
* By default, this is disabled.
*
* @return true to remove mean effects, false otherwise.
*/
public boolean isMeansFromFingerprintReadingsRemoved() {
return removeMeansFromFingerprintReadings;
}
/**
* Specifies whether mean effects are removed from fingerprints.
* True indicates that mean effects are removed from located fingerprints and from
* new fingerprints whose location is unknown.
* By default, this is disabled.
*
* @param removeMeansFromFingerprintReadings true to remove mean effects, false otherwise.
* @throws LockedException if estimator is locked.
*/
public void setMeansFromFingerprintReadingsRemoved(final boolean removeMeansFromFingerprintReadings)
throws LockedException {
if (isLocked()) {
throw new LockedException();
}
this.removeMeansFromFingerprintReadings = removeMeansFromFingerprintReadings;
}
/**
* Indicates whether estimator is ready to find a solution.
*
* @return true if estimator is ready, false otherwise.
*/
@Override
public boolean isReady() {
return sources != null && locatedFingerprints != null && fingerprint != null;
}
/**
* Internally sets located radio sources.
*
* @param sources located radio sources.
* @throws IllegalArgumentException if provided value is null.
*/
private void internalSetSources(final List<? extends RadioSourceLocated<P>> sources) {
if (sources == null) {
throw new IllegalArgumentException();
}
this.sources = sources;
}
}