繁体   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