I've been trying to implement a feature to get the correct altitude based on the barometer sensor from Android Galaxy S5 phones. The only problem is, I don't think it is accurate. Based on http://www.whatismyelevation.com on my particular location, it shows that my altitude is around 114 meters. However, on my phone, it shows that it is 210 meters based on the barometer sensor. I am in a tall building, however, but I don't think it is 100 meters tall.
Here is my simple code:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.configure_settings);
context = getApplicationContext();
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensors = mSensorManager.getSensorList(Sensor.TYPE_PRESSURE);
if (sensors.size() > 0)
{
sensor = sensors.get(0);
mSensorManager.registerListener(this, sensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
}
#Override
public void onSensorChanged(SensorEvent event)
{
float pressure = event.values[0];
altitude = String.valueOf(SensorManager.getAltitude(
SensorManager.PRESSURE_STANDARD_ATMOSPHERE, pressure));
}
Thanks!
First: The barometers are very precise, but not accurate. If you place 10 Android phones next to each other on a table, you can find barometric pressure differences of up to 3 mb between devices. This is one source of error.
Second: Different groups will define 'altitude' differently, so make sure you're using the same definitions. For example, in the Location class, getAltitude is defined as
Get the altitude if available, in meters above the WGS 84 reference ellipsoid.
http://developer.android.com/reference/android/location/Location.html#getAltitude()
Third, the weather will affect the reading of the barometer by up to 40 mb. If you want to get a more accurate altitude reading from the barometer, you will have to offset from the current weather. The atmosphere can change the local pressure by up to 1-2 millibars per hour (in extreme cases)
Fourth: it is not yet possible to get a completely accurate altitude reading using the barometer in a smartphone. Nobody has solved this yet - the barometer alone is insufficient to achieve floor-level detection, for example.
I'm the developer of PressureNet, by the way - I have collected over 2 billion pressure readings from smartphones, and I see all these types of errors every day.
In closing: the reading that the barometer delivers to you requires significant interpretation before using, if you want to achieve a value for 'altitude'. Every value that is read from every barometer is 'wrong' by default; you'll have to do specific work to make it work for you, depending on what your exact needs are.
github.com/cbsoftware/pressurenet
The air-pressure sensor of a smartphone-type device has very poor absolute accuracy. I.e. when you are stationary the value read will probably not be equal to what you read from another source.
It is, however, rather good at measuring changes to the air-pressure. So if you read the air-pressure at one altitude and then quickly move to another altitude you will get a fairly accurate measure of the difference in altitude (provided you use the right altitude formula, ex. https://physics.stackexchange.com/questions/333475/how-to-calculate-altitude-from-current-temperature-and-pressure)
I.e. if you know the absolute altitude at one of your locations you can compute a rather accurate value for the other location.
It is also important to remember that air-pressure for any location is variable due to weather changes. In a windy environment you will generally find that values are less accurate unless you do some time-averaging or low-pass filtering of the values.
When it comes to altitude values served by Google, the GPS or other sources they generally refer an altitude for a location to an idealized shape of the earths surface. This shape is typically called a geoid (a spheroid shape that rather closesly resembles the actual shape of our globe). The actual surface of the globe, that be either land or ocean, do deviate in shape from the ideal geoid in most places. For areas that were covered by thick layers of ice during the last ice-age the land may still be 30-50 meters below the geoid reference. More details are found here: https://www.esri.com/news/arcuser/0703/geoid1of3.html.
For normal mapping purposes the altitude is referenced to some form of constant. When close to the sea altitude == 0 at LAT (Lowest Astronomical Tide) and local mapping references to altitude is thus traditionally referenced to this level. Other more 'modern' references are also used. Google, the satellite-based global positioning systems, etc. do not use this reference, hence the altitude you get from them and the altitude you calculate (or read off a map) locally do not generally match.
Just a report for Android 8.1 on Samsung S7 smartphone compared to weather station pressure sensor/algorithms.
Samsung S7 phone=970 millibars
Weather station=1010 millibars (at the same time)
Those are about +/- 2% difference from the arithmetic mean of the two values, 990 millibars.
However, GPS is about 3% error limit for altitude. Within a span of about 5 minutes, consumer grade GPS reports altitude on a hilltop nearby ranged generally from about 1080ft to 1150ft, with isolated readings lower and higher than those. The arithmetic mean is 1115ft, and the lower and upper values are about +/- 3% of the 1115ft value. A National Geodetic Survey map shows the official altitude of the hilltop is 1110ft, which is very close to the mean of the two values.
Related
What are the data needed for calculating barometric altitude? How do I get them and then calculate the altitude?
Also how accurate is the barometric compared to GPS altitude? I tried GPS but after searching hours in the web I cannot find a suitable Geoid library.
Please correct me if I got any concept long.
You need to use the pressure sensor to measure the pressure then use the SensorManager.getAltitude(float, float) call to convert the measures pressure along with a reference sea level pressure to get the altitude.
The tricky bit is what to use as the reference pressure. This will change with the weather and will drift over time. Typically you would do some sort of calibration to set this values and possibly update it. It depends on your use case what the right solution is.
If properly calibrated pressure based altitude is considerably more accurate then gps based altitude especially if want you are interested in is altitude differences rather than absolute altitudes. With a bit of filtering on the raw pressure sensor values you can easily detect holding the phone at face level or arms length above your head which you want do with gps.
The arguments are: GPS altitude (it's good to use average value calculated from array of measurements) and barometric pressure. Method returns pressure at sea level (formula from SensorManager.getAltitude(float p0, float p) in reverse).
public static float getSealevelPressure (float alt, float p)
{
float p0 = (float) (p / Math.pow(1 - (alt/44330.0f), 5.255f));
return p0;
}
I'm using the default value: SensorManager.PRESSURE_STANDARD_ATMOSPHERE until GPS collects 10 locks. After that, the above method is called.
I'm trying to obtain the longitude and latitude positions of existing access points within an indoor environment using Java (Eclipse). I understand that these are needed to complete the triangulation method. I have spoken to the IT team and they're unable to provide me with these readings. However I'm wondering if there's another way to do this?
You will need to work with signal strength. You cannot determine lat. & long. with wifi. It appears that a few iPhone apps leverage triangulation of wifi.
But for outdoor triangulation , the default is GPS.
See this question - Wifi Triangulation
Specifically this answer
If you knew the locations of the access points to within the tolerances required for your application and had a good way to accurately measure the distance between the APs and you had a way to account for signal attenuation between your measurement device and the APs then you could do a little bit of math to solve for where you are.
Java certainly has the mathematical functions you'd need to calculate your location. However, there's a ton of other variables that you would need to account for while triangulating your position from just WiFi access points.
Wifi transmission range usually are in a radius, you have to discover available networks.
You cannot know the exact point where are you, but you can know the area where you are.
If you add the lat & long of the access point, and know the reach of each access point, you can play with sin, cos & tan to accieve the aproximate position.
I am Android developer.
I am getting the longitude and latitude point of a place but for the same place these values changes and the third decimal varies.
My main purpose is to detect a place so it works only
when all these values of longitude and latitude matches so they must
be constant.
My questions are:
What is the reason for this variation?
Is there any method by which ti make these values remain constant for a specific place?
The phone's GPS isn't very accurate. That is, it is very accurate for navigate in your car, but missing by 20 meters is not unheard of.
To figure out if you're in the same place, you should calculate the distance between your current location and the place's coordinates. If it's lower than a threshold (try to find one that makes sense) - you're there.
Try using the GPS for more accurate data, but know that they will not be the same values everytime, but not very different either
You can look at the accuracy as well. The Location class has a getAccuracy() method -- if your accuracy decreased from the last method, it may be that the person went inside and lost line-of-sight to the sky.
As I have said before in other posts, I recommend using Google's Play Location service rather than the pure GPS. You can also use an isBetterLocation method as documented here.
As stated above, the GPS inherent accuracy isn't the best. For an idea of how the decimal places show accuracy levels, see the Wikipedia page
In short, the third decimal place results in an accuracy differential of 43-111 meters, depending on your position on the globe. So I would either look at some other method of refining the data, or implementing some sort of threshold processing.
I would like to implement GPS Tracking service. After a search on the web I'm still a bit confused on the best way to practice this feature.
I want to start following the user when he gets a mile away from his home.
I thought that the app will be installed at user's home and using:
locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
I'll get the user's coordinates and compare it with changing coordinates as he travels.
When the user gets away a mile from his home I'll send SMS messages with his maps location every predefined time interval.
I was wondering if there is someone who done something similar before and can recommend a best practice for this task.
Also, how accurate the GPS can be, and what might be the best practice to get distance?
Thanks in advance.
From my experience it is not a good idea to use GPS all the time to track when a user departs from his home location because it burns the battery in no time. I ended up learning the home location by looking at the cell tower IDs over night (assuming the user is at home then). If you reach a certain level of confidence that you know the user's home location you can ask him something like "Are you at home right now?" to be completely sure (although this is somehow creepy for many users).
If you follow this strategy you can start the GPS if the user connects to a new cell tower and save a lot of battery.
Regarding accuracy. You can get the accuracy provided with each Android.Location object. If you are outside, this is usually 5 or 10 meters. But be aware that there is only an 68% chance this value is correct, according to the documentation:
We define accuracy as the radius of 68% confidence. In other words, if you draw a circle centered at this location's latitude and longitude, and with a radius equal to the accuracy, then there is a 68% probability that the true location is inside the circle.
Be carefull, the getLastKnownLocation method will not necessary return the user home position.
You shoud rather get the current position. Most of the time, getLastKnownLocation is used to get a location quickly (avoiding heavy background work).
GPS accuracy depends on many factors:
Weather, quality of the chip, field, ...
But, most of the time, it's more accurate that the network provider.
Here a very good link : http://developer.android.com/guide/topics/location/strategies.html
You will learn a lot with that.
I need to obtain the velocity of an android device, based on the accelerometer values. I made a code that allows me to get the accelerometer values, and then I calculate the velocity, using the formula:
v = v0 + at. (vector calculation)
My problem is that my velocity only increases and never decreases. I think the problem is that the device never gets an negative acceleration.
Can you help me with this?
Obtaining velocity from the accelerometers might not be possible (forget reliable) because at constant speed there will be no acceleration (other than gravity). You might be better off obtaining GPS location data and their associated time samples and computing velocity by distance over time.
Are you subtracting out the force of gravity? The device is always accelerating -- even if it is just sitting on your desk, it is accelerating at 9.8 m/s^2 away from the center of the Earth.
You can use a combination of the accelerometer and the digital compass, in phones that have them, to determine a speed and direction as mentioned in this post.
If all you need to do is determine if the person is walking, all you need is the accelerometer. Just process its output for foot steps.
There are plenty of tutorials on the web for detecting foot steps with an accelerometer.
There an app note here: http://www.analog.com/library/analogDialogue/archives/41-03/pedometer.html that gives a decent mathematical background and an example algorithm. Its of course up to you to extract the math and rewrite it for Android (the example code is written in C). I don't currently know of an open source android library with a footstep detection algorithm.
If you implement something, I would like to get the code, don't forget to post back the results.