guys
I'm using Altbeacon Android Library to do some Bluetooth app for demo. It provides with a getDistance() method that I can use to get distance between my phone and external Bluetooth device with Altbeacon protocol uploaded. However, as the devices are different, I think the distance might vary with a large error (I get 0.05m when I'm at 1m away, so on and so forth). This makes me think that if we do some calibration work for the getDistance() method will be useful. Is there any way of doing this? (Currently I have no idea how to modify the getDistance method, maybe #override it? Not very sure)
Many thanks.
I am not aware of any calibration functionality in the library. However, you can change distance calculation by implementing your own DistanceCalculator.
The default distance calculator is ModelSpecificDistanceCalculator and it set in the BeaconServices onCreate method (check this). So, simply creating your own version of the DistanceCalculator and set it after BeaconService is created can do what you want;
// after beacon service is created
DistanceCalculator customCalculator = ...;
Beacon.setDistanceCalculator(customCalculator);
However, you should now that device is also causes variation;
Each model may have a different Bluetooth chipset and antenna, and therefore may receive a different signal level when in the same position relative to a beacon. In order to address this, the library uses a different formula for calculating distance for different Android device models. Because not all devices have custom formulas built into the library, the library will fall back to the default device calculation for the Nexus 5 if no matching formula is found.
For more information about distance calculation, please visit AltBeacon - Distance Calculations page. This page also explains how distance calculation works as well as how you can contribute to enhance the library for device variation.
By the way, you can also check CurveFittedDistanceCalculator but this one requires you to give device specific coefficients (explained in this page). For more info about this, check its source code.
Related
I would like to figure out how to locate a device by its connection strenght(dBm). Even if this don't give me a direct location, it could give me a radius of the device to the phone or the other way around. So far i've been able to gather the device name and RSSI "strenght" however, its a dynamic data i'm getting. I would like an continuously update of how good the strenght is. So the part I'm stuck on is getting the correct values(ive got -72dbm and -342654dbm form the tests) and i need updates every 3 second.
What you should really do is use the Android Beacon Library, it will work the distance out for you.
The actual calculation is very complex and this Library has been used by a lot of people since Radius Networks created it. The link is for the website downloads, but you can use gradle too.
It's easy to use and probably exactly what you're looking for
I've been doing a bit of research on a problem we are trying to solve. I think this is the best approach but please add in your opinions
We are trying to calculate reaction times in a real world driving scenario and would like to use a mobile phone as the data collection device. What we are trying to accomplish is how much acceleration and more importantly deceleration a driver exerts when exposed to certain prompts.
I found this paper that has allot of useful information Accelerometer physics
The problem is that we most likely will not have a calibration time to start at zero.. however it is assumed that the driver is starting at 0. We will use GPS positioning to locate the vehicle, tracking the time stamped location data we should calculate the time when the prompt took place then using the time stamped accelerometer data we should be able to calculate their reaction to the prompt.
This is the best way I have found to solve the problem however I'm not sure if the accelerometer data will be rendered useless because of not being able to calibrate it and also the noise seen from vibrations may be too great to use the data... Has anyone tried or used these types of methods before?
Interesting application.
You are missing an important point. You either have to implement the so-called sensor fusion yourself or use the sensor fusion provided on the platform you are using. Both Android and iPhone have one.
The TYPE_LINEAR_ACCELERATION (Android, SensorManager) or userAcceleration (iPhone) should be sufficient for you.
As for the linked PDF, don't try integrating the acceleration, you will get very poor results. Even though that answer is about position, the velocity will already be inaccurate. I would try the GPS instead.
I know it's very old question but since I am recently working on a similar project let me share what we did in our company. We simply used OBD-II dongle to get velocity of car. There are many API's that return information about vehicle.
PID010D returns speed of vehicle. I'm using this PID to calculate distance between points A and B since there is no PID to return Odometer :(
There are few libraries on github that you can find easily by search. This mine. This is not library but after run on your device you can see how it works.
I'm fairly new to iBeacon but I have spent the day trying to get informations and a working Android application with iBeacon.
I have stumbled upon Android iBeacon Library samples and gave it a try. I used the latest aar file (0.7.3) and basically copy/paste their examples in a new project.
I have created a beacon using an iPad with AirLocate (compiled from Apple's code from the Dev Center) and launch the code.
My problem is the range fluctuating all the time with no logic.
For example, the phone (in this case a Nexus 5, original rom, no modification) placed half a meter away from the iPad gives me the following measures :
0.01m
0.03m
0.07m
0.48m
0.01m
0.02m
etc.
When I use another iPad with AirLocate on it, it gives a more stable and realistic measure. Excluding the beacon as the source of the problem.
I have made the test with a Nexus 7 2013 (Original rom, not modified) and I got the same issue. I have read the wifi can cause problem so I disabled it but it is still the same.
I also have the same issue with Radius Networks application on the Play Store: iBeacon Locate
I was wondering if the anyone else have the problem with this library ?
Is there something I can do to help fix this problem ?
Do you know another library I can use which won't cause that kind of problem ?
Any help is appreciate. Thank you in advance.
A big part of the variation you see is Android is caused by a limitation in the way Android allows access signal strength measurements from Bluetooth LE. Unfortunately, there isn't much that can be done about this without changes to Android.
In both iOS CoreLocation and the Android iBeacon Library, the distance estimate is only an estimate, and fluctuations with noise on signal strength measurements cause the estimates to bounce around.
The algorithm in the Android iBeacon Library is not the same as in iOS CoreLocation, because the iOS CoreLocation implementation is closed source. The intention is that they behave in a similar way. The Android iBeacon Library is based on a 10 second running average of 80th percentile measurements (e.g. the top and bottom 10th percentile measurements are thrown away for the average.) You can see the details of the calculation here:
protected static double calculateAccuracy(int txPower, double rssi) {
if (rssi == 0) {
return -1.0; // if we cannot determine accuracy, return -1.
}
double ratio = rssi*1.0/txPower;
if (ratio < 1.0) {
return Math.pow(ratio,10);
}
else {
double accuracy = (0.89976)*Math.pow(ratio,7.7095) + 0.111;
return accuracy;
}
}
On Android, the Bluetooth LE Scan API only allows a single signal strength measurement per scan. On iOS, it is possible to get a different measurement for each advertisement broadcasted. By default, the Android iBeacon Library does one bluetooth scan every 1.1 seconds when it is in the foreground, therefore allowing one measurement every 1.1 seconds. So if you have an iBeacon that is transmitting 30 times per second (as iOS devices acting as iBeacons do), iOS will be able to get 300 samples in a 10 second period, and Android only 9. This explains why the estimate has higher noise on Android. And again, there is very little that can be done about it without operating system changes.
Depending on your use case, you may be able to reduce the noise in the distance estimate on Android by implementing a custom calculation that includes more samples over a longer period of time. This would only be appropriate if your use case does not need rapid updates in the estimate. If you are interested in this, you might open a feature request in the open source library.
I've been doing a bit of research on a problem we are trying to solve. I think this is the best approach but please add in your opinions
We are trying to calculate reaction times in a real world driving scenario and would like to use a mobile phone as the data collection device. What we are trying to accomplish is how much acceleration and more importantly deceleration a driver exerts when exposed to certain prompts.
I found this paper that has allot of useful information Accelerometer physics
The problem is that we most likely will not have a calibration time to start at zero.. however it is assumed that the driver is starting at 0. We will use GPS positioning to locate the vehicle, tracking the time stamped location data we should calculate the time when the prompt took place then using the time stamped accelerometer data we should be able to calculate their reaction to the prompt.
This is the best way I have found to solve the problem however I'm not sure if the accelerometer data will be rendered useless because of not being able to calibrate it and also the noise seen from vibrations may be too great to use the data... Has anyone tried or used these types of methods before?
Interesting application.
You are missing an important point. You either have to implement the so-called sensor fusion yourself or use the sensor fusion provided on the platform you are using. Both Android and iPhone have one.
The TYPE_LINEAR_ACCELERATION (Android, SensorManager) or userAcceleration (iPhone) should be sufficient for you.
As for the linked PDF, don't try integrating the acceleration, you will get very poor results. Even though that answer is about position, the velocity will already be inaccurate. I would try the GPS instead.
I know it's very old question but since I am recently working on a similar project let me share what we did in our company. We simply used OBD-II dongle to get velocity of car. There are many API's that return information about vehicle.
PID010D returns speed of vehicle. I'm using this PID to calculate distance between points A and B since there is no PID to return Odometer :(
There are few libraries on github that you can find easily by search. This mine. This is not library but after run on your device you can see how it works.
I am developing a project that is intended to use the GPS capabilities of an Android phone and a nearby station to compute positioning to a much more precise degree (cm), using RTK DGPS technology.
So far, I haven't been able to see anyone saying they actually managed to perform a similar task (apart from #GPSmaster, who doesn't explain how), and the APK doesn't seem to offer any information from the GPS chip other than location and NMEA message updates. I need, if possible, pseudo-ranges and carrier phases.
I was wondering if:
It would be possible to look for lower level hooks on my phone using native code, or other lower level snooping;
It would be possible to send RTCM corrections to the GPS chip present on one of these devices;
Any ideas?
Generally speaking DGPS is a technique that improves real position accuracy by canceling out most of the atmospheric effects on the GPS signal. In a typical direct GPS measurement there is about a random error in the ranges computed to the satellites due to atmospheric effects. This is why a GPS receiver that is left collecting data in a fixed location will seem to wander with in an error ellipse. For two receiver stations in the same area the atmospheric effects are almost identical and they will wander in parallel within their similarly sized and oriented error ellipses. If one of the two receivers is at a know location then the differences in their apparent GPS locations can be taken and plotted from the true location of the known station to find the true location of the unknown station.
Back in the day (circa 1992) when we had to accomplish DGPS by "post processing" we used to take the raw NEMA data collected at the two stations match up the times, compute the baseline vector and apply it to the known point to find the unknown point. I think the NEMA data we were using was only recorded to the nearest 10 sec. The math isn't really that hard.
I suspect that NEMA GPS messages [http://developer.android.com/reference/android/location/GpsStatus.NmeaListener.html ] from a tablet at a known point (with a clear sky view) could probably be sent over an internet socket to a smart phone (also with a clear sky view), which could then compute the difference and achieve a sub-meter relative location over a distance of few km, even if the assumed Internet transit times were ignored. This technique would probably still work even if the tablet and smart phone were both applying broadcast DGPS adjustments.
With the andvent of Android 7.1, the raw data from GPS chips will be available to developers. (http://gpsworld.com/google-to-provide-raw-gnss-measurements/)
Others seem to have done something similar to what you wish to accomplish (http://gpsworld.com/innovation-precise-positioning-using-raw-gps-measurements-from-android-smartphones/)
No, it is not practical to get any lower level access to the GPS device by an Android application. This has several reasons:
The application has no other means of accessing the GPS device as through the Java based API. Native code is forbidden to use most devices and usually needs a Java wrapper to tunnel through the sandbox for Android sensor devices. This makes up the main security concept.
If native code would have access to the GPS device on a lower level, it would have to cope with several different manufacturers protocols now not abstracted by the API. Best chances are to get access to custom NMEA codes, which may still have device dependent caveats.
Even if lower level access would be possible, one loses the integrated merging of other location sources like WLAN and cellphone carrier, that are presumably merged in native code below the Java API but above the NMEA protocol.
You can use DGPS corrections in Europe via custom application for SISnet receiving correction signals from EGNOS augmentation satellites(http://egnos-portal.gsa.europa.eu/news/egnos-gets-invite-your-smartphone-11). It does however need a subscription (which isn't really open to public yet) to SISnet to obtain username and password for connection to their servers. There's some of SDK published which you may find useful. Just remember that you are limited to C/A signals only (pseudoranges) and you CANNOT get phase data (L1/L2) from those cheap chips inside smartphones.You'd need a precision GNSS receiver such as Trimble BD910 (http://www.trimble.com/gnss-inertial/bd910.aspx?dtID=overview) to be able to access L1 carrier phase signal for GPS & GLONASS. There are however cheaper chips that support SBAS but none are yet installed natively in phones.
Umm. Your android probably has such a crap GPS antenna that achieving cm accuracy is impossible. Maybe if you average the position for days.. usually DGPS support is not published and not many chipsets support it. Last time I saw DGPS implemented it involved hacking the actual GPS chip firmware to add support. Even getting A-GPS to work on a random chipset is iffy since they might not support a documented way of feeding the assistance data.
It should be related with the hardware implementation , rather than the software implementation.
In the reality, GPS is usually accompanied with Wi-Fi or 3G to assist in searching the current position.
RTCM correction can be sent to your android phone using NTRIP 'provider'. Then you need to apply it to your raw GPS in your android.