2

The iBeacon ranging process (as available from CoreLocation) do not provide a smooth going distance of iPhone from an iBeacon instead it gives a too much fluctuating values. I also tried to use weighted average but it do not gives desired results. I come across the link that explained the use of Kalman Filter to remove noise from signals. I also came across a swift framework that has implemented the filter. My question is how to apply the kalman filter logic to get a smooth distance from iBeacon? I am currently using below code to calculate a distance but I do not have any idea how to apply a kalman filter over it.

func calculateNewDistance(txCalibratedPower: Int, rssi: Int) -> Double{
        if rssi == 0{
            return -1
        }
        let ratio = Double(exactly:rssi)!/Double(txCalibratedPower)
        if ratio < 1.0{
            return pow(10.0, ratio)
        }else{
            let accuracy = 0.89976 * pow(ratio, 7.7095) + 0.111
            return accuracy
        }

    }

Here txCalibratedPower is being passed as -74

1 Answers1

0

When ranging, each callback to didRangeBeacons includes an array of [Beacon] objects, and each element has a rssi parameter beacon.rssi.

You need to create a dictionary or some other data structure to store the most recent rssi readings for each beacon. For convenience, I often use a key into the dictionary based on the beacon identifier:

var recentRssiDict: [String:[Double]] = [:]

...

// inside didRangeBeacons
let dictKey = "\(beacon.uuid) \(beacon.major) \(beacon.minor)"
var recentRssis = recentRssiDict[dictKey] && []
recentRssis.append(beacon.rssi)
recentRssiDict[dictKey] = recentRssis
// TODO: delete old elements depending on how many you want to track

You can then apply a Kalman filter algorithm based on these readings in recentRSSIs to get a filteredRssi. Finally, you plug the filteredRssi into a distance algorithm. See my answer here:

Understanding ibeacon distancing

davidgyoung
  • 63,876
  • 14
  • 121
  • 204