Настройка Saitek Pro Yoke System на FlightGear под FreeBSD22 марта 2011 12:00, 1 комментарий

FreeBSD, Авиасимуляторы

После приобретения Saitek Flight Yoke System и попытки задействовать данный девайс на авиасимуляторе FlightGear в своей FreeBSD-системе выяснилось, что штурвал работает только наполовину (вперед и влево). Проблему удалось решить только за несколько дней, о чем, собственно, и статья.

Сначала я грешным делом подумал, что сам штурвал неисправен аппаратно. Это меня малость расстроило, поскольку покупалось на eBay и шло почтой несколько недель. Проверить было легко, подключив к другому симулятору на другом компьютере. Что и было сделано на мелкомягком симуляторе под виндовозом - мир не без добрых людей. На этом шаге я выяснил, что мой штурвал идеально настроен и работает без замечаний. Другими словами, проблема в моем компьютере.

Следующим шагом я проверил что выдает драйвер uhid (что, по-уму надо было сделать в первую очередь). Я подчеркиваю - драйвер uhid из системы FreeBSD, а не sysutils/uhidd из портов (его я тоже пробовал, но получил худший результат). Проверял я это так:

usbhidctl -f /dev/uhid0 -a -l

Что показало, что драйвер uhid правильно видит все движения элементов управления штурвала и квадранта (это такая отдельная коробочка с тремя рычагами и тремя двух-позиционными переключателями).

Далее, я сравнил эти показания с результатом утилиты js_demo, что идет в комплекте с симулятором и предназначена специально для тестирования джойстиков и других подобных девайсов (строго говоря, мой штурвал понимается симулятором как подвид джойстика). Утилита js_demo выдает все параметры в диапазоне от -1.0 до +1.0. Ровно так же видит все параметры и сам симулятор. То есть, если повернуть штурвал влево, соответствующий параметр станет равным -1.0, а если повернуть вправо, то значение данного параметра будет менять в большую сторону до тех пор, пока не достигнет значения +1.0 в крайне правом положении штурвала. Таким образом, любой параметр, который не попадает в пределы -1.0 - +1.0, обрабатывается неправильно. На этом этапе я, наконец, определил, что дело не в моей операционной системе и не в драйвере USB, а непосредственно в самом симуляторе, что значительно сузило круг поиска решения.

Следующим шагом я стал искать решение на англо- и русскоязычном форумах FlightGear. В результате нашел описание подобной проблемы (второй пост сверху) от пользователя с ником yurik_nsk. На тот момент это был уже не первый и даже не третий день поисков решения, поэтому у меня уже свербило, и я не стал писать на форум, а связался непосредственно с автором поста Юрием Никифоровым по джабберу. Я застал его в командировке где-то не сервере, но не смотря на это, он мне здорово помог в поиске решения, за что ему спасибо. Проблема оказалась в том, что моя система выдает значение поворота штурвала в диапазоне с двойной точностью (1024 вместо 512), а библиотека plib не может правильно обработать такую ситуацию.

Поскольку проблема сузилась до редактирования исходных кодов библиотеки x11-toolkits/plib, посредством которой FlightGear получает данные с джойстиков, следующим шагом я занялся подбором правильного значения методом научного тыка. В итоге правильными оказались параметры, которые выдает драйвер uhid посредством usbhidctl (что и логично).

Пересобирал я исправленную библиотеку уже хорошо проверенным ранее методом. Последовательность пересборки такая:

  • Сначала неплохо бы убедиться, что в файле /etc/make.conf есть директива FORCE_PKG_REGISTER=yes, иначе нам будет необходимо вводить эту директиву каждый раз при сборке.
  • Копируем файл с исходными кодами библиотеки plib-1.8.5.tar.gz из /usr/ports/distfiles/ куда-нибудь в другое место, хотя бы в Desktop.
  • Разворачиваем ее в одноименную директорию plib-1.8.5 (так по-умолчанию делает Nautilus через контекстное меню).
  • Вносим необходимые исправления в файлы исходных кодов.
  • Архивируем директорию с исправленными файлами обратно в архив с тем же именем (опять же, Nautilus делает всё правильно через контекстное меню).
  • Переносим новый файл plib-1.8.5.tar.gz обратно в /usr/ports/disfiles/, перезаписывая при этом старый файл.
  • Переходим в директорию библиотеки /usr/ports/x11-toolkits/plib и запускаем сборку командой make NO_CHECKSUM=yes install. Второй параметр имеет ключевое значение, потому как без него система определит по контрольной сумме, что файл не тот и загрузит из Сети новый, перезаписав при этом наши изменения. Параметр clean на данном шаге необязателен - временные файлы почистятся на следующем шаге.
  • После нормального окончания сборки plib переходим в директорию симулятора /usr/ports/games/flightgear и собираем симулятор FlightGear обычным способом - make install clean. Пересборка симулятора необходима, потому что при сборке plib получается статическая библиотека libplibjs.a, которая (как и все статические библиотеки) жестко связывается с программой симулятора в момент её компиляции.
  • После нормального завершения предыдущего шага мы имеем заново собранными с нашими исправлениями библиотеку и симулятор. Остается только переинициализировать девайс. Если модуль uhid вкомпилирован в ядро (как в ядре GENERIC) - ничего не поделаешь - придется ребутнуться. Если же модуль подгружен вручную или посредством /boot/loader.conf, то нужно сделать четыре шага: физически отключить девайс от USB, выгрузить модуль ядра посредством команды kldunload uhid, загрузить модуль обратно командой kldload uhid и подключить снова девайс в разъем USB.

После всего вышесказанного мой штурвал заработал как положено. Но! Поскольку я увеличил диапазоны параметров для штурвала, то задел и рукоятки квадранта, диапазон которых вдвое меньше. Еще полночи я пытался выправить эти параметры XML-конфигами, но не получалось никак. Видимо, всё же, это делается не так, решил я и снова полез в исходники. В итоге я внес исправления в исходники еще в одно место и все заработало как и было задумано.

Исправления в коде

Все исправления делаются в одном-единственном файле src/js/jsBSD.cxx. Первое исправление касается непосредственно самого штурвала. Нужно найти строчки:

max       [ i ] = 255.0f ;
center    [ i ] = 127.0f ;

У меня в plib версии 1.8.5 это строки с номерами 379 и 380 соответственно. Их надо заменить на:

max       [ i ] = 1023.0f ;
center    [ i ] = 512.0f ;

Далее, нужно найти строчку:

os->cache_axes[i] = (float)d;

У меня в неисправленном файле эта строка была под номером 490. Заменить её нужно на следующее условие:

if (i > 1)
{
    os->cache_axes[i] = (float) (d * 4);
}
else
{
    os->cache_axes[i] = (float) d;
}

Поскольку поворот и горизонтальное перемещение штурвала имеют номера 0 и 1 соответственно, то все элементы управления с номерами больше единицы должны иметь вдвое меньший диапазон. Что в данном месте кода выражается умножением на 4.

Оговорюсь, что всё вышесказанное справедливо для системы FreeBSD 8.1, симулятором FlightGear 2.0.0_3 и plib 1.8.5. Возможно, что с другими системами и версиями нужны будут другие множители, но суть изменений, надеюсь, ясна.

Добавьте свой комментарий

К этой статье в настоящий момент 1 комментарий. Если вам есть, что добавить, вы можете оставить здесь и свой комментарий. Поля имя и почтовый адрес обязательны для заполнения. Адрес на сайте не публикуется.

Цитаты оформляются так: /* Цитируемый текст */.