From d706c906c3b90bb0ee2e9977702ca0cdef02faa9 Mon Sep 17 00:00:00 2001 From: Padraig O Conbhui Date: Fri, 8 Jul 2016 08:35:45 +0100 Subject: [PATCH 1/3] Add controller "splash" on connection --- ds4drv/actions/__init__.py | 1 + ds4drv/actions/splash.py | 68 ++++++++++++++++++++++++++++++++++++++ ds4drv/device.py | 12 +++++-- 3 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 ds4drv/actions/splash.py diff --git a/ds4drv/actions/__init__.py b/ds4drv/actions/__init__.py index 2d37a0c..afaa60b 100644 --- a/ds4drv/actions/__init__.py +++ b/ds4drv/actions/__init__.py @@ -7,3 +7,4 @@ from . import input from . import led from . import status +from . import splash diff --git a/ds4drv/actions/splash.py b/ds4drv/actions/splash.py new file mode 100644 index 0000000..5ce4909 --- /dev/null +++ b/ds4drv/actions/splash.py @@ -0,0 +1,68 @@ +from ..action import Action + +from time import sleep + + +Action.add_option("--no-splash", action="store_true", + help="Disable rumbling controller and flashing LEDs on connection.") + + +class ActionSplash(Action): + """Rumble controller and flash LEDs on connection.""" + + def load_options(self, options): + if not self.controller.device: + return + + if options.no_splash == True: + return + + def interpolate_leds(l1, l2, n): + diff = ( + (l2[0] - l1[0])/n, + (l2[1] - l1[1])/n, + (l2[2] - l1[2])/n + ) + for i in range(n): + yield ( + l1[0] + diff[0]*i, + l1[1] + diff[1]*i, + l1[2] + diff[2]*i + ) + + splash_time = 1 + splash_frame_counts = [10, 10, 10, 10] + splash_frame_time = splash_time/sum(splash_frame_counts) + + big_rumble = 255 + small_rumble = 255 + + self.controller.device.rumble(small_rumble, big_rumble) + for led in interpolate_leds( + (0, 0, 0), (255, 255, 0), splash_frame_counts[0] + ): + self.controller.device.set_led(*tuple(map(int, led))) + sleep(splash_frame_time) + + self.controller.device.rumble(0, 0) + for led in interpolate_leds( + (255, 255, 0), (0, 255, 255), splash_frame_counts[1] + ): + self.controller.device.set_led(*tuple(map(int, led))) + sleep(splash_frame_time) + + self.controller.device.rumble(small_rumble, big_rumble) + for led in interpolate_leds( + (0, 255, 255), (0, 0, 0), splash_frame_counts[2] + ): + self.controller.device.set_led(*tuple(map(int, led))) + sleep(splash_frame_time) + + self.controller.device.rumble(0, 0) + for led in interpolate_leds( + (0, 0, 0), options.led, splash_frame_counts[2] + ): + self.controller.device.set_led(*tuple(map(int, led))) + sleep(splash_frame_time) + + self.controller.device.set_led(*(options.led)) diff --git a/ds4drv/device.py b/ds4drv/device.py index 5ac471b..564ddbe 100644 --- a/ds4drv/device.py +++ b/ds4drv/device.py @@ -81,16 +81,24 @@ def __init__(self, device_name, device_addr, type): self._led_flash = (0, 0) self._led_flashing = False + self._small_rumble = 0 + self._big_rumble = 0 + self.set_operational() def _control(self, **kwargs): self.control(led_red=self._led[0], led_green=self._led[1], led_blue=self._led[2], flash_led1=self._led_flash[0], - flash_led2=self._led_flash[1], **kwargs) + flash_led2=self._led_flash[1], + big_rumble = self._big_rumble, + small_rumble = self._small_rumble, + **kwargs) def rumble(self, small=0, big=0): """Sets the intensity of the rumble motors. Valid range is 0-255.""" - self._control(small_rumble=small, big_rumble=big) + self._big_rumble = big + self._small_rumble = small + self._control() def set_led(self, red=0, green=0, blue=0): """Sets the LED color. Values are RGB between 0-255.""" From ad0c09915b2435b250c8bc951ceef9a625684baa Mon Sep 17 00:00:00 2001 From: Padraig O Conbhui Date: Sat, 9 Jul 2016 15:48:31 +0100 Subject: [PATCH 2/3] Splashes only on device connection. --- ds4drv/actions/splash.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/ds4drv/actions/splash.py b/ds4drv/actions/splash.py index 5ce4909..1813484 100644 --- a/ds4drv/actions/splash.py +++ b/ds4drv/actions/splash.py @@ -10,11 +10,14 @@ class ActionSplash(Action): """Rumble controller and flash LEDs on connection.""" - def load_options(self, options): - if not self.controller.device: - return + def __init__(self, *args, **kwargs): + super(ActionSplash, self).__init__(*args, **kwargs) + + self.led = (0, 0, 1) + self.no_splash = False - if options.no_splash == True: + def setup(self, device): + if self.no_splash == True: return def interpolate_leds(l1, l2, n): @@ -39,7 +42,7 @@ def interpolate_leds(l1, l2, n): self.controller.device.rumble(small_rumble, big_rumble) for led in interpolate_leds( - (0, 0, 0), (255, 255, 0), splash_frame_counts[0] + self.led, (255, 255, 0), splash_frame_counts[0] ): self.controller.device.set_led(*tuple(map(int, led))) sleep(splash_frame_time) @@ -60,9 +63,13 @@ def interpolate_leds(l1, l2, n): self.controller.device.rumble(0, 0) for led in interpolate_leds( - (0, 0, 0), options.led, splash_frame_counts[2] + (0, 0, 0), self.led, splash_frame_counts[2] ): self.controller.device.set_led(*tuple(map(int, led))) sleep(splash_frame_time) - self.controller.device.set_led(*(options.led)) + self.controller.device.set_led(*(self.led)) + + def load_options(self, options): + self.led = options.led + self.no_splash = options.no_splash From 076ea3e2bc933413597bf2f2364ecf4b6ab6c4fe Mon Sep 17 00:00:00 2001 From: Padraig O Conbhui Date: Sat, 9 Jul 2016 16:28:54 +0100 Subject: [PATCH 3/3] Changed splash frame duration and rumbles. Cleaned up splashing code. --- ds4drv/actions/splash.py | 103 ++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/ds4drv/actions/splash.py b/ds4drv/actions/splash.py index 1813484..9344acd 100644 --- a/ds4drv/actions/splash.py +++ b/ds4drv/actions/splash.py @@ -1,5 +1,6 @@ from ..action import Action +from collections import namedtuple from time import sleep @@ -16,57 +17,67 @@ def __init__(self, *args, **kwargs): self.led = (0, 0, 1) self.no_splash = False + @staticmethod + def interpolate_leds(l1, l2, n): + diff = ( + (l2[0] - l1[0])/n, + (l2[1] - l1[1])/n, + (l2[2] - l1[2])/n + ) + + for i in range(n): + yield ( + l1[0] + diff[0]*i, + l1[1] + diff[1]*i, + l1[2] + diff[2]*i + ) + def setup(self, device): if self.no_splash == True: return - def interpolate_leds(l1, l2, n): - diff = ( - (l2[0] - l1[0])/n, - (l2[1] - l1[1])/n, - (l2[2] - l1[2])/n + splash_time = 0.5 + + # Define key frames + high_rumble = (255, 63) # (small_rumble, big_rumble) + low_rumble = (0, 0) + + Frame = namedtuple('Frame', ['led', 'rumble']) + + splash_key_frames = [ + Frame(led = self.led, rumble = high_rumble), + Frame(led = (255, 255, 0), rumble = low_rumble), + Frame(led = (0, 255, 255), rumble = high_rumble), + Frame(led = (0, 0, 0), rumble = low_rumble), + Frame(led = self.led, rumble = low_rumble) + ] + splash_frame_counts = [4, 6, 8, 4] + + + # Build all frames + splash_frames = [] + for i, nframes in enumerate(splash_frame_counts): + frame_leds = self.interpolate_leds( + splash_key_frames[i].led, splash_key_frames[i+1].led, + nframes ) - for i in range(n): - yield ( - l1[0] + diff[0]*i, - l1[1] + diff[1]*i, - l1[2] + diff[2]*i - ) - - splash_time = 1 - splash_frame_counts = [10, 10, 10, 10] - splash_frame_time = splash_time/sum(splash_frame_counts) - - big_rumble = 255 - small_rumble = 255 - - self.controller.device.rumble(small_rumble, big_rumble) - for led in interpolate_leds( - self.led, (255, 255, 0), splash_frame_counts[0] - ): - self.controller.device.set_led(*tuple(map(int, led))) - sleep(splash_frame_time) - - self.controller.device.rumble(0, 0) - for led in interpolate_leds( - (255, 255, 0), (0, 255, 255), splash_frame_counts[1] - ): - self.controller.device.set_led(*tuple(map(int, led))) - sleep(splash_frame_time) - - self.controller.device.rumble(small_rumble, big_rumble) - for led in interpolate_leds( - (0, 255, 255), (0, 0, 0), splash_frame_counts[2] - ): - self.controller.device.set_led(*tuple(map(int, led))) - sleep(splash_frame_time) - - self.controller.device.rumble(0, 0) - for led in interpolate_leds( - (0, 0, 0), self.led, splash_frame_counts[2] - ): - self.controller.device.set_led(*tuple(map(int, led))) - sleep(splash_frame_time) + frame_rumbles = [splash_key_frames[i].rumble] * nframes + + for led, rumble in zip(frame_leds, frame_rumbles): + splash_frames.append(Frame(led = led, rumble = rumble)) + + + # Play frames + splash_frame_duration = splash_time/len(splash_frames) + + for splash_frame in splash_frames: + frame_led = tuple(map(int, splash_frame.led)) + frame_rumble = tuple(map(int, splash_frame.rumble)) + + self.controller.device.set_led(*frame_led) + self.controller.device.rumble(*frame_rumble) + + sleep(splash_frame_duration) self.controller.device.set_led(*(self.led))