linux-surface / iptsd

Userspace daemon for Intel Precise Touch & Stylus
GNU General Public License v2.0
86 stars 39 forks source link

iptsd performs weirdly at edge cases #142

Closed curioxide closed 9 months ago

curioxide commented 9 months ago

If the the size of the touch‘s pixels oscillatings around the NeurtralValue + ActivationThreshold (or the DeactivationThreshold I'm not quite sure)(Neutral set to constant), it will constantly triger touches and the other figures like SizeThreshold and SizeMin can not control this anomaly. My device is surface pro 8 running arch with latest surface-kernel and iptsd-1.3.2 and this phenomenon happens more significantly on Android x86. It's not a big issue just sometimes annoying because it will occasionally cause double taps when touching the screen or an unexpected touch when lifting the finger off the screen.

StollD commented 9 months ago

What values are you changing exactly in the config? And what are you trying to do? Get rid of ghost touches?

To get rid of ghost touches you should try raising the ActivationThreshold. Start with something like 30, if you still have ghost touches, increase it a bit more, if iptsd starts missing contacts, decrease it a bit.

Please don't modify the Neutral option unless you are 100% sure what you are doing. Neutral = mode is the correct operation.

curioxide commented 9 months ago

It's not ghost touch and it's more like when putting a finger on the screen very softly and slowly apply pressure, it will reach a point that very very small changes in size will trigger a touch event and this touch event can not be eliminated by SizeThreshold neither SizeMin. I changed Neutral and NeutralValue just to find where the point is and it seems to be when the blob detection starts. I tried higher ActivationThreshold but that's not helpful.

curioxide commented 9 months ago

dumped.zip I dumped logs on BlissOS which is a Android x86 and configurations are all default except for OrientationThresholdMax, maybe this would help.

StollD commented 9 months ago

iptsd-142.webm

This is definitly a threshold issue. You need to decide what to do here:

You can generate a video yourself with this:

$ iptsd-plot dumped.bin out
$ ffmpeg -r 100 -i out/%05d.png out.webm
curioxide commented 9 months ago

OK I will try it

StollD commented 9 months ago

iptsd-142-30.webm

Thats with ActivationThreshold = 30 like I recommended before.

curioxide commented 9 months ago

The plotting tool seems not built by default and I am sorry that I don't know how to build it.

With higher value like 30 and even 60 or lower value like 5, this problem exists and only the trigger size differs.

Another problem: why can't the other value like SizeThresholdMin control the situation, doesn't the procedure work like firstly we mark the pixels as a contact and try to determine its size and then if the size doesn't increase to the value set by SizeThresholdMin in a limited time, we'll drop this contact. Because the size of my touch almost unchanges when the situation appears.

changed-value.zip

StollD commented 9 months ago

The plotting tool seems not built by default and I am sorry that I don't know how to build it.

Ah yeah, its probably too complicated to build it on Android.

With higher value like 30 and even 60 or lower value like 5, this problem exists and only the trigger size differs.

Okay, stupid question, but how do you apply the settings? Maybe iptsd isn't even reading the value in the first place.

Can you try setting it to 256? That should disable touch entirely. If using the touchscreen is still possible after that and a reboot, then iptsd is not reading your config file.

Another problem: why can't the other value like SizeThresholdMin control the situation, doesn't the procedure work like firstly we mark the pixels as a contact and try to determine its size and then if the size doesn't increase to the value set by SizeThresholdMin in a limited time, we'll drop this contact. Because the size of my touch almost unchanges when the situation appears.

We don't use temporal properties for contact validation, because a simple check for size and aspect ratio is easier and way more robust. A contact doesn't have to move or change its size, in fact this is what we want, because it prevents jitter.

iptsd is really simple: ActivationThreshold and DeactivationThreshold filter noise, SizeMin, SizeMax, AspectMin and AspectMax filter palms (and more noise), the *ThresholdMin entries filter jitter, and the *ThresholdMax entries try to protect against edge cases (e.g. contacts jumping around).

changed-value.zip

FYI, the dumping tool stores the raw data, before any processing. The config file isn't relevant for it, so changing a config value won't change its output.

Also, because I am not really sure right now, I'm gonna ask: This is actually you touching the device, right? Or is this noise and you are not actually doing anything?

If it is not noise: How hard are you pressing on the display? Just barely, or full send / normally?

Also, I will ask again: What do you want iptsd to do? Drop the contact? Or recognize it in a stable way?

curioxide commented 9 months ago

Setting to 256 did disabled touch even after a reboot.

I am literally touching the screen very softly with default ActivationThreshold value and a little more pressure with higher value and a little less with lower value.

Drop it or recognize it are both OK. On android it acts like constant taps on the screen so I just want it recognized as a hold on screen or just dropped. It feels like we need a buffer here.

StollD commented 9 months ago

Setting to 256 did disabled touch but after reboot the touch works, and if I set it to 256 again, the touch will be disabled as the same.

That kinda sounds like iptsd isn't starting automatically and you are getting the fallback singletouch implementation by the kernel driver.

I am literally touching the screen very softly with default ActivationThreshold value and a little more pressure with higher value and a little less with lower value.

You are compensating the change of the config option by pressing harder? That just means you will always get the same behaviour.

The instability you are triggering by this is an edge case. It is impossible to fix the edge case, because there needs to be an edge, between "contact" and "no contact". The only thing you can do is move this edge, so that it doesn't impact normal use.

If you get ghost touches in normal use, without trying to make them happen, raise the ActivationThreshold and continue using it like you did before. Don't adapt your usage to the new value.

StollD commented 9 months ago

The instability you are triggering by this is an edge case. It is impossible to fix the edge case, because there needs to be an edge, between "contact" and "no contact". The only thing you can do is move this edge, so that it doesn't impact normal use.

For example what iptsd could do is detect when a blob got dropped and then mark that area as tainted until the pixels have returned to the neutral value to make sure the finger is off the display. We already temporally track blobs, so its not impossible. But thats just moving the edge from the activation threshold to the neutral value, where it will be much more sensitive to noise. Its still sampled analog data (electric resistance on different parts of the screen).

curioxide commented 9 months ago

Quite curious about how other touch device like iphone or android phone handle this edge situation because it never happens on those devices, at least for me.

curioxide commented 9 months ago

Mayde I should close this issue. Sorry for bothering and thank you so much for answering me.

StollD commented 9 months ago

Quite curious about how other touch device like iphone or android phone handle this edge situation because it never happens on those devices, at least for me.

A combination of multiple things I guess:

Its also not totally absent on commercial devices: https://www.reddit.com/r/fairphone/comments/142tm4n/ghost_input_at_bottom_of_screen_anyone_else_had/

And by buffer I mean that we may set a release threshold which is lower than ActivationThreshold and activates only after a contact is registried on screen and if the contact's size reduces below the release threshold then the contact can be seen as released.

Hmm, yeah that would be possible. It would require moving the contact tracking into the blob detector, searching for blobs by this new DropThreshold instead of ActivationThreshold, and then removing those blobs that are not in the last frame and below the ActivationThreshold.

What I don't really understand is how it would interact with the DeactivationThreshold. Probably Activation > Drop > Deactivation?

If you are curious, this is how it currently searches for blobs (or clusters): https://github.com/linux-surface/iptsd/blob/master/src/contacts/detection/algorithms/cluster.hpp#L109-L115

I would be curious to see this implemented actually and whether it would change anything, e.g. for my usage. Because I honestly can't tell. IMHO, normal use causes values that are so large, that the amount of frames where you are near the activation threshold should be minimal. For me, pixels usually turn white, so at least 80 or 100 points away from the neutral value. And I wouldn't consider my fingers that big.

Mayde I should close this issue. Sorry for bothering and thank you so much for answering me.

Don't worry :)

I'm always open to suggestions on how to improve the algorithms, especially because I don't really understand them. I only combined multiple working solutions into one that works a bit better. @qzed did most of the theoretical work. I can tell you what it does, but I can't tell you why or how.

And thats kinda the same reason why I am so stubbornly invested in simple algorithms: I can only maintain what I understand.

qzed commented 9 months ago

I can tell you what it does, but I can't tell you why or how.

To be fair, a great deal of that was also just me trying things out to see what works and how stuff could be combined to improve things.