ernesst / ActivityTracker

ActivityTracker app for Ubuntu
GNU General Public License v3.0
6 stars 12 forks source link

Jitters are recorded when switching applications. #33

Open Talkless opened 3 years ago

Talkless commented 3 years ago

My use case is that I use ActivityTracker to record some path, and PureMaps to collect "bookmarks", noting in this way points of interests or other details to be uploaded to OpenStreetMap later.

But issue is that when I switch from PureMaps back to ActivityTracker, I get "jitters" recorded on the map, like this (screenshot from JOSM editor): activity_tracker_jitters

Maybe it' location service issue, as during switch I see that location indicator flashes off/on, so maybe precision is actaully lost, IDK.

Though maybe it would be possible to workaround this issue with (primitive?) heuristics? If application is switched-back, app should get GPS position change event "significantly" (whatever that is) later than expected 5s (if 5000ms is the interval set in app settings) since the last event (before switching applications). Detected as such, this position change event could be ignored, maybe even together with subsequent (and too frequent) ones, as it seems there are "burst" of GPS updates after switching back).

EDIT: this is detected on BQ Aquaris E5.

mymike00 commented 3 years ago

Apps aren't usually allowed to do stuff in the background, due to battery friendly ubuntu touch apps lifecycle. Given that you can try to disable app suspension when in background in the UT Tweak Tool app, but even with that I think the location service will pause if the app in the foreground isn't requesting the gps position. There were some plans to add a better support for apps that need background services, we might wait for that to implemebt background tracking, as it will be an official way to do that

hscheewel commented 3 years ago

While waiting for the implementation of location services in the background you can maybe use Utrack. It works quite well without draining the battery..

Edit: And it automatically imports tracks into the Activity tracker if you want.

Talkless commented 3 years ago

Apps aren't usually allowed to do stuff in the background, due to battery friendly ubuntu touch apps lifecycle....

Yes, I know. I'm am suggesting workaround for this issue, until we get location working in the background (if ever).

Another workaround idea (instead of "guessing" using time itervals) would be to pause recording if GPS precision is too poor. Or detect that app was woken up (using timer intervals) PLUS waiting for precision to return to optimal. Etc, etc.

you can maybe use Utrack.

Thanks for suggestion @hendrikscheewel , but that feels too.. "advanced". I could do that (I am not afraid of terminals & scripting, etc, etc), but.. no :) .

ernesst commented 3 years ago

The original developer set the GPS recording method to high, by using the satellite. https://github.com/ernesst/ActivityTracker/blob/master/qml/Tracker.qml#L104 So from my understanding that shouldn't happen.

In Utrack, i've fix a specific position error to block the recording if the measurement error goes above. However in ActivityTracker this information is not giving to the software, but managed by QT libraries and below. If possible to use this way, It's a significant amount of work for fixing an operating system feature.
It would be more profitable for all the software using the GPS to enable that : https://github.com/ubports/ubuntu-touch/issues/1067

Talkless commented 3 years ago

I've played a bit with ActivityTracker, buit with various changes.

Firstly, I seems that PositionSource.onPositionChanged is called three times on every interval:

qml: PositionSource.onPositionChanged  55.924686666666666 23.336583333333337 5.2
qml: ========================
0.000
qml: PositionSource.onPositionChanged  55.924686666666666 23.336583333333337 5.2
qml: ========================
0.000
qml: PositionSource.onPositionChanged  55.924686666666666 23.336583333333337 5.2
qml: ========================
0.000
qml: PositionSource.onPositionChanged  55.924438333333335 23.336086666666667 6.9
qml: ========================
0.000
qml: PositionSource.onPositionChanged  55.924438333333335 23.336086666666667 6.9
qml: ========================
0.000
qml: PositionSource.onPositionChanged  55.924438333333335 23.336086666666667 6.9

It's rather.. inefficient..? Maybe this is Ubuntu-touch-backed specifics? I mean, application has to perform same calculations tree times. That's battery usage.

Secondly, loggingpoints's Timer.onTriggered is called late and then too soon. If interval is 5000ms, and you swipe to other app and get back, you might get 14000, 2300, and then 5000ms interval. I'll try walking with ActivityTracker to see if ignoring these off-the-time-table events would make these jitters avoided in GPX files.

mymike00 commented 3 years ago

Firstly, I seems that PositionSource.onPositionChanged is called three times on every interval:

Mmh... that's not ActivityTracker fault. We just do some stuff when the signal positionChanged() is emitted. If then the signal is emitted even when the position hasn't changed, that's fault of the backend, QtPositioning or maybe lower, I don't know how the location stack works. But this would need to be reported here

Secondly, loggingpoints's Timer.onTriggered is called late and then too soon. If interval is 5000ms, and you swipe to other app and get back, you might get 14000, 2300, and then 5000ms interval. I'll try walking with ActivityTracker to see if ignoring these off-the-time-table events would make these jitters avoided in GPX files.

Did you disables app suspension when in background? I don't know why a timer would trigger outside its interval...

Talkless commented 3 years ago

Mmh... that's not ActivityTracker fault

Yes, this is comment for the backend / Qt .

If then the signal is emitted even when the position hasn't changed

No, it's when there is a change, that slot is called multiple times for the same change. Basically application performs same calculation multiple times in few milliseconds.

Did you disables app suspension when in background? I don't know why a timer would trigger outside its interval...

Suspencion is left as is, not disabled. Timer triggers not when application is asleep, but when you get back, probably timer events are queued in Kernel and Qt event loop just "plays" them after it is possible (after being resumed). At least that's my guess.

mymike00 commented 3 years ago

No, it's when there is a change, that slot is called multiple times for the same change.

I meant that the first is called when the position changes but when the second and the third are called the position hasn't changed yet...

Suspension is left as is, not disabled.

I guess you can try to disable that and see if it improves

Timer triggers not when application is asleep

Ok, that's right. the app is suspended so timers can't be triggered while in background. But then I'm afraid I haven't understood the timer issue...

Talkless commented 3 years ago

I meant that the first is called when the position changes but when the second and the third are called the position hasn't changed yet...

Well yes, from that point of view. Maybe lat, lon, alt are updated in the backend separately , producing three signals, BUT the .position item is actually updated once, in one go.. somehow. So we get three "fake" signals, while .position is updated actually in one go. Again, this is pure speculation so far.

I guess you can try to disable that and see if it improves

Yeah maybe, but user shouldn't need to "hack" around using some other software that has full OS access, etc, etc...

But then I'm afraid I haven't understood the timer issue...

Let's paraphrase. When you return to ActiviytTracker after some while, you get burst of these queued late timer events, maybe taking not-yet-very-precise coordinates into GPX route, hence, the "jitters".

I've forgot to take a test while walking to/from job yesterday, will try (to not forget) today.

Another idea is to use repeat: false timer instead ignoring too-old-or-too-soon events (queued-up and burst) and restart timer again on every onTriggered manually. This way timer events will not queue-up.