Multilateration using bluetooth beacons
There may be breaking changes when upgrading from 0.3.8! All changes to the previous release can be found in PR #160.
boolean canMatch(Beacon beacon)
method to avoid ClassCastException
s when using BeaconFilter
s with Beacon
instances of the wrong typeAscendingRssiComparator
and DescendingRssiComparator
There may be breaking changes when upgrading from 0.3.0! All changes to the previous release can be found in PR 130.
rootMeanSquareThreshold
property to filter out inaccurate multilateration results. Increase the value to allow location updates with higher deviation (div)getMeanLocation
convenience method (div)maximumMovementSpeed
indoorPositioningBeaconFilter
usableIndoorPositioningBeaconFilter
rootMeanSquareThreshold
minimumRssiThreshold
rootMeanSquare
property (div)hasBeenSeenInThePast(long duration, TimeUnit timeUnit)
)BeaconUpdateListener
from different trheads (div)getSmallestDistance(List<? extends Beacon> beaconList)
getClosestBeacon(List<? extends Beacon> beaconList)
calculateRssiForDistance(Beacon beacon, float distance)
proximityUuids
(div)updateLocation()
canUpdateLocation()
AdvertisingPacketFactory
is now an abstract class for the generic type <AP extends AdvertisingPacket>
that can hold sub-factoriesAdvertisingPacketFactoryManager
, IBeaconAdvertisingPacketFactory
and EddystoneAdvertisingPacketFactory
have been adjusted accordingly (div)elevation
property (div)
elevation
describes the relative height to the floor (e.g. 2.5 meters)altitude
describes the distance to the sea level (e.g. 200 meters)LocationUtil
class with convenience methods (div)
calculateMeanLocation(List<Location> locationList)
getLocationsBetween(List<Location> locationList, long minimumTimestamp, long maximumTimestamp)
getLocationsFromLast(List<Location> locationList, long amount, TimeUnit timeUnit)
getLocationsSince(List<Location> locationList, long timestamp)
getLocationsBefore(List<Location> locationList, long timestamp)
There's a new LocationPredictor
class available, which is capable of predicting future locations based on recent locations. Internally, it calculates the mean speed and angle from the specified locations. It will then shift the most recent location depending on how far you want to look into the future. You can check out the implementation here or find usage examples in the LocationPredictorTest
.
One LocationPredictor
instance is now part of the IndoorPositioning
singleton, always populated with the most recent multilateration results.
// predict where the device will be located in 2 seconds
LocationPredictor locationPredictor = IndoorPositioning.getLocationPredictor();
locationPredictor.setPredictionDuration(TimeUnit.SECONDS.toMillis(2));
Location predictedLocation = locationPredictor.getLocation()
Any Location
instance can now be shifted by a given distance (in meters) towards an angle (in degrees).
double distance = 1000; // 1 km
double angle = 180; // heading south
Location notTheCenterOfBerlin = new Location(BERLIN);
notTheCenterOfBerlin.shift(distance, angle);
There's also a convenience method available if you want to shift a new instance of a location.
double distance = BERLIN.getDistanceTo(NEW_YORK_CITY);
double angle = BERLIN.getAngleTo(NEW_YORK_CITY);
// this should be New York City
Location shiftedLocation = BERLIN.getShiftedLocation(distance, angle);
The DistanceUtil
now contains methods allowing you trim the distance between two locations based on a specified maximum speed. It will essentially restrain the newLocation
being further away from the oldLocation
than the distance possible in the time window based on the maximumSpeed
. Check out the DistanceUtilTest
for usage examples.
Location oldLocation = BERLIN;
oldLocation.setTimestamp(System.currentTimeMillis());
// create a new location, 5 meters away from the old location
Location newLocation = oldLocation.getShiftedLocation(5, 0);
// increment the timestamp by 1 second (note that the
// speed would thus be 5 meters per second)
newLocation.setTimestamp(oldLocation.getTimestamp() + TimeUnit.SECONDS.toMillis(1));
// instead of being 5 meters away from the old location, the speed
// filtered location will be ~1.4 meters away from it
Location speedFilteredLocation = DistanceUtil.speedFilter(oldLocation, newLocation, DistanceUtil.HUMAN_WALKING_SPEED);
The new AngleUtil
provides some methods for dealing with angles. It can, for instance, calculate the mean angle between given a list of locations. This is used for the location prediction mentioned above. Check out the AngleUtilTest
for usage examples.
You can now use classes implementing RssiFilter
to reduce the signal fluctuation. Using filters leads to more stable results and thus more accurate indoor positioning. This release already includes a MeanFilter
, a KalmanFilter
and an ArmaFilter
. Convenience methods in the Beacon
class have been adjusted accordingly.
// get the average RSSI from the past 5 seconds
MeanFilter meanFilter = new MeanFilter(5, TimeUnit.SECONDS);
float meanRssi = beacon.getRssi(meanFilter);
In addition to the already included Eddystone
and IBeacon
classes, you can now define your own custom Beacon
classes. To make sure that the BeaconManager
still operates nicely, it now holds a BeaconFactory
. You can add you own classes to that factory.
Check out the BeaconFactoryTest
to see an example implementation.
For the same reason, the BeaconManager
now also holds an AdvertisingPacketFactoryManager
, which you can extend with your own AdvertisingPacketFactory
. These factories will be used to create AdvertisingPacket
instances from the raw advertising data byte arrays (e.g. when you call BeaconManager.processAdvertisingData(...)
).
Check out the AdvertisingPacketFactoryManagerTest
to see an example implementation.