Как перехватывать события обратной связи от силы между приложением и джойстиком?

Вопрос или проблема

Я хочу иметь возможность перехватывать событие FF (силовая отдача) (вибрация/дрожание в данном случае), которое обычно направляется напрямую в файл устройства игрового контроллера, чтобы отправить событие на какое-то другое устройство, при этом оставив игровой контроллер конечным получателем события. Это в надежде создать нативную для Linux альтернативу инструменту, доступному только для Windows, под названием Intiface Game Haptics Router (недопустимый случай использования, делает в основном то, что написано на упаковке)

Я уже пытался безуспешно создать скрипт на Python с использованием python-evdev, чтобы читать события, идущие к игровому контроллеру, но оказывается, что события UInput не содержат информацию о длине или интенсивности, если вы не начинаете загружать их на устройство, и мне не удалось захватить событие с реального игрового контроллера и загрузить его на виртуальный с теми же “возможностями” FF (я предполагаю, что приложение все еще напрямую общается с игровым контроллером, поэтому виртуальное устройство ничего не получает?). Возможно, это нехватка опыта с библиотекой, так как я в основном собрал вместе несколько примерных скриптов из раздела с учебными материалами на сайте документации

В предыдущей попытке сделать что-то подобное я наткнулся на xboxdrv, драйвер пользовательского пространства для игровых контроллеров Xbox. У него, похоже, есть некоторый функционал для отправки FF-событий на определенное устройство из-за некоторых крайних случаев. К сожалению, это не полезно, потому что эта опция имеет ограниченное применение, не позволяя указывать файлы устройств.

Я видел, что могу использовать модуль ядра usbmon и wireshark для перехвата USB-сообщений, однако я считаю, что это немного громоздко для настройки (как программно, так и вручную, я хотел бы, чтобы удобство использования учитывалось, поскольку слышал, что даже некоторые пользователи Steam Deck пытались использовать инструмент для Windows). У меня также есть опасения по поводу производительности и задержки, так как некоторые игры могут сильно нагружать систему, и если два устройства будут слишком сильно рассинхронизированы, это может сбивать с толку.

Для справки, я немного любитель Linux, я в основном использую Arch Linux и его производные на протяжении нескольких лет, в основном с KDE Plasma. Что касается кода, упомянутого ранее, я мог бы поделиться фрагментом кода, который пытался сделать работающим, но, как я уже говорил, он собран из примеров, так что там нет ничего революционного.

Я понимаю, что это странное нишевое дело и трудная задача, поэтому заранее большое спасибо, если вы сможете хотя бы осветить мой путь. И извините, если это не тот форум, я немного нов в Stack Exchange и имел некоторые трудности с тем, чтобы определить, к какому именно из них подходит мой вопрос.

Ответ или решение

Перехват событий обратной связи (Force Feedback): Руководство для Linux

Введение

Перехват событий обратной связи от игровых контроллеров в Linux — это непростая задача, особенно если вы хотите отправить эти события на другое устройство, сохранив при этом функциональность оригинального контроллера. В данном руководстве мы рассмотрим возможности реализации такого решения, используя существующие инструменты и библиотеки на Linux.

Проблема и её сущность

Как вы справедливо заметили, одно из основных препятствий в вашей задаче — это отсутствие необходимых данных о силе и продолжительности вибрации в событиях, отправленных через UInput. Это связано с тем, что оригинальная игра отправляет команды непосредственно на устройство, минуя ваш виртуальный контроллер. Использование python-evdev также может оказаться ограниченным, особенно если вы не до конца понимаете, как правильно использовать его функционал для обработки событий обратной связи.

Возможные решения

  1. Использование uinput и evdev для создания виртуального контроллера

    Вы можете попробовать создать виртуальный контроллер с помощью uinput и объединить его с обработкой событий с оригинального контроллера. Примерный план:

    • Создайте виртуальное устройство, используя UInput.
    • Подписывайтесь на события, отправляемые вашему контроллеру, через evdev.
    • Когда событие обратной связи осуществляется, вы получаете информацию о его интенсивности и длительности.
    • Повторно отправьте это событие как на оригинальный контроллер, так и на ваше виртуальное устройство.

    Пример кода:

    import evdev
    from evdev import InputDevice, UInput, ecodes as ev
    
    # Открытие устройства игры
    gamepad = InputDevice('/dev/input/eventX')  # замените на ваш путь устройства
    ui = UInput()
    
    for event in gamepad.read():
       if event.type == ev.EV_FF:
           # Обработка события обратной связи
           ui.write(ev.EV_FF, event.code, event.value)  # Отправляем на виртуальный контроллер
           gamepad.write(ev.EV_FF, event.code, event.value)  # Отправляем на оригинальный контроллер
           ui.syn()
           gamepad.syn()
  2. Использование usbmon и анализа USB-трафика

    Хотя вы считаете использование usbmon громоздким, это один из самых мощных способов решения вашей задачи. Пакеты могут быть захвачены с использованием wireshark, а затем повторно отправлены в реальном времени, обеспечивая высокую точность и контроль над параметрами обратной связи.

    Вы можете автоматизировать данный процесс, написав скрипт, который будет захватывать нужные события и отправлять их на ваше либо любое другое устройство.

  3. Пользовательские драйвера

    Если вы чувствуете себя уверенно в написании модулей для ядра Linux, можете рассмотреть создание собственного драйвера, который будет перехватывать события перед их отправкой в устройство. Это обеспечит вам полное управление данными о вибрации и способности отправки их на другое устройство.

Оптимизация производительности

Для снижения задержек и повышения производительности ото всех сценариев:

  • Рассмотрите возможность использования реального программного обеспечения для сбора и обработки событий в режиме реального времени.
  • Убедитесь, что ваш код оптимизирован для минимизации нагрузок на CPU.
  • Сведите к минимуму задержки вызова метода через использование асинхронного программирования, например, с помощью библиотеки asyncio.

Заключение

Создание системы для перехвата событий обратной связи от игрового контроллера на Linux — это сложная, но выполнимая задача. С помощью вышеописанных методов и подходов вы можете достичь своей цели. Не забывайте документировать ваш процесс и делиться базовым кодом с сообществом — это поможет не только вам, но и другим, кто пытается решить аналогичную задачу. Удачи в ваших усилиях!

Оцените материал
Добавить комментарий

Капча загружается...