mirror of
https://github.com/odriverobotics/ODrive.git
synced 2026-09-24 01:23:52 +08:00
robustify python USB discovery/communication
This commit is contained in:
@@ -35,6 +35,12 @@ class USBBulkTransport(odrive.protocol.PacketSource, odrive.protocol.PacketSink)
|
||||
return string
|
||||
|
||||
def init(self):
|
||||
# Under some conditions, the Linux USB/libusb stack ends up in a corrupt
|
||||
# state where there are a few packets in a receive queue but a call
|
||||
# to epr.read() does not return these packet until a new packet arrives.
|
||||
# This undesirable queue can be cleared by resetting the device.
|
||||
self.dev.reset()
|
||||
|
||||
try:
|
||||
if self.dev.is_kernel_driver_active(1):
|
||||
self.dev.detach_kernel_driver(1)
|
||||
@@ -106,7 +112,7 @@ class USBBulkTransport(odrive.protocol.PacketSource, odrive.protocol.PacketSink)
|
||||
else:
|
||||
# Try resetting halt/stall condition
|
||||
try:
|
||||
self.epw.clear_halt()
|
||||
self.epr.clear_halt()
|
||||
except usb.core.USBError:
|
||||
raise odrive.protocol.ChannelBrokenException()
|
||||
# Retry transfer
|
||||
|
||||
+17
-2
@@ -73,11 +73,15 @@ class Event():
|
||||
"""
|
||||
Alternative to threading.Event(), enhanced by the subscribe() function
|
||||
that the original fails to provide.
|
||||
@param Trigger: if supplied, the newly created event will be triggered
|
||||
as soon as the trigger event becomes set
|
||||
"""
|
||||
def __init__(self):
|
||||
def __init__(self, trigger=None):
|
||||
self._evt = threading.Event()
|
||||
self._subscribers = []
|
||||
self._mutex = threading.Lock()
|
||||
if not trigger is None:
|
||||
trigger.subscribe(self.set())
|
||||
|
||||
def is_set(self):
|
||||
return self._evt.is_set()
|
||||
@@ -120,7 +124,18 @@ class Event():
|
||||
self._mutex.release()
|
||||
|
||||
def wait(self, timeout=None):
|
||||
return self._evt.wait(timeout=timeout)
|
||||
if not self._evt.wait(timeout=timeout):
|
||||
raise TimeoutError()
|
||||
|
||||
def trigger_after(self, timeout):
|
||||
"""
|
||||
Triggers the event after the specified timeout.
|
||||
This function returns immediately.
|
||||
"""
|
||||
def delayed_trigger():
|
||||
if not self.wait(timeout=timeout):
|
||||
self.set()
|
||||
threading.Thread(target=delayed_trigger, daemon=True).start()
|
||||
|
||||
def wait_any(*events, timeout=None):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user