Оглавление |
---|
Информация | ||
---|---|---|
| ||
|
Основная информация
Предупреждение | ||
---|---|---|
| ||
Если на |
акселерометр на устройстве работает корректно, то его калибровать не требуется. |
Для настройки акселерометра требуется создать правило udev, определяющее привязку данных, получаемых от акселерометра, к осям координат устройства. Эта привязка может быть представлена в виде таблицы (матрицы) 3х3, содержащей коэффициенты коррекции для данных, получаемых от акселерометра.
За взаимодействие с датчиком поворота отвечает IIO подсистема ядра Linux, в частности утилита iio-sensor-proxy - https://gitlab.freedesktop.org/hadess/iio-sensor-proxy/#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" |
Значения интерпретируется в виде udev правила следующим образом:
По умолчанию, 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
|
-tc dsdt.dsliasl
- 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) необходимо найти матрицу по умолчанию:
- Если известны DEVDEVICE_ID/VENVENDOR_ID, необходимо найти данное устройство
- Затем у устройства необходимо найти метод ROTM (Rotation Matrix)устройства необходимо найти метод ROTM (Rotation Matrix).
В случае, если целевая матрица не была обнаружена - необходимо перейти к другому способу калибровки, описанному в п.3.
Рассмотрим пример для планшета 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" |
В случае если полученная матрица некорректно откалибровала устройство, необходимо произвести калибровку по алгоритму, приведенному ниже (п.3).
Настройка акселерометра: калибровка при помощи udev правила
- Определить желаемое нормальное положение устройства (портретная либо альбомная ориентация). Нормальное положение зависит от нужд пользователя. За нормальное можно принять любое положение, и отталкиваясь от этого, проводить настройку. Можно также в качестве нормальной использовать ориентацию, в которой отображается экран при включении устройства (для планшетов iRU, например, это альбомный режим);
- Если режим отображения экрана не соответствует положению устройства, то определить, на сколько нужно осуществить поворот изображения для приведения его в правильное положение, и выполнить указанные далее изменения элементов матрицы для получения нужного режима отображения экрана.
Настройка акселерометра: применение единичной матрицы
Первым шагом необходимо задать начальную (единичную) матрицу в виде 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" |
Настройка акселерометра: определение необходимости инвертирования
Если после выполнения п. 3.2 получилось инверсия какого либо из режимов просмотра (инвертированный альбомный/портретный режим), необходимо произвести инверсию относительно Y координат. (п. 3.3.1).
В случае, если после применение инверсии желаемый результат не был достигнут, необходимо вернуть матрицу, полученную из п. 3.2.х, и произвести инверсию относительно X координат (п. 3.3.2).
Настройка акселерометра: инвертирование Y координаты
Для инверсии , в качестве исходной матрицы необходимо брать матрицу, полученную после поворота (из п. 3.2.х).
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 координаты
Для инверсии, в качестве исходной матрицы необходимо брать матрицу, полученную после поворота (из п. 3.2.х).
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
У данного подхода есть недостаток, после перезагрузки датчик не сохранит полученное запоминает измененное значение.
Ниже будет перечислен порядок действий, необходимый для того, чтобы система могла автоматически устанавливать минимальную частоту обновления датчика.
Блок кода | ||||
---|---|---|---|---|
| ||||
sudo mkdir /etc/mig sudo touch /etc/mig/mig-t8x-accel-sampling-freq-fix.sh |
Далее, в файл /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" freqLine=$(cat $AV_FREQ_FILE) minFreq=0 for freq in $freqLine do minFreq=$freq break done echo $minFreq > $SET_FREQ_FILE |
Теперь необходимо создать сервис:
Блок кода | ||||
---|---|---|---|---|
| ||||
sudo touch /etc/systemd/system/mig-t8x-accel-sampling-fix.service sudo chmod 644 /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 |
После сохранения файла, необходимо активировать сервис:
Блок кода | ||||
---|---|---|---|---|
| ||||
sudo systemctl enable mig-t8x-accel-sampling-fix.service |
Теперь после перезагрузки системы датчик будет автоматически настраиваться на минимальную частоту обновления.
Ниже прикреплен скрипт, который сценарий автоматически выполняет выполняющий все предыдущие шаги: generate_mig-t8x-fix-accel-sampling-frequency.sh