Re: [PATCH] iio/hid: Add mount_matrix

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 6/25/22 14:33, Hans de Goede wrote:
> Hi,
> 
> Jonathan, thanks for Cc-ing me on this.
> 
> On 6/25/22 13:09, Jonathan Cameron wrote:
>> On Fri, 24 Jun 2022 15:33:41 -0700
>> Gwendal Grignou <gwendal@xxxxxxxxxxxx> wrote:
>>
>>> ISH based sensors do not naturally return data in the W3C 'natural'
>>> orientation.
>>> They returns all data inverted, to match Microsoft Windows requirement:
>>> [https://docs.microsoft.com/en-us/windows/uwp/devices-sensors/sensors#accelerometer]
>>> """ If the device has the SimpleOrientation of FaceUp on a table, then
>>> the accelerometer would read -1 G on the Z axis. """
>>
>> Probably reference the HID Usage Tables 1.3 spec rather than the MS one.
>> https://usb.org/sites/default/files/hut1_3_0.pdf
>> After some waving around of my left and right hand I'm fairly sure that says the same
>> thing as the MS spec. Section 4.4 Vector Usages 
>>
>>> While W3C defines [https://www.w3.org/TR/motion-sensors/#accelerometer-sensor]
>>> """The Accelerometer sensor is an inertial-frame sensor, this means that
>>> when the device is in free fall, the acceleration is 0 m/s2 in the
>>> falling direction, and when a device is laying flat on a table, the
>>> acceleration in upwards direction will be equal to the Earth gravity,
>>> i.e. g ≡ 9.8 m/s2 as it is measuring the force of the table pushing the
>>> device upwards."""
>>>
>>> Fixes all HID sensors that defines IIO_MOD_[XYZ] attributes.
>>>
>>> Tested on "HP Spectre x360 Convertible 13" and "Dell XPS 13 9365".
>>>
>>> Signed-off-by: Gwendal Grignou <gwendal@xxxxxxxxxxxx>
>>
>> Ah.  Whilst this is a fix, it seems likely to break a whole bunch of existing
>> users that are compensating for the wrong orientation in userspace.  Also, do
>> we know how universal this is?  I have a nasty feeling it'll turn out some
>> HID sensors do it the other way whatever the spec says.  Bastien, are you
>> carrying a local fix for this in your userspace code?
>>
>> +CC a few people who are likely to know more on just how bad that will be...
> 
> Right, so Linux userspace expects an axis system similar to the Android one,
> which is actually the one which seems to be described here.
> 
> The axis system expect is that when a tablet is layed flat on the table,
> the x and y axis are as one would expect when drawing a mathematics
> graph on the surface of the tablet.
> 
> So X-axis goes from left to right, with left side being lower numbers and
> right side higher numbers.
> 
> And Y-axis goes from bottom to top, with the bottom being lower numbers and
> the top higher numbers.
> 
> That leaves the Z-axis which comes out of the screen at a 90° angle (to both
> the X and Y axis) and the vector coming out of the screen towards to the user /
> observer of the screen indicates positive numbers where as imagining the same
> axis pointing down through the table on which the tables is lying towards
> the floor represents negative numbers.
> 
> This means that the accel values of a tablet resting on a table, expresses
> in units of 1G are: [ 0, 0, -1 ] and I've seen quite a few HID sensors
> with accel reporting on various devices and they all adhere to this
> without applying any accel matrix. Or in other words, HID sensors behave
> as expected by userspace when applying the norm matrix of:
> 
> 	.rotation = {
> 		"1", "0", "0",
> 		"0", "1", "0",
> 		"0", "0", "1"
> 
> And this patch will cause the image to be upside down (no matter what the
> rotation) when using auto-rotation with iio-sensor-proxy.
> 
> So big NACK from me for this patch.
> 
> I'm not sure what this patch is trying to fix but it looks to me like it
> is a bug in the HID sensors implementation of the specific device.
> 
> Again HID-sensors already work fine on tons of existing devices without
> any matrix getting applied.
> 
> Merging this patch would break existing userspace on tons of devices!

p.s.

Also I must say that the W3C specification is frankly
quite silly. The are talking about the counter force of the
table but that cancels out the actual  acceleration force of
the gravity, resulting in an effective force of 0.

Take away the table and the tablet would accelerate
at 9.8 m/s² towards the earth, so down, so -1 G .

The HID / Android (and AFAIK also Windows) definitions of the
sensor axis are much more sensible.

If chromeos / chrome the browser wants to report accel values
to web-apps in the silly W3C format then any conversion matrix
for that should be applied inside chrome-the-browser.

Note that this suggested patch would like also break the
accel values of the Android-compatibility inside Chrome OS!!

Regards,

Hans




> 
> Regards,
> 
> Hans
> 
> 
> 
> 
> 
>>
>> One other thing inline.  The mount matrix you've provided isn't a rotation matrix.
>>
>> I'd forgotten the annoyance of graphics folks using the right handed sensor
>> axis whilst nearly all other uses are left handed. It drove me mad many years
>> ago - every code base that used sensors and rendered the result needed a
>> flip of the z axis - it was never well documented, so half the time
>> the code ended up with many axis flips based on people debugging local
>> orientation problems.  *sigh*
>>
>>
>>> ---
>>>  drivers/iio/accel/hid-sensor-accel-3d.c       |  3 +++
>>>  .../hid-sensors/hid-sensor-attributes.c       | 21 +++++++++++++++++++
>>>  drivers/iio/gyro/hid-sensor-gyro-3d.c         |  3 +++
>>>  drivers/iio/magnetometer/hid-sensor-magn-3d.c |  3 +++
>>>  include/linux/hid-sensor-hub.h                |  2 ++
>>>  5 files changed, 32 insertions(+)
>>>
>>> diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
>>> index a2def6f9380a3..980bbd7fba502 100644
>>> --- a/drivers/iio/accel/hid-sensor-accel-3d.c
>>> +++ b/drivers/iio/accel/hid-sensor-accel-3d.c
>>> @@ -59,6 +59,7 @@ static const struct iio_chan_spec accel_3d_channels[] = {
>>>  		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>>>  		BIT(IIO_CHAN_INFO_HYSTERESIS),
>>>  		.scan_index = CHANNEL_SCAN_INDEX_X,
>>> +		.ext_info = hid_sensor_ext_info,
>>>  	}, {
>>>  		.type = IIO_ACCEL,
>>>  		.modified = 1,
>>> @@ -69,6 +70,7 @@ static const struct iio_chan_spec accel_3d_channels[] = {
>>>  		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>>>  		BIT(IIO_CHAN_INFO_HYSTERESIS),
>>>  		.scan_index = CHANNEL_SCAN_INDEX_Y,
>>> +		.ext_info = hid_sensor_ext_info,
>>>  	}, {
>>>  		.type = IIO_ACCEL,
>>>  		.modified = 1,
>>> @@ -79,6 +81,7 @@ static const struct iio_chan_spec accel_3d_channels[] = {
>>>  		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>>>  		BIT(IIO_CHAN_INFO_HYSTERESIS),
>>>  		.scan_index = CHANNEL_SCAN_INDEX_Z,
>>> +		.ext_info = hid_sensor_ext_info,
>>>  	},
>>>  	IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP)
>>>  };
>>> diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
>>> index 9b279937a24e0..e367e4b482ef0 100644
>>> --- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
>>> +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
>>> @@ -585,6 +585,27 @@ int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev,
>>>  }
>>>  EXPORT_SYMBOL_NS(hid_sensor_parse_common_attributes, IIO_HID);
>>>  
>>> +static const struct iio_mount_matrix hid_sensor_windows_axis = {
>>> +	.rotation = {
>>> +		"-1", "0", "0",
>>> +		"0", "-1", "0",
>>> +		"0", "0", "-1"
>>
>> Unless my memory of rotation matrices serves me wrong, that's not a rotation matrix.
>> (det(R) != 1)
>>
>> That's a an axis flip from a right handed set of axis to a left handed one.
>> So to fix this up, you would need to invert the raw readings of at least one axis
>> rather than rely on the mount matrix or make the scale negative.
>>
>> Jonathan
>>
>>
>>> +	}
>>> +};
>>> +
>>> +static const struct iio_mount_matrix *
>>> +hid_sensor_get_mount_matrix(const struct iio_dev *indio_dev,
>>> +				const struct iio_chan_spec *chan)
>>> +{
>>> +	return &hid_sensor_windows_axis;
>>> +}
>>> +
>>> +const struct iio_chan_spec_ext_info hid_sensor_ext_info[] = {
>>> +	IIO_MOUNT_MATRIX(IIO_SHARED_BY_TYPE, hid_sensor_get_mount_matrix),
>>> +	{ }
>>> +};
>>> +EXPORT_SYMBOL(hid_sensor_ext_info);
>>> +
>>>  MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@xxxxxxxxx>");
>>>  MODULE_DESCRIPTION("HID Sensor common attribute processing");
>>>  MODULE_LICENSE("GPL");
>>> diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c b/drivers/iio/gyro/hid-sensor-gyro-3d.c
>>> index 8f0ad022c7f1b..b852f5166bb21 100644
>>> --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
>>> +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
>>> @@ -58,6 +58,7 @@ static const struct iio_chan_spec gyro_3d_channels[] = {
>>>  		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>>>  		BIT(IIO_CHAN_INFO_HYSTERESIS),
>>>  		.scan_index = CHANNEL_SCAN_INDEX_X,
>>> +		.ext_info = hid_sensor_ext_info,
>>>  	}, {
>>>  		.type = IIO_ANGL_VEL,
>>>  		.modified = 1,
>>> @@ -68,6 +69,7 @@ static const struct iio_chan_spec gyro_3d_channels[] = {
>>>  		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>>>  		BIT(IIO_CHAN_INFO_HYSTERESIS),
>>>  		.scan_index = CHANNEL_SCAN_INDEX_Y,
>>> +		.ext_info = hid_sensor_ext_info,
>>>  	}, {
>>>  		.type = IIO_ANGL_VEL,
>>>  		.modified = 1,
>>> @@ -78,6 +80,7 @@ static const struct iio_chan_spec gyro_3d_channels[] = {
>>>  		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>>>  		BIT(IIO_CHAN_INFO_HYSTERESIS),
>>>  		.scan_index = CHANNEL_SCAN_INDEX_Z,
>>> +		.ext_info = hid_sensor_ext_info,
>>>  	},
>>>  	IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP)
>>>  };
>>> diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>>> index e85a3a8eea908..aefbdb9b0869a 100644
>>> --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>>> +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
>>> @@ -74,6 +74,7 @@ static const struct iio_chan_spec magn_3d_channels[] = {
>>>  		BIT(IIO_CHAN_INFO_SCALE) |
>>>  		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>>>  		BIT(IIO_CHAN_INFO_HYSTERESIS),
>>> +		.ext_info = hid_sensor_ext_info,
>>>  	}, {
>>>  		.type = IIO_MAGN,
>>>  		.modified = 1,
>>> @@ -83,6 +84,7 @@ static const struct iio_chan_spec magn_3d_channels[] = {
>>>  		BIT(IIO_CHAN_INFO_SCALE) |
>>>  		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>>>  		BIT(IIO_CHAN_INFO_HYSTERESIS),
>>> +		.ext_info = hid_sensor_ext_info,
>>>  	}, {
>>>  		.type = IIO_MAGN,
>>>  		.modified = 1,
>>> @@ -92,6 +94,7 @@ static const struct iio_chan_spec magn_3d_channels[] = {
>>>  		BIT(IIO_CHAN_INFO_SCALE) |
>>>  		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
>>>  		BIT(IIO_CHAN_INFO_HYSTERESIS),
>>> +		.ext_info = hid_sensor_ext_info,
>>>  	}, {
>>>  		.type = IIO_ROT,
>>>  		.modified = 1,
>>> diff --git a/include/linux/hid-sensor-hub.h b/include/linux/hid-sensor-hub.h
>>> index c27329e2a5ad5..ee7d5b430a785 100644
>>> --- a/include/linux/hid-sensor-hub.h
>>> +++ b/include/linux/hid-sensor-hub.h
>>> @@ -236,6 +236,8 @@ struct hid_sensor_common {
>>>  	struct work_struct work;
>>>  };
>>>  
>>> +extern const struct iio_chan_spec_ext_info hid_sensor_ext_info[];
>>> +
>>>  /* Convert from hid unit expo to regular exponent */
>>>  static inline int hid_sensor_convert_exponent(int unit_expo)
>>>  {
>>




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux