2026-03-27
Trail Sense's sea level calibration algorithm can be used to improve offline weather forecasting by providing a cleaner barometric pressure signal that is adjusted for the user's elevation. Because barometric pressure varies with altitude, raw measurements from a smartphone's sensors can be inaccurate when the user is changing elevation, so a calibration procedure is needed.
Many modern smartphones contain a barometer to measure atmospheric pressure. This sensor was originally added to smartphones to enable faster GPS locks, but it can have other uses today.[1] Barometers can also be used for short-term weather forecasting by sensing the movement of weather fronts via changes in pressure.[2] However, pressure also changes when the altitude of the sensor changes, which can obscure the pressure changes caused by weather fronts. To combat this, the pressure can be converted to sea level using the barometric formula. The conversion requires an elevation reading, which can be obtained using the GPS sensor.
GPS-derived elevation readings are subject to significant noise, which can degrade the accuracy of sea level-corrected pressures. Additional processing techniques are required to make this reading usable. GPS elevations on Android are returned in meters above the WGS84 reference ellipsoid and can be converted to mean sea level (MSL) using a geoid model.[3] [4]
To reduce the noise in GPS elevation data, multiple readings can be combined using a joint Gaussian filter. This filter considers the elevation value and how accurate Android reports it to be to construct a better estimate of the actual elevation. The algorithm is as follows:
def join(mean1, var1, mean2, var2):
joint = mean1 * var2 + mean2 * var1
sumVar = var1 + var2
multVar = var1 * var2
mean = joint / sumVar
var = multVar / sumVar
return (mean, var)
def join_all(dists):
if len(dists) == 0:
return None
last = dists[0]
for dist in dists[1:]:
last = join(last[0], last[1], dist[0], dist[1])
return last
In addition to filtering, the elevation needs to be converted to be relative to MSL. This requires a geoid model, which is essentially a map of latitude and longitude to a correction factor. Trail Sense ships this as an image where X is longitude, Y is latitude, and the red channel contains a normalized offset amount. The red pixel value is read for the given location and scaled/shifted by a predefined constant to map it to meters. This value is added to the GPS elevation to convert it to MSL.
Trail Sense also offers the option to use a digital elevation model (DEM) instead of the GPS. The DEM can obtain the elevation given a latitude and longitude. This model is a lot less noisy than the GPS, but the resolution is very coarse, so rugged terrain may not work well.
Once a somewhat accurate MSL elevation is obtained, the pressure readings can be converted to sea level pressure using the following formula:
P * (1 - D / 44330.0)^(-5.255)
where P is the pressure in hPa and D is the MSL elevation in meters.[5]
Despite the filtering done to the GPS elevation, it still has a lot of residual noise, which means the sea level pressures are inaccurate. To improve the estimate, Trail Sense records the sea level pressure at a fixed interval (default 30 minutes) and then smooths the time series data. It uses the LOESS algorithm, which applies a weighted least squares regression to smooth the data (span of 0.15, 1 robustness interval).[6] This algorithm was easy to implement, fast to run, and produced decent results.
There are no quantitative results for this algorithm, but users have provided positive feedback that it has accurate detection of storms and is generally within 1 hPa of local weather stations.