Python - беспроводной контроллер и список дополнений / значений - PullRequest
3 голосов
/ 14 февраля 2020

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

Оборудование: RPi4 4 ГБ, SteelSeries Stratus Duo Беспроводной контроллер WiFi / BTLE

Долгосрочная цель: Выполнить несколько задач (т. Е. Переместить / обнулить инструментальную головку, запустить / приостановить / остановить программу и т. Д. c.) С помощью беспроводного контроллера, который будет взаимодействовать с RPi, на котором запущен сервер, управляющий маршрутизатором CN C.

Краткосрочная цель: Определить, какая комбинация кнопок нажимается без использования безбожного числа операторов if/elif ,

Резюме: Я уже разобрался, как считывать выходные данные с беспроводного контроллера, используя PyUSB. Я изменил / добавил код к тому, что было включено в PyUSB, чтобы получить некоторые удобочитаемые результаты. Выходные данные форматируются в виде списка, причем значение каждого элемента определяется некоторой комбинацией кнопок. (Я знаю, что он говорит «массив», но Python, кажется, обрабатывает его как список.)

Это вывод, когда ни одна кнопка не нажата (по умолчанию):

array('B', [0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

Первые два значения (...[0, 20,...]) кажутся некими идентификаторами, и они никогда не меняются. Однако несколько кнопок используют одно и то же индексированное место в списке. Все они имеют разные значения и суммируются при одновременном нажатии. Никакая комбинация значений кнопок не генерирует одинаковый выход для индексированного местоположения. Примеры:

Кнопка A: array('B', [0, 20, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

Вверху слева: array('B', [0, 20, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

Вверху слева & A: array('B', [0, 20, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

В качестве заявления об отказе от ответственности, Я уверен, что здесь много новых ie ошибок. Я не здесь, потому что я какой-то профессиональный Python программист, поэтому любая законная конструктивная критика приветствуется. Я видел другие посты, где люди избивали ОП таким образом, который не способствовал решению проблемы. Пожалуйста, не тратьте мое или чужое время на посты "Ха-ха, ты сосешь".

С этим, кстати, моя текущая программа, и, как вы можете видеть, операторы if / elif начинают немного выходить из-под контроля. :

#!/usr/bin/python
from __future__ import division

import usb.core
import usb.util
import time
import os
import sys
#import csv

USB_IF      = 0 # Interface
USB_TIMEOUT = 5 # Timeout in MS

USB_VENDOR  = 0x1038 # SteelSeries
USB_PRODUCT = 0x1430 # Stratus Duo

dev = usb.core.find(idVendor=USB_VENDOR, idProduct=USB_PRODUCT)

endpoint = dev[0][(0,0)][0]

if dev.is_kernel_driver_active(USB_IF) is True:
    dev.detach_kernel_driver(USB_IF)

usb.util.claim_interface(dev, USB_IF)

while True:
    control = None

    try:
        control = dev.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize, USB_TIMEOUT)
        CtrlA = control[2]      #Directional Pad, Start/Select, L/R Stick Press
        CtrlB = control[3]      #Top Left/Top Right, Center, A, B, X, Y
        CtrlC = control[4]      #Left Trigger (0-255)
        CtrlD = control[5]      #Right Trigger (0-255)
        CtrlEH = control[6:10]  #Left Stick
        CtrlIL = control[10:14] #Right Stick
        print control
        if CtrlA ==0:
            print "No Input"
        elif CtrlA == 1:
            print "Directional Pad: Up"
        elif CtrlA == 2:
            print "Directional Pad: Down"
        elif CtrlA == 4:
            print "Directional Pad: Left"
        elif CtrlA == 8:
            print "Directional Pad: Right"  
        elif CtrlA == 16:
            print "Right Center Button"
        elif CtrlA == 32:
            print "Left Center Button"
        elif CtrlA == 64:
            print "Left Stick Pressed"
        elif CtrlA == 128:
            print "Right Stick Pressed"
        elif CtrlA == 192:
            print "Right & Left Sticks Pressed"
        else:
            break

        if CtrlC == 0:
            print "Left Trigger: No Input"
        elif 1 <= CtrlC <=254:
            print "Left Trigger: " + "{:.0%}".format(CtrlC/255)
        elif CtrlC == 255:
            print "Left Trigger: Max"
        else:
            break


        if CtrlD == 0:
            print "Right Trigger: No Input"
        elif 1 <= CtrlD <=254:
            print "Right Trigger: " + "{:.0%}".format(CtrlD/255)
        elif CtrlD == 255:
            print "Right Trigger: Max"
        else:
            break

except:
pass

#Let Ctrl+C actually exit.
time.sleep(0.01)

Снова Мой желаемый результат - чтобы программа определяла комбинацию нажатых кнопок. Например, если значение для control[3] равно 17, есть ли способ, чтобы программа эффективно определяла, что это комбинация присвоенные значения 16 и 1 (кнопка «A» и кнопка «вверху слева»)?

Возможно, я рассмотрел использование CSV-файла, itertools (перестановки, комбинации и т. д. *) 1055 *.), Встроенные списки и другие подобные возможные решения. На первый взгляд, все это, кажется, где-то на уровне того, что я хочу сделать. К сожалению, ни один из них (по крайней мере, сам по себе), кажется, не достиг цели. Для меня это совершенно неисследованная область программирования, и мы будем благодарны за любые рекомендации.

Ответы [ 2 ]

0 голосов
/ 14 февраля 2020

Если значение для элемента управления [3] равно 17, существует ли способ, позволяющий программе эффективно определить, что это комбинация присвоенных значений 16 и 1

Это интересная часть вопроса. И ответ «да». Возможно, вы заметили, что отдельные значения (1, 2, 4, 8, 16, 32, 64 ...) являются степенями 2 (2**1, 2**2, 2**3...). Это означает, что объединенные значения можно рассматривать как двоичные цифры. Поэтому, если я дал вам 40, единственный способ показать, что использование степеней 2 - это 32 + 8. В двоичном виде это 101000. Если вы хотите получить это в Python, то (по крайней мере, в Python3) вы можете do bin(40), которая печатает строку '0b10001'.

Что касается того, как максимально использовать это, я отложу ответ арт-солопова.

0 голосов
/ 14 февраля 2020

Вот что я бы сделал.

Я бы назначил каждой кнопке свой собственный набор позиции и значения, например:

buttons = [
    ('dir_up', 2, 1),
    ('dir_down', 2, 2),
    ('dir_left', 2, 4),
    ('dir_right', 2, 8),
    # ... etc, other buttons here
]

Затем вы можете увидеть, какие кнопки на самом деле нажата с генератором:

def pressed_buttons(control):
    for button in buttons:
        name, control_pos, value = button
        # To check if the button was pressed, perform a binary masking
        if control[control_pos] & value == value:
            yield button

PS Для большей ясности, вы можете найти namedtuples или даже перечисления полезными.

...