[systemd-devel] hwdb: inconsistency in 60-sensor.hwdb accel_mount_matrix

Gwendal Grignou gwendal at chromium.org
Mon Jun 27 22:52:39 UTC 2022


[+cc: systemd-devel]
Bounced since I was not a member.

On Mon, Jun 27, 2022 at 12:50 PM Gwendal Grignou <gwendal at chromium.org> wrote:
>
> In 60-sensor.hwdb, we can specify a matrix to rotate sensor output to
> match the expected 'natural' orientation [1].
>
> When behind a screen, accelerometers are usually soldered upside down,
> so a rotation matrix is needed to rotate their raw output into the
> 'natural' orientation when read directly.
>
> When flat on a table, standalone accelerometers/IMUs report the force
> exercised by the table to prevent the sensor from falling down
> further. In the 'natural' orientation, this is [0, 0, 1g]. See for
> instance the BMI160 specification[2], page 107).
>
> However, Gnome expects the sensor to return the gravity force itself,
> as specified by windows and the HID specification:  When flat on a
> table, the expected value is [0, 0 , -1g].
>
> Therefore, the matrix, in addition to rotating the sensors, should
> also invert the axes.
> When a matrix inverts the axes, its determinant is -1 [3].
> Out of the 160 matrices defined, 136 invert the axes, 29 does not and
> one as a determinant equals to 0.
>
> That matrix, for Hometech device is obviously not correct: the sensor
> input vector X component is is used for both Y and Z axes of the
> output vector:
>
> #########################################
> # Hometech
> ########################################
>
> # Nobody bothered to use Linux on any device of this manufacturer
> # so current marks might be too general and need fixes.
> # These values are based on Wi101 model.
> sensor:modalias:acpi:BMA250E*:dmi:*:svnInsyde*:pni101c:*
>  ACCEL_MOUNT_MATRIX=0,1,0;-1,0,0;-1,0,0
>
> Remains 29 matrices where axes are not inverted:
> 9 (':acpi:BOSC0200*', 1.0)
> 3 (':acpi:INVN6500*', 1.0)
> 2 (':acpi:KIOX010A*', 1.0)
> 2 (':acpi:KIOX020A*', 1.0)
> 1 (':acpi:KIOX0009*', 1.0)
> 1 (':acpi:SMO8500:*', 1.0)
> 1 (':acpi:MXC6655*', 1.0)
> 1 (':acpi:ACCE0001*', 1.0)
> 1 (':acpi:KIOX000A*', 1.0)
> 1 (':i2c:bmc150_accel', 1.0)
> 1 (':acpi:NCPE0388*', 1.0)
> 1 (':acpi:SMO8500*', 1.0)
>
> Interestingly, some matrices for the same sensors are inverting axes:
>  KIOX000A* sensors axes are inverted 36 times.
>
> The reason is the expectation that in convertible devices the
> accelerometers return the same data after rotation when the lid angle
> is 0:
>
> # A note about setting ACCEL_MOUNT_MATRIX for ACCEL_LOCATION=base sensors,
> # [...] This means that the
> # base-accelerometer's mount-matrix must be such, that after applying
> # the mount-matrices to both sensors, the base-accelerometer's readings must
> # be identical to the display-accelerometer's readings (when the lid is
> # closed).
>
> It means that one of 2 accelerometers is expected to not return data
> in the 'normal' orientation.
>
> W3C device orientation specs [4] implies the sensors use the same
> device coordinate frame, and therefore should return the same data
> when the lid angle is 180 degree.
>
> The convention of aligning returned data to 180 degree lid angle can
> be fixed completely in user space as long as the algorithm for
> calculating lid angle and the udev tables are changed at the same
> time. It will result that matrices defined for sensors that follow the
> W3C specifications will always invert the axes.
>
> Regards,
> Gwendal.
>
> [1]:
> https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git/tree/Documentation/ABI/testing/sysfs-bus-iio#n1838
>
> [2]:
> https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmi160-ds000.pdf
>
> [3]:
> https://en.wikipedia.org/wiki/Determinant#Orientation_of_a_basis)
>
> [4]
> https://w3c.github.io/deviceorientation/#deviceorientation
>
> python script to pocess the determinent of the matrices:
> #!/usr/bin/python3
>
> import collections
> import numpy as np
> import re
> import sys
>
>
> sensor_re=re.compile(r'sensor:modalias(.*):dmi.*')
> matrix_re=re.compile(r' ACCEL_MOUNT_MATRIX=(.*)')
>
> sensors = []
> sensor_dict = collections.defaultdict(int)
> for l in sys.stdin:
>     l = l.rstrip()
>     if l == '':
>         sensors = []
>     sensor_match = sensor_re.match(l)
>     if sensor_match:
>         sensors.append(sensor_match.group(1))
>     matrix_match = matrix_re.match(l)
>     if matrix_match:
>         matrix = np.matrix(matrix_match.group(1))
>         for s in sensors:
>           sensor_dict[(s, np.linalg.det(matrix))] += 1
>
> for k in sorted(sensor_dict, key=sensor_dict.get, reverse=True):
>   print(sensor_dict[k], k)
>
> Output of the script on 60-sensor.hwdb:
>
> cat 60-sensor.hwdb.txt | ~/bin/process_rotation_matrix.py
> 36 (':acpi:KIOX000A*', -1.0)
> 35 (':acpi:BOSC0200*', -1.0)
> 29 (':acpi:SMO8500*', -1.0)
> 14 (':acpi:INVN6500*', -1.0)
> 14 (':acpi:BMA250E*', -1.0)
> 9 (':acpi:BOSC0200*', 1.0)
> 9 (':acpi:KIOX010A*', -1.0)
> 6 (':platform:cros-ec-accel', -1.0)
> 6 (':acpi:KIOX020A*', -1.0)
> 4 (':i2c:bmc150_accel', -1.0)
> 4 (':acpi:BMA250*', -1.0)
> 3 (':acpi:KIOX0009*', -1.0)
> 3 (':acpi:MXC6655*', -1.0)
> 3 (':acpi:INVN6500*', 1.0)
> 3 (':acpi:*BOSC0200*', -1.0)
> 2 (':acpi:KIOX010A*', 1.0)
> 2 (':acpi:KIOX020A*', 1.0)
> 1 (':acpi:KIOX0009*', 1.0)
> 1 (':acpi:SMO8500:*', 1.0)
> 1 (':acpi:KXJ2109*', -1.0)
> 1 (':acpi:BMI0160*', -1.0)
> 1 (':acpi:MXC6655*', 1.0)
> 1 (':acpi:*KIOX000A*', -1.0)
> 1 (':acpi:ACCE0001*', 1.0)
> 1 (':acpi:KIOX000A*', 1.0)
> 1 (':acpi:KXCJ9000*', -1.0)
> 1 (':acpi:BMA250E*', 0.0)
> 1 (':i2c:bmc150_accel', 1.0)
> 1 (':acpi:NCPE0388*', 1.0)
> 1 (':acpi:SMO8840*', -1.0)
> 1 (':acpi:DUAL250E*', -1.0)
> 1 (':acpi:SMO8500*', 1.0)
> 1 (':acpi:KIOX0008*', -1.0)


More information about the systemd-devel mailing list