簡體   English   中英

SF30 控制器 Bluez 編程

[英]SF30 Controller Bluez Programming

Bluez 問題:我有一個 Raspberry Pi ZW、一個 8bitdo SF30 藍牙控制器和一個我的雇主批量生產的機器人。 我希望通過遙控器從 RPI 控制機器人。

我使用 bluetoothctl 將 RPi 連接到控制器,並且我可以通過 btmon(藍牙監視器)查看來自控制器的消息。 很明顯,下面的四個“80”值對應於兩個操縱桿的中點。

> ACL Data RX: Handle 11 flags 0x02 dlen 15                         #30 [hci0] 2.555574
      Channel: 65 len 11 [PSM 0 mode Basic (0x00)] {chan 65535}
        a1 03 0f 80 80 12 31 00 00 00 00                 ......1....     
> ACL Data RX: Handle 11 flags 0x02 dlen 15                         #31 [hci0] 2.587293
      Channel: 65 len 11 [PSM 0 mode Basic (0x00)] {chan 65535}
        a1 03 0f 80 80 27 4b 00 00 00 00                 .....'K....     
> ACL Data RX: Handle 11 flags 0x02 dlen 15                         #32 [hci0] 2.613543
      Channel: 65 len 11 [PSM 0 mode Basic (0x00)] {chan 65535}
        a1 03 0f 80 80 61 7b 00 00 00 00                 .....a{....     
> ACL Data RX: Handle 11 flags 0x02 dlen 15                         #33 [hci0] 2.615552
      Channel: 65 len 11 [PSM 0 mode Basic (0x00)] {chan 65535}
        a1 03 0f 80 80 80 80 00 00 00 00                 ...........     
> ACL Data RX: Handle 11 flags 0x02 dlen 15                         #34 [hci0] 74.653567
      Channel: 65 len 11 [PSM 0 mode Basic (0x00)] {chan 65535}
        a1 03 0f 80 80 80 80 00 00 00 08                 ...........

我還一直在使用格式 LLHHQ 從 Python 中的兩個結果 /dev/input/ 文件(/dev/input/js0 和 /dev/input/event0)中讀取數據。 我認為來自 btmon(易於解釋)的相同數據將在該格式的 Q 部分(下面的最后一個數字)中表示。

(470898350, 155732, 22190, 7185, 16919435)
(470898350, 160124, 22190, 7185, 16916057)
(470898380, 162488, 22220, 7185, 163502)
(470898380, 16915382, 22260, 7185, 16910652)
(470898420, 16908288, 22290, 7185, 161137)
(470898450, 16971797, 22300, 7185, 155732)
(470898460, 16966392, 22330, 7185, 154043)
(470898490, 16966054, 22340, 7185, 147287)
(470898500, 16967405, 22340, 7185, 131072)
(470898500, 16908288, 22740, 7185, 151060481)
(470899070, 151060480, 22970, 7185, 134283265)
(470899320, 134283264, 23200, 7185, 117506049)
(470899550, 117506048, 23420, 7185, 100728833)
(470899750, 100728832, 23590, 7185, 117506049)
(470899910, 117506048, 23930, 7185, 134283265)
(470900310, 134283264, 25110, 7185, 100728833)
(470901380, 117506049, 25250, 7185, 134283265)
(470901490, 100728832, 25390, 7185, 117506048)
(470901710, 134283264, 25580, 7185, 100728833)
(470901750, 117506049, 25720, 7185, 117506048)
(470901940, 134283265, 25810, 7185, 100728832)
(470902160, 100728833, 26070, 7185, 134283264)
(470902400, 100728832, 26690, 7185, 134283265)
(470903070, 134283264, 27130, 7185, 151060481)
(470903430, 151060480, 27360, 7185, 100728833)

然而,這些輸出在讀入二進制時似乎並不對應,例如兩個操縱桿似乎改變了相同的位。

我的問題的基本問題是如何獲取在基於 bluez 的代碼中在 btmon 中讀取的相同數據。

這是我目前使用的python代碼。

f = open( "/dev/input/js0", "rb" ); # Open the file in the read-binary mode
EVENT_SIZE = struct.calcsize("LLHHQ")
while 1:
  data = f.read(EVENT_SIZE)
  unpacked_data = struct.unpack('llHHQ',data)
#  print("Length:" + str(len(unpacked_data)))
#  print(unpacked_data)
  remote_data = unpacked_data[4]
  print(format(remote_data, '064b'))

使用像evdev這樣的庫可能會有所幫助,因為它可以為您完成很多繁重的工作。

使用它的示例可能是:

from time import sleep

from pydbus import SystemBus
import evdev

# For testing
# python3 -m evdev.evtest


class Controller:
    def __init__(self, adapter_int=0):
        adapter_path = '/org/bluez/hci{}'.format(adapter_int)
        self.dbus = SystemBus()
        self.adapter = self.dbus.get('org.bluez', adapter_path)
        # Use bluetoothctl to find out what the path is for your controller
        self.controller = self.dbus.get('org.bluez', '/org/bluez/hci0/dev_DC_0C_2D_20_DA_E8')
        print('Waiting for connection from DC:0C:2D:20:DA:E8')
        # self.controller.Discoverable = True
        while not self.controller.Connected:
            sleep(1)
        print('Connected')
        sleep(6)
        # https://python-evdev.readthedocs.io/en/latest/tutorial.html to get path of your controller
        self.device = evdev.InputDevice('/dev/input/event2')
        self.max_value = 0
        self.min_value = 255
        self.max_throttle = 1
        self.min_throttle = -1
        self.right_steering = 1
        self.left_steering = -1

    def map_throttle(self, value):
        input_range = self.max_value - self.min_value
        output_range = self.max_throttle - self.min_throttle
        input_percentage = (value - self.min_value) / input_range
        output_value = (output_range * input_percentage) + self.min_throttle
        return round(output_value, 2)

    def map_steering(self, value):
        input_range = self.max_value - self.min_value
        output_range = self.right_steering - self.left_steering
        input_percentage = (value - self.min_value) / input_range
        output_value = (output_range * input_percentage) + self.left_steering
        return round(output_value, 2)

    def get_events(self):
        for event in self.device.read_loop():
            ly = None
            rx = None
            btn = None
            if event.type == evdev.ecodes.EV_ABS:
                if event.code == 1:
                    # print('Left:', event.value)
                    ly = self.map_throttle(event.value)
                if event.code == 3:
                    # print('Right:', event.value)
                    rx = self.map_steering(event.value)
            if event.type == evdev.ecodes.EV_KEY:
                if event.code == evdev.ecodes.BTN_SOUTH and event.value == 0:
                    btn = 'BTN_SOUTH'
                elif event.code == evdev.ecodes.BTN_WEST and event.value == 0:
                    btn = 'BTN_WEST'
                elif event.code == evdev.ecodes.BTN_NORTH and event.value == 0:
                    btn = 'BTN_NORTH'
                elif event.code == evdev.ecodes.BTN_EAST and event.value == 0:
                    btn = 'BTN_EAST'
            yield ly, rx, btn


if __name__ == '__main__':
    ctrl = Controller()
    for speed, steer, action in ctrl.get_events():
        print('Speed: {}, Steer: {}, Button: {}'.format(speed, steer, action))

如果你想更上一層樓,那么像https://github.com/ApproxEng/approxeng.input這樣的庫是一個流行的庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM