Replace high/low accuracy with omit rests option.

I have been feeling that the high/low accuracy switch is a bit
misleading because while it can help us choose waypoints that
are sufficiently far apart from each other, the accuracy of any
individual waypoint isn't inherently better than normal. However,
the option to omit or keep rests allows the user to keep the raw
data or postprocess it in their own way; or accept the default
different-enough detection.
master
voussoir 2022-04-02 21:45:25 -07:00
parent 981e8806b1
commit 3741d0baf5
No known key found for this signature in database
GPG Key ID: 5F7554F8C26DACCB
7 changed files with 41 additions and 35 deletions

View File

@ -56,7 +56,7 @@ object Keys {
const val PREF_TRACKING_STATE: String = "prefTrackingState"
const val PREF_USE_IMPERIAL_UNITS: String = "prefUseImperialUnits"
const val PREF_GPS_ONLY: String = "prefGpsOnly"
const val PREF_RECORDING_ACCURACY_HIGH: String = "prefRecordingAccuracyHigh"
const val PREF_OMIT_RESTS: String = "prefOmitRests"
const val PREF_ALTITUDE_SMOOTHING_VALUE: String = "prefAltitudeSmoothingValue"
const val PREF_LOCATION_ACCURACY_THRESHOLD: String = "prefLocationAccuracyThreshold"
const val PREF_LOCATION_AGE_THRESHOLD: String = "prefLocationAgeThreshold"

View File

@ -65,6 +65,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
// set up "Restrict to GPS" preference
val preferenceGpsOnly: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context)
preferenceGpsOnly.isSingleLineTitle = false
preferenceGpsOnly.title = getString(R.string.pref_gps_only_title)
preferenceGpsOnly.setIcon(R.drawable.ic_gps_24dp)
preferenceGpsOnly.key = Keys.PREF_GPS_ONLY
@ -74,6 +75,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
// set up "Use Imperial Measurements" preference
val preferenceImperialMeasurementUnits: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context)
preferenceImperialMeasurementUnits.isSingleLineTitle = false
preferenceImperialMeasurementUnits.title = getString(R.string.pref_imperial_measurement_units_title)
preferenceImperialMeasurementUnits.setIcon(R.drawable.ic_square_foot_24px)
preferenceImperialMeasurementUnits.key = Keys.PREF_USE_IMPERIAL_UNITS
@ -110,13 +112,15 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
}
// set up "Recording Accuracy" preference
val preferenceRecordingAccuracy: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context)
preferenceRecordingAccuracy.title = getString(R.string.pref_recording_accuracy_title)
preferenceRecordingAccuracy.setIcon(R.drawable.ic_timeline_24dp)
preferenceRecordingAccuracy.key = Keys.PREF_RECORDING_ACCURACY_HIGH
preferenceRecordingAccuracy.summaryOn = getString(R.string.pref_recording_accuracy_summary_high)
preferenceRecordingAccuracy.summaryOff = getString(R.string.pref_recording_accuracy_summary_default)
preferenceRecordingAccuracy.setDefaultValue(false)
val DEFAULT_OMIT_RESTS = true
val preferenceOmitRests: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context)
preferenceOmitRests.isSingleLineTitle = false
preferenceOmitRests.title = getString(R.string.pref_omit_rests_title)
preferenceOmitRests.setIcon(R.drawable.ic_timeline_24dp)
preferenceOmitRests.key = Keys.PREF_OMIT_RESTS
preferenceOmitRests.summaryOn = getString(R.string.pref_omit_rests_on)
preferenceOmitRests.summaryOff = getString(R.string.pref_omit_rests_off)
preferenceOmitRests.setDefaultValue(DEFAULT_OMIT_RESTS)
// set up "Altitude Smoothing" preference
// val preferenceAltitudeSmoothingValue: SeekBarPreference = SeekBarPreference(activity as Context)
@ -136,8 +140,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
preferenceResetAdvanced.setIcon(R.drawable.ic_undo_24dp)
preferenceResetAdvanced.summary = getString(R.string.pref_reset_advanced_summary)
preferenceResetAdvanced.setOnPreferenceClickListener{
// reset "Recording Accuracy" preference
preferenceRecordingAccuracy.isChecked = false
preferenceOmitRests.isChecked = DEFAULT_OMIT_RESTS
// preferenceAltitudeSmoothingValue.value = Keys.DEFAULT_ALTITUDE_SMOOTHING_VALUE
return@setOnPreferenceClickListener true
}
@ -168,7 +171,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
val preferenceCategoryAdvanced: PreferenceCategory = PreferenceCategory(activity as Context)
preferenceCategoryAdvanced.title = getString(R.string.pref_advanced_title)
preferenceCategoryAdvanced.contains(preferenceRecordingAccuracy)
preferenceCategoryAdvanced.contains(preferenceOmitRests)
// preferenceCategoryAdvanced.contains(preferenceAltitudeSmoothingValue)
preferenceCategoryAdvanced.contains(preferenceResetAdvanced)
@ -184,7 +187,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList
screen.addPreference(preferenceCategoryMaintenance)
screen.addPreference(preferenceDeleteNonStarred)
screen.addPreference(preferenceCategoryAdvanced)
screen.addPreference(preferenceRecordingAccuracy)
screen.addPreference(preferenceOmitRests)
// screen.addPreference(preferenceAltitudeSmoothingValue)
screen.addPreference(preferenceResetAdvanced)
screen.addPreference(preferenceCategoryAbout)

