Оглавление |
---|
Информация | ||
---|---|---|
| ||
|
Общие сведения
В данной статье приведено описание настройки акселерометра устройства, необходимой для корректной работы автоматической ориентации экрана.
Предупреждение | ||
---|---|---|
| ||
Если на акселерометр на устройстве работает корректно, то его калиброватьне требуется. |
Для настройки акселерометра требуется создать правило udev
, определяющее привязку данных, получаемых от акселерометра, к осям координат устройства. Эта привязка может быть представлена в виде таблицы (матрицы) размером 3х3, содержащей коэффициенты коррекции для данных, получаемых от акселерометра.
За взаимодействие с датчиком поворота отвечает IIO-подсистема ядра Linux, в частности — утилита iio-sensor-proxy
(см. https://gitlab.freedesktop.org/hadess/iio-sensor-proxy/#iio-sensor-proxy).
Ниже представлена таблица, содержащая матрицу, используемую для калибровки экрана (Подробнее см.: https://gitlab.freedesktop.org/hadess/iio-sensor-proxy/#accelerometer-orientation). Голубым отмечены заголовки строк и столбцов, относительно которых в дальнейшем будет производится калибровка. Красным в таблице отмечены участки, которыене нужно редактировать (не участвуют в калибровке).
x | y | z | |
(1) | x1 | y1 | z1 |
(2) | x2 | y2 | z2 |
(3) | x3 | y3 | z3 |
Блок кода | ||||
---|---|---|---|---|
| ||||
ENV{IIO_SENSOR_PROXY_TYPE}=="*accel*", ENV{ACCEL_MOUNT_MATRIX}="x1,y1,z1;x2,y2,z2;x3,y3,z3" |
По умолчанию , iio-sensor-proxy
использует единичную матрицу:
x | y | z | |
(1) | 1 | 0 | 0 |
(2) | 0 | 1 | 0 |
(3) | 0 | 0 | 1 |
Значения интерпретируется в виде правила udev
следующим образом:
Блок кода | ||||
---|---|---|---|---|
| ||||
ENV{IIO_SENSOR_PROXY_TYPE}=="*accel*", ENV{ACCEL_MOUNT_MATRIX}="1,0,0;0,1,0;0,0,1" |
Для калибровки экрана , необходимо изменять значения данной таблицы.
Проверка наличия целевой матрицы
Целевая матрица используется для калибровки датчика поворота. По умолчанию , она должна находится в описании устройств из ACPI - Advanced Configuration and Power Interface (см. https://ru.wikipedia.org/wiki/ACPI).
Для проверки наличия целевой матрицы устройства необходимо получить дамп DSL (описание устройств из ACPI), выполнив следующие команды:
Блок кода | ||||
---|---|---|---|---|
| ||||
cat /sys/firmware/acpi/tables/DSDT > dsdt.dat iasl -d dsdt.dat |
iasl
- Intel ACPI компилятор/декомпилятор, используется для работы с ACPI и не только (см. https://linux.die.net/man/1/iasl). Команда iasl -d dsdt.dat
дизассемблирует dsdt.dat
в dsdt.dsl
(формат ASL). ASL - ACPI Source Language, исходный язык для определения и написания методов ACPI (см. https://wiki.osdev.org/AML).В полученном файле (dsdt.dsl
) необходимо найти матрицу по умолчанию:
- если известны
DEVICE_ID
/VENDOR_ID
, необходимо найти запись о данном устройстве; - в записи об устройстве необходимо найти методROTM (Rotation Matrix).
В случае если целевая матрица не была обнаружена, необходимо выполнить калибровку с помощью правила udev
(см. Калибровка при помощи правила udev).
Пример метода ROTM для планшета Lenovo IdeaPad 3IGL5-LTE:
Блок кода | ||||
---|---|---|---|---|
| ||||
Method (ROTM, 0, NotSerialized) { Name (RBUF, Package (0x03) { "0 -1 0", "1 0 0", "0 0 1" }) Return (RBUF) /* \_SB_.PCI0.I2C5.DEV_.ROTM.RBUF */ } |
Целевая матрица для данной модели имеет следующий вид.
x | y | z | |
(1) | 0 | -1 | 0 |
(2) | 1 | 0 | 0 |
(3) | 0 | 0 | 1 |
Блок кода | ||||
---|---|---|---|---|
| ||||
ENV{IIO_SENSOR_PROXY_TYPE}=="*accel*", ENV{ACCEL_MOUNT_MATRIX}="0,-1,0;1,0,0;0,0,1" |
В случае если полученная матрица некорректно откалибровала устройство, необходимо выполнить калибровку с помощью правила udev
(см. Калибровка при помощи правила udev).
Якорь | ||||
---|---|---|---|---|
|
Порядок калибровки
В случае если целевая матрица отсутствует или если при её применении калибровка сенсора некорректна, для калибровки датчика необходимо:
- определить желаемое нормальное положение устройства (портретная либо альбомная ориентация). Нормальное положение зависит от нужд пользователя. За нормальное можно принять любое положение и отталкиваясь от этого проводить настройку. Можно также в качестве нормальной использовать ориентацию, в которой отображается экран при включении устройства (например, для планшетов iRU это альбомный режим);
- задать начальную матрицу в виде правила
udev
(см. Применение единичной матрицы); - если режим отображения экрана не соответствует положению устройства — определить, на сколько нужно осуществить поворот экрана для приведения его в правильное положение, и выполнить указанные далее изменения элементов матрицы для получения нужного режима отображения экрана (см. Приведение экрана в правильное положение).
Якорь | ||||
---|---|---|---|---|
|
Первым шагом необходимо задать начальную (единичную) матрицу в виде правила udev
, помещенного в файл /etc/udev/rules.d/99-astra-orientation.rules
(все дальнейшие действия по калибровке экрана будут сводится к редактированию этого файла):
x | y | z | |
(1) | 1 | 0 | 0 |
(2) | 0 | 1 | 0 |
(3) | 0 | 0 | 1 |
Блок кода | ||
---|---|---|
| ||
ENV{IIO_SENSOR_PROXY_TYPE}=="*accel*", ENV{ACCEL_MOUNT_MATRIX}="1,0,0;0,1,0;0,0,1" |
Для применения правил необходимо перезагрузить устройство.
После того, как была применена начальная матрица, необходимо определить, на сколько градусов нужно осуществить поворот экрана для приведения его в правильное положение (см. Приведение экрана в правильное положение).
Все дальнейшие изменения по повороту применимы только к начальной (единичной) матрице (п. 3.1).
Якорь | ||||
---|---|---|---|---|
|
Поворот изображения на 90° по часовой стрелке
Исходная матрица имеет следующий вид.
x | y | z | |
(1) | 1 | 0 | 0 |
(2) | 0 | 1 | 0 |
(3) | 0 | 0 | 1 |
Блок кода | ||||
---|---|---|---|---|
| ||||
ENV{IIO_SENSOR_PROXY_TYPE}=="*accel*", ENV{ACCEL_MOUNT_MATRIX}="1,0,0;0,1,0;0,0,1" |
Вычисления.
x | y | z | |
(1) | cos (90) | -1 * sin (90) | 0 |
(2) | sin (90) | cos (90) | 0 |
(3) | 0 | 0 | 1 |
Результирующая матрица.
x | y | z | |
(1) | 0 | -1 | 0 |
(2) | 1 | 0 | 0 |
(3) | 0 | 0 | 1 |
Блок кода | ||||
---|---|---|---|---|
| ||||
ENV{IIO_SENSOR_PROXY_TYPE}=="*accel*", ENV{ACCEL_MOUNT_MATRIX}="0,-1,0;1,0,0;0,0,1" |
Поворот изображения на 180° по часовой стрелке
Исходная матрица.
x | y | z | |
(1) | 1 | 0 | 0 |
(2) | 0 | 1 | 0 |
(3) | 0 | 0 | 1 |
Блок кода | ||||
---|---|---|---|---|
| ||||
ENV{IIO_SENSOR_PROXY_TYPE}=="*accel*", ENV{ACCEL_MOUNT_MATRIX}="1,0,0;0,1,0;0,0,1" |
Вычисления.
x | y | z | |
(1) | cos (180) | -1 * sin (180) | 0 |
(2) | sin (180) | cos (180) | 0 |
(3) | 0 | 0 | 1 |
Результирующая матрица.
x | y | z | |
(1) | -1 | 0 | 0 |
(2) | 0 | -1 | 0 |
(3) | 0 | 0 | 1 |
Блок кода | ||||
---|---|---|---|---|
| ||||
ENV{IIO_SENSOR_PROXY_TYPE}=="*accel*", ENV{ACCEL_MOUNT_MATRIX}="-1,0,0;0,-1,0;0,0,1" |
Поворот изображения на 270° по часовой стрелке
Исходная матрица.
x | y | z | |
(1) | 1 | 0 | 0 |
(2) | 0 | 1 | 0 |
(3) | 0 | 0 | 1 |
Блок кода | ||||
---|---|---|---|---|
| ||||
ENV{IIO_SENSOR_PROXY_TYPE}=="*accel*", ENV{ACCEL_MOUNT_MATRIX}="1,0,0;0,1,0;0,0,1" |
Вычисления.
x | y | z | |
(1) | cos (270) | -1 * sin (270) | 0 |
(2) | sin (270) | cos (270) | 0 |
(3) | 0 | 0 | 1 |
Результирующая матрица.
x | y | z | |
(1) | 0 | 1 | 0 |
(2) | -1 | 0 | 0 |
(3) | 0 | 0 | 1 |
Блок кода | ||||
---|---|---|---|---|
| ||||
ENV{IIO_SENSOR_PROXY_TYPE}=="*accel*", ENV{ACCEL_MOUNT_MATRIX}="0,1,0;-1,0,0;0,0,1" |
Определение необходимости инвертирования
Если после определения нормального положения устройства (см. Приведение экрана в правильное положение) получилось инверсия какого либо из режимов просмотра (инвертированный альбомный/портретный режим), необходимо произвести инверсию относительно Y-координат (см. Инвертирование Y-координаты).
В случае если после применения инверсии относительно Y-координат не был достигнут желаемый результат, необходимо вернуть матрицу к состоянию, полученному в Приведение экрана в правильное положение, и произвести инверсию относительно X-координат (см. Инвертирование X-координаты).
Якорь | ||||
---|---|---|---|---|
|
Для инверсии в качестве исходной матрицы необходимо брать матрицу, полученную после поворота (см. Приведение экрана в правильное положение).
x | y | z | |
(1) | x1 | y1 | z1 |
(2) | x2 | y2 | z2 |
(3) | x3 | y3 | z3 |
Для выполнения инверсии необходимо каждуюY-координату (из тех, которые участвуют в калибровке)умножить на -1, т. е.:
- y1 * -1;
- y2 * -1.
Таким образом, результирующая матрица будет иметь следующий вид.
x | y | z | |
(1) | x1 | y1 = -1 * y1 | z1 |
(2) | x2 | y2 = -1 * y2 | z2 |
(3) | x3 | y3 | z3 |
Блок кода | ||||
---|---|---|---|---|
| ||||
ENV{IIO_SENSOR_PROXY_TYPE}=="*accel*", ENV{ACCEL_MOUNT_MATRIX}="x1,-y1,z1;x2,-y2,z2;x3,y3,z3" |
Якорь | ||||
---|---|---|---|---|
|
Для инверсии в качестве исходной матрицынеобходимо брать матрицу, полученную после поворота (см. Приведение экрана в правильное положение).
x | y | z | |
(1) | x1 | y1 | z1 |
(2) | x2 | y2 | z2 |
(3) | x3 | y3 | z3 |
Для выполнения инверсии необходимо каждую X-координату (из тех, которые участвуют в калибровке) умножить на -1, т. е.:
- x1 * -1;
- x2 * -1.
Таким образом, результирующая матрица будет иметь следующий вид.
x | y | z | |
(1) | x1 = -1 * x1 | y1 | z1 |
(2) | x2 = -1 * x2 | y2 | z2 |
(3) | x3 | y3 | z3 |
Блок кода | ||||
---|---|---|---|---|
| ||||
ENV{IIO_SENSOR_PROXY_TYPE}=="*accel*", ENV{ACCEL_MOUNT_MATRIX}="-x1,y1,z1;-x2,y2,z2;x3,y3,z3" |
Настройка частоты опроса датчика поворота на устройстве МИГ Т8х
Для снижения чувствительности (частоты опроса) датчика поворота на планшете МИГ Т8х необходимо:
- получить минимально возможное значение из файла
/sys/bus/iio/devices/iio:device0/in_accel_sampling_frequency_available
; - обновить значение на полученное минимальное путем редактирования файла
/sys/bus/iio/devices/iio:device0/in_accel_sampling_frequency
.
Недостаток данного подхода в том, что после перезагрузки датчик не запоминает измененное значение.
Для того чтобы система могла автоматически устанавливать минимальную частоту обновления датчика, необходимо:
- выполнить команды:
Блок кода language bash title Создание файла, папки sudo mkdir /etc/mig sudo touch /etc/mig/mig-t8x-accel-sampling-freq-fix.sh
- в файл
/etc/mig/mig-t8x-accel-sampling-freq-fix.sh
вставить следующий текст:Блок кода language bash title /etc/mig/mig-t8x-accel-sampling-freq-fix.sh SET_FREQ_FILE="/sys/bus/iio/devices/iio:device0/in_accel_sampling_frequency" AV_FREQ_FILE="/sys/bus/iio/devices/iio:device0/in_accel_sampling_frequency_available" minFreq=`cat $AV_FREQ_FILE | cut -d' ' -f1` echo $minFreq > $SET_FREQ_FILE
- создать файл службы:
Блок кода language bash title Создание файла для сервиса, установка прав доступа sudo touch /etc/systemd/system/mig-t8x-accel-sampling-fix.service sudo chmod 644 /etc/systemd/system/mig-t8x-accel-sampling-fix.service
- в созданный файл вставить следующий текст:
Блок кода language bash title /etc/systemd/system/mig-t8x-accel-sampling-fix.service [Unit] Description=Fix accel sampling frequency for MIG T8x [Service] Type=simple ExecStart=/bin/bash /etc/mig/mig-t8x-accel-sampling-freq-fix.sh [Install] WantedBy=multi-user.target
- после сохранения файла активировать службу:
Блок кода language bash title Активация сервиса sudo systemctl enable mig-t8x-accel-sampling-fix.service
После перезагрузки системы датчик будет автоматически настраиваться на минимальную частоту обновления.
Ниже прикреплен сценарий автоматически выполняющий все предыдущие шаги: generate_mig-t8x-fix-accel-sampling-frequency.sh