Skip to content

Commit 4974253

Browse files
authored
EV3-G API: touch sensor add is_released (#367)
* EV3-G API: touch sensor add is_released * Replace TABs with spaces * TouchSensor: add wait_for_pressed, etc * MODES to use MODE_TOUCH constant * Only decrement timeout_ms when it is not None * Simplify wait_for_press logic
1 parent 6f8f6af commit 4974253

File tree

1 file changed

+79
-41
lines changed

1 file changed

+79
-41
lines changed

ev3dev/core.py

Lines changed: 79 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,15 @@ def list_device_names(class_path, name_pattern, **kwargs):
6767
provided parameters.
6868
6969
Parameters:
70-
class_path: class path of the device, a subdirectory of /sys/class.
71-
For example, '/sys/class/tacho-motor'.
72-
name_pattern: pattern that device name should match.
73-
For example, 'sensor*' or 'motor*'. Default value: '*'.
74-
keyword arguments: used for matching the corresponding device
75-
attributes. For example, address='outA', or
76-
driver_name=['lego-ev3-us', 'lego-nxt-us']. When argument value
77-
is a list, then a match against any entry of the list is
78-
enough.
70+
class_path: class path of the device, a subdirectory of /sys/class.
71+
For example, '/sys/class/tacho-motor'.
72+
name_pattern: pattern that device name should match.
73+
For example, 'sensor*' or 'motor*'. Default value: '*'.
74+
keyword arguments: used for matching the corresponding device
75+
attributes. For example, address='outA', or
76+
driver_name=['lego-ev3-us', 'lego-nxt-us']. When argument value
77+
is a list, then a match against any entry of the list is
78+
enough.
7979
"""
8080

8181
if not os.path.isdir(class_path):
@@ -266,15 +266,15 @@ def list_devices(class_name, name_pattern, **kwargs):
266266
arguments.
267267
268268
Parameters:
269-
class_name: class name of the device, a subdirectory of /sys/class.
270-
For example, 'tacho-motor'.
271-
name_pattern: pattern that device name should match.
272-
For example, 'sensor*' or 'motor*'. Default value: '*'.
273-
keyword arguments: used for matching the corresponding device
274-
attributes. For example, address='outA', or
275-
driver_name=['lego-ev3-us', 'lego-nxt-us']. When argument value
276-
is a list, then a match against any entry of the list is
277-
enough.
269+
class_name: class name of the device, a subdirectory of /sys/class.
270+
For example, 'tacho-motor'.
271+
name_pattern: pattern that device name should match.
272+
For example, 'sensor*' or 'motor*'. Default value: '*'.
273+
keyword arguments: used for matching the corresponding device
274+
attributes. For example, address='outA', or
275+
driver_name=['lego-ev3-us', 'lego-nxt-us']. When argument value
276+
is a list, then a match against any entry of the list is
277+
enough.
278278
"""
279279
classpath = abspath(Device.DEVICE_ROOT_PATH + '/' + class_name)
280280

@@ -1038,13 +1038,13 @@ def list_motors(name_pattern=Motor.SYSTEM_DEVICE_NAME_CONVENTION, **kwargs):
10381038
the provided arguments.
10391039
10401040
Parameters:
1041-
name_pattern: pattern that device name should match.
1042-
For example, 'motor*'. Default value: '*'.
1043-
keyword arguments: used for matching the corresponding device
1044-
attributes. For example, driver_name='lego-ev3-l-motor', or
1045-
address=['outB', 'outC']. When argument value
1046-
is a list, then a match against any entry of the list is
1047-
enough.
1041+
name_pattern: pattern that device name should match.
1042+
For example, 'motor*'. Default value: '*'.
1043+
keyword arguments: used for matching the corresponding device
1044+
attributes. For example, driver_name='lego-ev3-l-motor', or
1045+
address=['outB', 'outC']. When argument value
1046+
is a list, then a match against any entry of the list is
1047+
enough.
10481048
"""
10491049
class_path = abspath(Device.DEVICE_ROOT_PATH + '/' + Motor.SYSTEM_CLASS_NAME)
10501050

@@ -2143,11 +2143,11 @@ def list_sensors(name_pattern=Sensor.SYSTEM_DEVICE_NAME_CONVENTION, **kwargs):
21432143
provided arguments.
21442144
21452145
Parameters:
2146-
name_pattern: pattern that device name should match.
2147-
For example, 'sensor*'. Default value: '*'.
2148-
keyword arguments: used for matching the corresponding device
2149-
attributes. For example, driver_name='lego-ev3-touch', or
2150-
address=['in1', 'in3']. When argument value is a list,
2146+
name_pattern: pattern that device name should match.
2147+
For example, 'sensor*'. Default value: '*'.
2148+
keyword arguments: used for matching the corresponding device
2149+
attributes. For example, driver_name='lego-ev3-touch', or
2150+
address=['in1', 'in3']. When argument value is a list,
21512151
then a match against any entry of the list is enough.
21522152
"""
21532153
class_path = abspath(Device.DEVICE_ROOT_PATH + '/' + Sensor.SYSTEM_CLASS_NAME)
@@ -2202,24 +2202,20 @@ class TouchSensor(Sensor):
22022202
Touch Sensor
22032203
"""
22042204

2205-
__slots__ = ['auto_mode']
2205+
__slots__ = ['auto_mode', '_poll', '_value0']
22062206

22072207
SYSTEM_CLASS_NAME = Sensor.SYSTEM_CLASS_NAME
22082208
SYSTEM_DEVICE_NAME_CONVENTION = Sensor.SYSTEM_DEVICE_NAME_CONVENTION
22092209

2210-
def __init__(self, address=None, name_pattern=SYSTEM_DEVICE_NAME_CONVENTION, name_exact=False, **kwargs):
2211-
super(TouchSensor, self).__init__(address, name_pattern, name_exact, driver_name=['lego-ev3-touch', 'lego-nxt-touch'], **kwargs)
2212-
self.auto_mode = True
2213-
2214-
22152210
#: Button state
22162211
MODE_TOUCH = 'TOUCH'
2212+
MODES = (MODE_TOUCH,)
22172213

2218-
2219-
MODES = (
2220-
'TOUCH',
2221-
)
2222-
2214+
def __init__(self, address=None, name_pattern=SYSTEM_DEVICE_NAME_CONVENTION, name_exact=False, **kwargs):
2215+
super(TouchSensor, self).__init__(address, name_pattern, name_exact, driver_name=['lego-ev3-touch', 'lego-nxt-touch'], **kwargs)
2216+
self.auto_mode = True
2217+
self._poll = None
2218+
self._value0 = None
22232219

22242220
@property
22252221
def is_pressed(self):
@@ -2233,6 +2229,48 @@ def is_pressed(self):
22332229

22342230
return self.value(0)
22352231

2232+
@property
2233+
def is_released(self):
2234+
return not self.is_pressed
2235+
2236+
def _wait(self, wait_for_press, timeout_ms):
2237+
tic = time.time()
2238+
2239+
if self._poll is None:
2240+
self._value0 = self._attribute_file_open('value0')
2241+
self._poll = select.poll()
2242+
self._poll.register(self._value0, select.POLLPRI)
2243+
2244+
while True:
2245+
self._poll.poll(timeout_ms)
2246+
2247+
if self.is_pressed == wait_for_press:
2248+
return True
2249+
2250+
if timeout_ms is not None and time.time() >= tic + timeout_ms / 1000:
2251+
return False
2252+
2253+
def wait_for_pressed(self, timeout_ms=None):
2254+
return self._wait(True, timeout_ms)
2255+
2256+
def wait_for_released(self, timeout_ms=None):
2257+
return self._wait(False, timeout_ms)
2258+
2259+
def wait_for_bump(self, timeout_ms=None):
2260+
"""
2261+
Wait for the touch sensor to be pressed down and then released.
2262+
Both actions must happen within timeout_ms.
2263+
"""
2264+
start_time = time.time()
2265+
2266+
if self.wait_for_pressed(timeout_ms):
2267+
if timeout_ms is not None:
2268+
timeout_ms -= int((time.time() - start_time) * 1000)
2269+
return self.wait_for_released(timeout_ms)
2270+
2271+
return False
2272+
2273+
22362274
class ColorSensor(Sensor):
22372275

22382276
"""

0 commit comments

Comments
 (0)