/*******************************************************************************
* Gaggle is Copyright 2010 by Geeksville Industries LLC, a California limited liability corporation.
*
* Gaggle is distributed under a dual license. We've chosen this approach because within Gaggle we've used a number
* of components that Geeksville Industries LLC might reuse for commercial products. Gaggle can be distributed under
* either of the two licenses listed below.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Commercial Distribution License
* If you would like to distribute Gaggle (or portions thereof) under a license other than
* the "GNU General Public License, version 2", contact Geeksville Industries. Geeksville Industries reserves
* the right to release Gaggle source code under a commercial license of its choice.
*
* GNU Public License, version 2
* All other distribution of Gaggle must conform to the terms of the GNU Public License, version 2. The full
* text of this license is included in the Gaggle source, see assets/manual/gpl-2.0.txt.
******************************************************************************/
package com.geeksville.location;
import java.util.Observer;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.location.Location;
import android.util.Log;
import com.geeksville.android.PreferenceUtil;
import com.geeksville.util.IIRFilter;
import com.geeksville.util.LinearRegression;
/// FIXME - add a basic vario http://www.paraglidingforum.com/viewtopic.php?p=48465
public class AndroidBarometerClient extends SensorClient implements
IBarometerClient {
private static final String TAG = "BarometerClient";
IIRFilter filter = new IIRFilter();
LinearRegression regression = new LinearRegression();
public float pressure, altitude;
// / Defaults to 1013.25 hPa
private float reference = SensorManager.PRESSURE_STANDARD_ATMOSPHERE;
// / true if we've been set based on the GPS
private Calibration calibration = Calibration.UNCALIBRATED;
private Context context;
//private static BarometerClient instance = null;
public AndroidBarometerClient(Context context) {
super(context, Sensor.TYPE_PRESSURE);
this.context = context;
}
public String getStatus() {
return "int.";
}
/*
* (non-Javadoc)
*
* @see
* com.geeksville.location.IBarometerClient#addObserver(java.util.Observer)
*/
@Override
public synchronized void addObserver(Observer observer) {
// TODO Auto-generated method stub
super.addObserver(observer);
// 0.20 is a little too noisy,
// 0.05 is too stable
float damp = PreferenceUtil.getFloat(context, "averaging_percentage2",
0.10f);
filter.setDampingFactor(damp);
long xspan = (long) (PreferenceUtil.getFloat(context,
"integration_period2", 0.7f) * 1000);
regression.setXspan(xspan);
Log.d(TAG, "Setting damp=" + damp + " xspan=" + xspan);
}
// / If we've been calibrated, override the GPS provided altitude with our
// baro based alt
public void improveLocation(Location l) {
if (calibration != Calibration.UNCALIBRATED)
l.setAltitude(altitude);
}
// / Given a GPS based altitude, reverse engineer what the correct reference
// pressure is
/*
* (non-Javadoc)
*
* @see com.geeksville.location.IBarometerClient#setAltitude(float)
*/
@Override
public void setAltitude(float meters, Calibration calibration) {
// float p0 = 1013.25f; // Pressure at sea level (hPa)
// float p = p0 * (float) Math.pow((1 - meters / 44330), 5.255);
float p0 = pressure / (float) Math.pow((1 - meters / 44330), 5.255);
reference = p0;
altitude = SensorManager.getAltitude(reference, pressure);
Log.w(TAG, "Setting baro reference to " + reference + " alt=" + meters);
this.calibration = calibration;
regression.clearSamples();
}
static boolean isAvailable() {
return sensorMan.getSensorList(Sensor.TYPE_PRESSURE).size() > 0;
}
// / Return altitude in meters
/*
* (non-Javadoc)
*
* @see com.geeksville.location.IBarometerClient#getAltitude()
*/
@Override
public float getAltitude() {
return altitude;
}
public float getPressure() {
return pressure;
}
public float getBattery() {
return Float.NaN;
}
public float getBatteryPercent() {
return Float.NaN;
}
public Calibration getCalibration() {
return calibration;
}
// / In m/s
/*
* (non-Javadoc)
*
* @see com.geeksville.location.IBarometerClient#getVerticalSpeed()
*/
@Override
public float getVerticalSpeed() {
return (float)(regression.getSlope() * 1000);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Auto-generated method stub
}
// / We want to sample _every_ baro reading we see
@Override
protected void fullRateSensorChanged(float[] values) {
filter.addSample(values[0]);
pressure = filter.get();
altitude = SensorManager.getAltitude(reference, pressure);
regression.addSample(System.currentTimeMillis(), altitude);
super.fullRateSensorChanged(values);
}
@Override
public void onThrottledSensorChanged(float[] values) {
setChanged();
notifyObservers(pressure);
}
}