Resending to list. On Thu, May 10, 2012 at 10:32 PM, Jeffrey Brown <jeffbrown@xxxxxxxxxxx> wrote: > I have tackled this problem in Android and it's a real nuisance. As far as > I can tell, the vast majority of drivers don't use ABS_MT_TOUCH_MAJOR / > MINOR or ABT_MT_WIDTH_MAJOR / MINOR correctly. > > The drivers should be applying a transformation to the hardware reported > 'width' or 'area' measurements so that they can be reported up to user space > in terms of surface units. > > There are two common transformations that may need to be applied. > > 1. Width values typically need linear scaling sometimes with a bias > constant. eg. out = width * scale + bias. The scale adapts linear width > measurements to surface units. The bias is typically zero but some devices > have a measurement floor. > > 2. Area values typically need inverse quadratic scaling. Taking the > assumption that the contact is circular, obtain a nominal width (diameter) > using the square root. Thus we have the relation: out = sqrt(area) * scale > + bias. > > It is easy to determine which of the two schemes to apply by observing the > relation between reported width or area (in unknown device specific units, > possibly sensor cell sizes) versus physical size (in millimeters). When > plotted, look for the linear or quadratic relation and choose accordingly. > > (I have yet to find a touch controller that uses the same units to report > size as it uses for position.) > > I often use coins as benchmark test objects of known size. Dimes, nickels, > quarters, dollars... (I wish I had some standard probes of various sizes.). > It is a good idea to get a range of objects of different sizes, particularly > in the 6-16mm range. > > Special considerations: > > 1. Some devices do not report the individual size of each contact > correctly. They may report a value that is a sum of the total area > covered. A simple expedient is to divide the raw reported width or area by > the number of contacts for these devices. > > 2. Size measurement is by necessity an approximation. Laying a finger flat > may distribute the contact area over an elongated region. Often the device > does not report enough information to tell what is going on, so we often > must make the assumption that the contact is round. > > 3. The orientation vector reported by some devices can provide information > about the extent to which the contact is elongated in one direction or > another. By combining this information with the overall area measurement we > can estimate appropriate values for MAJOR and MINOR that capture the > distribution. > > 4. The resolution field in the absinfo structure rarely seems to be > populated. It would be very useful if it were so that applications could > get a sense of the relation between surface units and physical dimensions. > It is often more useful to know that a screen is 80mm wide or a touch is > 18mm wide than it is to know how many pixels that represents. > > I believe it would be very beneficial for the community to pull together and > fix drivers that currently report size incorrectly. I would dearly love to > delete the code I have in Android that compensates for this problem using > input device configuration files in user space... > > Jeff. > > On May 9, 2012 12:14 PM, "Jason Gerecke" <killertofu@xxxxxxxxx> wrote: >> >> On Thu, Mar 15, 2012 at 8:22 PM, Chris Bagwell <chris@xxxxxxxxxxxxxx> >> wrote: >> > On Thu, Mar 15, 2012 at 7:10 PM, Jason Gerecke <killertofu@xxxxxxxxx> >> > wrote: >> >> On Mon, Mar 12, 2012 at 3:41 PM, Chris Bagwell <chris@xxxxxxxxxxxxxx> >> >> wrote: >> >>> On Fri, Mar 9, 2012 at 5:26 PM, Jason Gerecke <killertofu@xxxxxxxxx> >> >>> wrote: >> >>>> On Fri, Mar 9, 2012 at 2:30 PM, Chris Bagwell <chris@xxxxxxxxxxxxxx> >> >>>> wrote: >> >>>>> On Wed, Mar 7, 2012 at 7:39 PM, Jason Gerecke <killertofu@xxxxxxxxx> >> >>>>> wrote: >> >>>>>> 3rd-gen Bamboo devices report both "amplitude" and "size" data >> >>>>>> in their touch packets. This patch changes the source for >> >>>>>> ABS_MT_TOUCH_MAJOR to be the latter rather than the former. >> >>>>>> --- >> >>>>>> drivers/input/tablet/wacom_wac.c | 2 +- >> >>>>>> 1 files changed, 1 insertions(+), 1 deletions(-) >> >>>>>> >> >>>>>> diff --git a/drivers/input/tablet/wacom_wac.c >> >>>>>> b/drivers/input/tablet/wacom_wac.c >> >>>>>> index d0b0fc4..5daf11d 100644 >> >>>>>> --- a/drivers/input/tablet/wacom_wac.c >> >>>>>> +++ b/drivers/input/tablet/wacom_wac.c >> >>>>>> @@ -916,7 +916,7 @@ static void wacom_bpt3_touch_msg(struct >> >>>>>> wacom_wac *wacom, unsigned char *data) >> >>>>>> if (touch) { >> >>>>>> int x = (data[2] << 4) | (data[4] >> 4); >> >>>>>> int y = (data[3] << 4) | (data[4] & 0x0f); >> >>>>>> - int w = data[6]; >> >>>>>> + int w = data[5]; >> >>>>>> >> >>>>>> input_report_abs(input, ABS_MT_POSITION_X, x); >> >>>>>> input_report_abs(input, ABS_MT_POSITION_Y, y); >> >>>>>> -- >> >>>>>> 1.7.9.1 >> >>>>>> >> >>>>> >> >>>>> I found time to test this patch and used "mtview" so I could get >> >>>>> some >> >>>>> visual feedback. >> >>>>> >> >>>>> The lines because extremely thin with this change. Part of reason I >> >>>>> quickly traced to we are setting range as 0-255 but I couldn't get >> >>>>> data[5] to go above a value of 18. So I changed range to 0-16 and >> >>>>> it >> >>>>> works better but the lines still never gets very thick (this could >> >>>>> well be that mtview doesn't scale values and prefers 0-255. I >> >>>>> didn't >> >>>>> look). >> >>>> Looks like its a combination of two problems, one mine one >> >>>> mtview's... >> >>>> >> >>>> I did some reading, and the MT protocol docs specify that >> >>>> ABS_MT_TOUCH_MAJOR are in terms of surface units. That means a value >> >>>> of e.g. "20" should represent a touch that spans 20 units of X. The >> >>>> touch sensor has a resolution of ~0.1mm, which would imply the touch >> >>>> was only 2 mm wide... There's going to have to be a correction factor >> >>>> to transform the value to something more appropriate. >> >>>> >> >>>> As for mtview, it looks like it doesn't scale the major/minor axis >> >>>> values based on the output size. At the very least it should scale >> >>>> everything by roughly (output_max_x / sensor_max_x) so that a touch >> >>>> taking up e.g. 10% of the tablet would take up 10% of the output. >> >>> >> >>> I see now that I got lucky that I had a 0-255 value available and >> >>> didn't look into what I needed to report close enough. >> >>> >> >>>> >> >>>>> >> >>>>> Amplitude feels better to me using test apps but your in a better >> >>>>> position to say if we should really change this. Please adjust >> >>>>> declared range though if you still think we should change this. >> >>>>> >> >>>>> Chris >> >>>> >> >>>> My main reasons for switching away from amplitude were that amplitude >> >>>> is a very crude number (I think I can get three or four unique values >> >>>> out of it), and that the tablet reports a size already. Worst case -- >> >>>> assuming a correction factor isn't sufficient to get data[5] working >> >>>> as MAJOR -- we should at least send data[5] through PRESSURE (which >> >>>> the MT docs state may be used instead of MAJOR/MINOR if the units are >> >>>> arbitrary). >> >>>> >> >>> >> >>> I've not found time to dig deeply to this (to compute real scale >> >>> value) but I'll offer this. I compared behaviour of original data[6] >> >>> to this: >> >>> >> >>> int w = (data[5] > 31) ? 255 : data[5] << 3; >> >>> >> >>> and with mtview the size change is much more responsive and >> >>> consistent. So I'm on board with changing to data[5] in some form. >> >>> >> >>> Chris >> >> >> >> I did a little more testing, and it looks like data[5] is proportional >> >> to the area (not linear dimension) of the touch. Given the intended >> >> semantics (and ignoring the huge blobs it produces in mtview), >> >> int_sqrt(data[5] << 13) seems to work well. We'd probably have to >> >> increase the maximum to 512 or 1024 though since I've been able to get >> >> my palm to produce values of ~600... >> >> >> >> Also, I don't yet know how these values scale between tablet sizes -- >> >> I imagine smaller tablets produce larger values (since their sensors >> >> are denser), but haven't been able to get my hands on other hardware >> >> yet. >> >> >> > >> > You've already given it much more thought than I but I made the >> > following assumption a little bit related. The sensors report X/Y >> > maximums of 4096 even though its a rectangle tablet. Thats why I made >> > sure resolution was reported proportionally. Here is from Xorg log of >> > my medium size tablet: >> > >> > (--) Wacom Wireless Receiver Finger pad: Wacom Unknown USB tablet >> > maxX=4096 maxY=4096 maxZ=0 resX=18000 resY=29000 >> > >> > I suspect that same ratio also applies to width reporting as well. >> > >> > I'm also guessing the value of size is really defining an ellipse with >> > fixed orientation. But we can't really expose that to user as >> > WIDTH_MINOR because it will be incorrectly interrupted as a pressure >> > estimate. >> > >> > But I suspect the above resolution calculation will help push the >> > scaling issue to user land and we can concentrate on reporting >> > something like the int_sqrt() values you've come up with. >> > >> > Chris >> >> Whoops. Looks like this fell off my radar. >> >> So, if I were to adjust the uncorrected width by the aspect ratio to >> get values for ABS_MT_TOUCH_MAJOR and ABS_MT_TOUCH_MINOR, would that >> be correct? For example, should placing a quarter (diameter of >> 24.26mm) on my Intuos5 Medium (logical size: 4096 x 4096, physical >> size: 223mm x 139mm) ideally report a contact with a MAJOR axis of 714 >> and MINOR axis of 445? > > Quarters are great aren't they? ;-) > > Foil wrapped pencils and conductive metal rods work well too. Low tech > solutions to high tech problems... > >> >> Jason >> >> --- >> Day xee-nee-svsh duu-'ushtlh-ts'it; >> nuu-wee-ya' duu-xan' 'vm-nvshtlh-ts'it. >> Huu-chan xuu naa~-gha. >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-input" in >> the body of a message to majordomo@xxxxxxxxxxxxxxx >> More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html