From 3d46284e6f5b0a95be2a9bc3abe64dca5f8c1f1b Mon Sep 17 00:00:00 2001 From: Dawid Kmak <73443304+KmakD@users.noreply.github.com> Date: Mon, 17 Apr 2023 13:00:33 +0200 Subject: [PATCH] Revert "Light dimmer (#105)" (#106) This reverts commit a521b240b7b8ada7eabb84c07c825d5d9f87bd0c. --- .../src/animation/battery_animation.py | 96 ++++++++----------- 1 file changed, 40 insertions(+), 56 deletions(-) diff --git a/panther_lights/src/animation/battery_animation.py b/panther_lights/src/animation/battery_animation.py index c4716f43f..009086ce7 100644 --- a/panther_lights/src/animation/battery_animation.py +++ b/panther_lights/src/animation/battery_animation.py @@ -13,12 +13,9 @@ def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self._anim = np.zeros((self._anim_len, self.num_led)) - self._h_min = 0.0 # red color - self._h_max = 120.0 / 360.0 # green color + self._h_min = 0.0 + self._h_max = 120.0 self._resolution = 100 - self._end_anim = 0.75 * self._resolution - self._start_fade = 0.80 * self._resolution - self._end_fade = 0.95 * self._resolution self._gaussian_blur_radius = 1.5 def _update_frame(self) -> list: @@ -34,64 +31,51 @@ def set_param(self, value: str) -> None: def _create_anim(self, battery_percent: float) -> None: battery_percent = np.clip(battery_percent, 0.0, 1.0) + # define basic HSV color + h = self._h_min + s = 1.0 + v = 1.0 + frame = np.zeros((self._num_led, 3), dtype=np.uint8) anim = np.zeros((self._resolution, self._num_led, 3), dtype=np.uint8) - color_rising_duration = int(round(battery_percent * self._end_anim / 2.0)) - - if color_rising_duration < 1: - color_rising_duration = 1 - - for i in range(1, self._resolution): - if i <= color_rising_duration: - progress = i / color_rising_duration - frame = self._color_rising(battery_percent, progress) - - elif i <= 2 * color_rising_duration: - progress = (i - color_rising_duration) / color_rising_duration - frame = self._fill_frame(frame, battery_percent, progress) + if self._num_led % 2 == 0: + percent_point = int(round(battery_percent * self._num_led / 2.0)) + else: + percent_point = int(np.ceil(battery_percent * self._num_led / 2.0)) + + # 0.9 was added to hold for some time the final frame of the animation when percentage is 1.0 + display_iterations = battery_percent * self._resolution * 0.9 + + if percent_point < 1: + percent_point = 1 + display_iterations = 1 + + for i in range(self._resolution): + if i <= display_iterations: + anim_ind = round(i / self._resolution * self._num_led / 0.9) + + if anim_ind < percent_point: + frame.fill(0) + ind_1 = int(np.ceil(self._num_led / 2.0 - anim_ind - 1.0)) + ind_2 = int(np.floor(self._num_led / 2.0 + anim_ind)) + h = (self._h_max - self._h_min) * np.sin( + max(0, battery_percent) * np.pi / 2.0 + ) * i / (display_iterations / 2.0) + self._h_min + rgb = np.array(hsv_to_rgb(h / 360.0, s, v)) + frame[ind_1] = np.uint8(rgb * 255.0) + frame[ind_2] = np.uint8(rgb * 255.0) + elif percent_point <= anim_ind < 2 * percent_point: + ind_1 = int(np.ceil(self._num_led / 2.0 - 2.0 * percent_point + anim_ind)) + ind_2 = int( + np.floor(self._num_led / 2.0 + 2.0 * percent_point - anim_ind - 1.0) + ) + frame[ind_1] = np.uint8(rgb * 255.0) + frame[ind_2] = np.uint8(rgb * 255.0) anim[i] = frame - if i > self._start_fade: - progress = (i - self._start_fade) / (self._end_fade - self._start_fade) - progress = min(1.0, progress) - anim[i] = (1 - progress) * frame - # filter to smooth animation and resize to match duration img = Image.fromarray(anim) img = img.filter(ImageFilter.GaussianBlur(self._gaussian_blur_radius)) img = img.resize((self._num_led, self._anim_len)) self._anim = np.array(img) - - def _color_rising(self, battery_percent: float, progress: float) -> np.array: - frame = np.zeros((self._num_led, 3), dtype=np.uint8) - led_to_disp = battery_percent * self._num_led - - middle_led = (self._num_led - 1) / 2 - ind_1 = int(np.ceil(middle_led - progress * led_to_disp / 2.0)) - ind_2 = int(np.floor(middle_led + progress * led_to_disp / 2.0)) - - rgb = self._calculate_color(battery_percent, progress) - frame[ind_1] = rgb - frame[ind_2] = rgb - return frame - - def _fill_frame(self, frame: np.array, battery_percent: float, progress: float) -> np.array: - led_to_disp = battery_percent * self._num_led - - middle_led = (self._num_led - 1) / 2 - ind_1 = int(np.ceil(middle_led - (1 - progress) * led_to_disp / 2.0)) - ind_2 = int(np.floor(middle_led + (1 - progress) * led_to_disp / 2.0)) - - rgb = self._calculate_color(battery_percent) - frame[ind_1] = rgb - frame[ind_2] = rgb - return frame - - def _calculate_color(self, battery_percent: float, progress: float = 1.0) -> tuple: - h = (self._h_max - self._h_min) * np.sin( - battery_percent * np.pi / 2.0 - ) * progress + self._h_min - rgb = np.array(hsv_to_rgb(h, 1.0, 1.0)) - rgb = np.uint8(rgb * 255.0) - return rgb