package org.altbeacon.beacon.distance; import org.altbeacon.beacon.BeaconManager; import org.altbeacon.beacon.logging.LogManager; /** * This class estimates the distance between the mobile device and a BLE beacon based on the measured * RSSI and a txPower calibration value that represents the expected RSSI for an iPhone 5 receiving * the signal when it is 1 meter away. * * This class uses a best-fit curve equation with configurable coefficients. The coefficients must * be supplied by the caller and are specific to the Android device being used. See the * <code>ModelSpecificDistanceCalculator</code> for more information on the coefficients. * * Created by dyoung on 8/28/14. */ public class CurveFittedDistanceCalculator implements DistanceCalculator { public static final String TAG = "CurveFittedDistanceCalculator"; private double mCoefficient1; private double mCoefficient2; private double mCoefficient3; /** * Construct a calculator with coefficients specific for the device's signal vs. distance * * @param coefficient1 * @param coefficient2 * @param coefficient3 */ public CurveFittedDistanceCalculator(double coefficient1, double coefficient2, double coefficient3) { mCoefficient1 = coefficient1; mCoefficient2 = coefficient2; mCoefficient3 = coefficient3; } /** * Calculated the estimated distance in meters to the beacon based on a reference rssi at 1m * and the known actual rssi at the current location * * @param txPower * @param rssi * @return estimated distance */ @Override public double calculateDistance(int txPower, double rssi) { if (rssi == 0) { return -1.0; // if we cannot determine accuracy, return -1. } LogManager.d(TAG, "calculating distance based on mRssi of %s and txPower of %s", rssi, txPower); double ratio = rssi*1.0/txPower; double distance; if (ratio < 1.0) { distance = Math.pow(ratio,10); } else { distance = (mCoefficient1)*Math.pow(ratio,mCoefficient2) + mCoefficient3; } LogManager.d(TAG, "avg mRssi: %s distance: %s", rssi, distance); return distance; } }