View File

@ -57,7 +57,7 @@ class TrackerService: Service(), SensorEventListener {
var networkProviderActive: Boolean = false
var useImperial: Boolean = false
var gpsOnly: Boolean = false
var accuracyMultiplier: Int = 1
var omitRests: Boolean = true
var currentBestLocation: Location = LocationHelper.getDefaultLocation()
var lastSave: Date = Keys.DEFAULT_DATE
var stepCountOffset: Float = 0f
@ -81,7 +81,7 @@ class TrackerService: Service(), SensorEventListener {
super.onCreate()
gpsOnly = PreferencesHelper.loadGpsOnly()
useImperial = PreferencesHelper.loadUseImperialUnits()
accuracyMultiplier = PreferencesHelper.loadAccuracyMultiplier()
omitRests = PreferencesHelper.loadOmitRests()
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
sensorManager = this.getSystemService(Context.SENSOR_SERVICE) as SensorManager
@ -438,8 +438,8 @@ class TrackerService: Service(), SensorEventListener {
useImperial = PreferencesHelper.loadUseImperialUnits()
}
// preference "Recording Accuracy"
Keys.PREF_RECORDING_ACCURACY_HIGH -> {
accuracyMultiplier = PreferencesHelper.loadAccuracyMultiplier()
Keys.PREF_OMIT_RESTS -> {
omitRests = PreferencesHelper.loadOmitRests()
}
}
}
@ -463,7 +463,7 @@ class TrackerService: Service(), SensorEventListener {
private val periodicTrackUpdate: Runnable = object : Runnable {
override fun run() {
// add waypoint to track - step count is continuously updated in onSensorChanged
val result: Pair<Boolean, Track> = TrackHelper.addWayPointToTrack(track, currentBestLocation, accuracyMultiplier, resumed)
val result: Pair<Boolean, Track> = TrackHelper.addWayPointToTrack(track, currentBestLocation, omitRests, resumed)
// get results
val successfullyAdded: Boolean = result.first
track = result.second

View File

@ -178,10 +178,17 @@ object LocationHelper {
/* Checks if given location is different enough compared to previous location */
fun isDifferentEnough(previousLocation: Location?, location: Location, accuracyMultiplier: Int): Boolean {
fun isDifferentEnough(previousLocation: Location?, location: Location, omitRests: Boolean): Boolean {
// check if previous location is (not) available
if (previousLocation == null) return true
if (previousLocation == null)
{
return true
}
if (! omitRests)
{
return true
}
// location.accuracy is given as 1 standard deviation, with a 68% chance
// that the true position is within a circle of this radius.
// These formulas determine if the difference between the last point and
@ -194,7 +201,7 @@ object LocationHelper {
// With 1*accuracyDelta we have 68% confidence that the points are
// different. We can multiply this number to increase confidence but
// decrease point recording frequency if needed.
return distance > accuracyDelta * accuracyMultiplier
return distance > accuracyDelta
}

View File

@ -101,16 +101,10 @@ object PreferencesHelper {
// return sharedPreferences.getBoolean(Keys.PREF_RECORDING_ACCURACY_HIGH, false)
// }
/* Loads current accuracy multiplier */
fun loadAccuracyMultiplier(): Int {
// load current setting
val recordingAccuracyHigh: Boolean = sharedPreferences.getBoolean(Keys.PREF_RECORDING_ACCURACY_HIGH, false)
// return multiplier based on state
return if (recordingAccuracyHigh) 2 else 1
fun loadOmitRests(): Boolean {
return sharedPreferences.getBoolean(Keys.PREF_OMIT_RESTS, true)
}
// /* Load altitude smoothing value */
// fun loadAltitudeSmoothingValue(): Int {
// // load current setting

View File

@ -41,7 +41,7 @@ object TrackHelper {
private val TAG: String = LogHelper.makeLogTag(TrackHelper::class.java)
/* Adds given locatiom as waypoint to track */
fun addWayPointToTrack(track: Track, location: Location, accuracyMultiplier: Int, resumed: Boolean): Pair<Boolean, Track> {
fun addWayPointToTrack(track: Track, location: Location, omitRests: Boolean, resumed: Boolean): Pair<Boolean, Track> {
// Step 1: Get previous location
val previousLocation: Location?
var numberOfWayPoints: Int = track.wayPoints.size
@ -68,9 +68,11 @@ object TrackHelper {
track.recordingStop = now
// Step 3: Add waypoint, ifrecent and accurate and different enough
val shouldBeAdded: Boolean = (LocationHelper.isRecentEnough(location) &&
LocationHelper.isAccurateEnough(location, Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY) &&
LocationHelper.isDifferentEnough(previousLocation, location, accuracyMultiplier))
val shouldBeAdded: Boolean = (
LocationHelper.isRecentEnough(location) &&
LocationHelper.isAccurateEnough(location, Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY) &&
LocationHelper.isDifferentEnough(previousLocation, location, omitRests)
)
if (shouldBeAdded) {
// Step 3.1: Update distance (do not update if resumed -> we do not want to add values calculated during a recording pause)
if (!resumed) {

View File

@ -96,9 +96,9 @@
<string name="pref_imperial_measurement_units_summary_metric">Currently using metric units (Kilometer, Meter).</string>
<string name="pref_imperial_measurement_units_summary_imperial">Currently using imperial units (Miles, Feet).</string>
<string name="pref_imperial_measurement_units_title">Use Imperial Measurements</string>
<string name="pref_recording_accuracy_summary_high">Waypoints have higher accuracy but are less frequent.</string>
<string name="pref_recording_accuracy_summary_default">Waypoints have lower accuracy but are more frequent.</string>
<string name="pref_recording_accuracy_title">Recording Accuracy</string>
<string name="pref_omit_rests_on">Waypoints will not be recorded if they are too close to the previous waypoint.</string>
<string name="pref_omit_rests_off">All waypoints will be recorded, even while standing still.</string>
<string name="pref_omit_rests_title">Omit points during rests</string>
<string name="pref_report_issue_summary">Report bugs and suggest improvements on GitHub.</string>
<string name="pref_report_issue_title">Report Issue</string>
<string name="pref_reset_advanced_summary">Reset advanced settings to defaults.</string>