begin calculating elevation only if queue is has enough data points (see #99) - (needs testing)

This commit is contained in:
y20k 2021-05-08 21:59:14 +02:00
parent 9f26a30b75
commit d0c93e3124
No known key found for this signature in database
GPG key ID: 824D4259F41FAFF6
3 changed files with 24 additions and 12 deletions

View file

@ -113,6 +113,8 @@ object Keys {
const val DEFAULT_THRESHOLD_LOCATION_AGE: Long = 60000000000L // one minute in nanoseconds
const val DEFAULT_THRESHOLD_DISTANCE: Float = 15f // 15 meters
const val DEFAULT_ZOOM_LEVEL: Double = 16.0
const val MIN_NUMBER_OF_WAYPOINTS_FOR_ELEVATION_CALCULATION: Int = 5
const val MAX_NUMBER_OF_WAYPOINTS_FOR_ELEVATION_CALCULATION: Int = 20
const val ALTITUDE_MEASUREMENT_ERROR_THRESHOLD = 10 // altitude changes of 10 meter or more (per 15 seconds) are being discarded
const val REQUEST_CODE_FOREGROUND = 42

View file

@ -121,8 +121,8 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
preferenceAltitudeSmoothingValue.key = Keys.PREF_ALTITUDE_SMOOTHING_VALUE
preferenceAltitudeSmoothingValue.summary = getString(R.string.pref_altitude_smoothing_value_summary)
preferenceAltitudeSmoothingValue.showSeekBarValue = true
preferenceAltitudeSmoothingValue.min = 5
preferenceAltitudeSmoothingValue.max = 20
preferenceAltitudeSmoothingValue.min = Keys.MIN_NUMBER_OF_WAYPOINTS_FOR_ELEVATION_CALCULATION
preferenceAltitudeSmoothingValue.max = Keys.MAX_NUMBER_OF_WAYPOINTS_FOR_ELEVATION_CALCULATION
preferenceAltitudeSmoothingValue.setDefaultValue(Keys.DEFAULT_ALTITUDE_SMOOTHING_VALUE)

View file

@ -264,6 +264,8 @@ class TrackerService: Service(), CoroutineScope, SensorEventListener {
// save state
trackingState = Keys.STATE_TRACKING_STOPPED
PreferencesHelper.saveTrackingState(this, trackingState)
// reset altitude values queue
altitudeValues.reset()
// stop recording steps and location fixes
sensorManager.unregisterListener(this)
handler.removeCallbacks(periodicTrackUpdate)
@ -533,20 +535,21 @@ class TrackerService: Service(), CoroutineScope, SensorEventListener {
// put current altitude into queue
val currentBestLocationAltitude: Double = currentBestLocation.altitude
if (currentBestLocationAltitude != Keys.DEFAULT_ALTITUDE) altitudeValues.add(currentBestLocationAltitude)
// TODO remove
// uncomment to use test altitude values - useful if testing wirth an emulator
// altitudeValues.add(getTestAltitude()) // TODO remove
//altitudeValues.add(getTestAltitude()) // TODO remove
// TODO remove
// get current smoothed altitude
val currentAltitude: Double = altitudeValues.getAverage()
// calculate and store elevation differences
track = LocationHelper.calculateElevationDifferences(currentAltitude, previousAltitude, track)
// TODO remove
LogHelper.e(TAG, "prev = $previousAltitude | curr = $currentAltitude | pos = ${track.positiveElevation} | neg = ${track.negativeElevation}")
// TODO remove
// only start calculating elevation differences, if enough data has been added to queue
if (altitudeValues.prepared) {
// get current smoothed altitude
val currentAltitude: Double = altitudeValues.getAverage()
// calculate and store elevation differences
track = LocationHelper.calculateElevationDifferences(currentAltitude, previousAltitude, track)
// TODO remove
LogHelper.d(TAG, "Elevation Calculation || prev = $previousAltitude | curr = $currentAltitude | pos = ${track.positiveElevation} | neg = ${track.negativeElevation}")
// TODO remove
}
// save a temp track
val now: Date = GregorianCalendar.getInstance().time
@ -572,8 +575,10 @@ class TrackerService: Service(), CoroutineScope, SensorEventListener {
/* Simple queue that evicts older elements and holds an average */
/* Credit: CircularQueue https://stackoverflow.com/a/51923797 */
class SimpleMovingAverageQueue(var capacity: Int) : LinkedList<Double>() {
var prepared: Boolean = false
private var sum: Double = 0.0
override fun add(element: Double): Boolean {
prepared = this.size + 1 >= Keys.MIN_NUMBER_OF_WAYPOINTS_FOR_ELEVATION_CALCULATION
if (this.size >= capacity) {
sum -= this.first
removeFirst()
@ -582,6 +587,11 @@ class TrackerService: Service(), CoroutineScope, SensorEventListener {
return super.add(element)
}
fun getAverage(): Double = sum / this.size
fun reset() {
this.clear()
prepared = false
sum = 0.0
}
}