diff --git a/libs/LedKit/CMakeLists.txt b/libs/LedKit/CMakeLists.txt index 28a92ae7c1..e446bbf842 100644 --- a/libs/LedKit/CMakeLists.txt +++ b/libs/LedKit/CMakeLists.txt @@ -14,6 +14,7 @@ target_sources(LedKit PRIVATE source/AfraidBlue.cpp source/AfraidRed.cpp + source/Angry.cpp source/AngryShort.cpp source/Bubbles.cpp source/Disgusted.cpp diff --git a/libs/LedKit/include/internal/Angry.h b/libs/LedKit/include/internal/Angry.h new file mode 100644 index 0000000000..5181cc54e7 --- /dev/null +++ b/libs/LedKit/include/internal/Angry.h @@ -0,0 +1,73 @@ +// Leka - LekaOS +// Copyright 2022 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +// + Stage 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + +// | | | | | | | | | | | | +// | | | | | | | | | | | | +// | || | || | || | || | |-----------| | +// | /|\ | || | /|\ | /|\ | /| | | +// | || | | / || | || | | || | | || || | +// | / | \ | | |\ | / | \ | / | \ | / | |\ | +// | | | | | / | | | | | | | | | | | | | | | | +// | / | | | | | | | / | \ | / | \ | / | | \ | +// | | | \ | | | \ | | | | | | | | | | | | | | +// | / | | |/ | || / | \ | / | \ | / | | \ | +// | | | \ || | \| | | || | | || | | | | | +// | / | || | |/ | \|/ | \|/ | | \ | +// | | | || | || | || | || | | | | +// | / | | | | | | | | | | \ | +// | | | | | | | | | | | | | | +// | / | | | | | | | | | | \ | +// | | | | | | | | | | | | | | +// | / | | | | | | | | | | \ | +// | | | | | | | | | | | | || +// |/ | | | | | | | | | | \| +// || | | | | | | | | | | | +// | | | | | | | | | | | | +// | | + +#pragma once + +// ? LCOV_EXCL_START - Exclude from coverage report + +#include "LEDAnimation.h" + +namespace leka::led::animation { + +class Angry : public interface::LEDAnimation +{ + public: + explicit Angry(interface::LED &ears, interface::LED &belt) : _ears(ears), _belt(belt) {}; + + void start() final; + void run() final; + void stop() final; + + private: + interface::LED &_ears; + interface::LED &_belt; + uint8_t _step = 0; + uint8_t _stage = 1; + + [[nodiscard]] auto mapStep(uint8_t step) const -> float; + + void stage1(); + void stage2(); + void stage3(); + void stage4(); + void stage5(); + void stage6(); + void stage7(); + void stage8(); + void stage9(); + + void increaseBrightness(float treshold); + void decreaseBrightness(float treshold); + + void turnLedBlack(); +}; + +} // namespace leka::led::animation + +// ? LCOV_EXCL_STOP - Exclude from coverage report diff --git a/libs/LedKit/source/Angry.cpp b/libs/LedKit/source/Angry.cpp new file mode 100644 index 0000000000..87f8a7cd9b --- /dev/null +++ b/libs/LedKit/source/Angry.cpp @@ -0,0 +1,133 @@ +// Leka - LekaOS +// Copyright 2022 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +// ? LCOV_EXCL_START - Exclude from coverage report + +#include "Angry.h" + +#include "MathUtils.h" + +namespace leka::led::animation { + +void Angry::start() +{ + turnLedBlack(); +} + +void Angry::stop() +{ + turnLedBlack(); +} + +void Angry::run() +{ + switch (_stage) { + case 1: + stage1(); + break; + case 2: + stage2(); + break; + case 3: + stage3(); + break; + case 4: + stage4(); + break; + case 5: + stage5(); + break; + case 6: + stage6(); + break; + case 7: + stage7(); + break; + default: + break; + } + _belt.show(); +} + +auto Angry::mapStep(uint8_t step) const -> float +{ + constexpr auto kMaxInputValue = uint8_t {60}; + return utils::math::map(step, uint8_t {0}, kMaxInputValue, 0.F, 1.F); +} + +void Angry::stage1() +{ + increaseBrightness(1.F); +} + +void Angry::stage2() +{ + static constexpr auto kTreshold = 0.7F; + decreaseBrightness(kTreshold); +} + +void Angry::stage3() +{ + increaseBrightness(1.F); +} + +void Angry::stage4() +{ + static constexpr auto kTreshold = 0.7F; + decreaseBrightness(kTreshold); +} + +void Angry::stage5() +{ + increaseBrightness(1.F); +} + +void Angry::stage6() +{ + if (auto pos = mapStep(_step); pos != 0.F) { + _step--; + } else { + _step = 60; + _stage++; + } +} + +void Angry::stage7() +{ + decreaseBrightness(0.F); +} + +void Angry::increaseBrightness(float treshold) +{ + if (auto pos = mapStep(_step); pos != treshold) { + RGB color = ColorKit::colorGradient(RGB::black, RGB::pure_red, pos); + _belt.setColor(color); + _step++; + } else { + _stage++; + } +} + +void Angry::decreaseBrightness(float treshold) +{ + if (auto pos = mapStep(_step); pos > treshold) { + RGB color = ColorKit::colorGradient(RGB::black, RGB::pure_red, pos); + _belt.setColor(color); + _step--; + } else { + _stage++; + } +} + +void Angry::turnLedBlack() +{ + _ears.setColor(RGB::black); + _belt.setColor(RGB::black); + _ears.show(); + _belt.show(); +} + +} // namespace leka::led::animation + +// ? LCOV_EXCL_STOP - Exclude from coverage report diff --git a/spikes/lk_led_kit/main.cpp b/spikes/lk_led_kit/main.cpp index 41da6ab2e3..50a4a90c1d 100644 --- a/spikes/lk_led_kit/main.cpp +++ b/spikes/lk_led_kit/main.cpp @@ -9,6 +9,7 @@ #include "AfraidBlue.h" #include "AfraidRed.h" +#include "Angry.h" #include "AngryShort.h" #include "Bubbles.h" #include "CoreLED.h" @@ -39,6 +40,7 @@ auto ledkit = LedKit {animation_thread, animation_event_queue, ears, belt}; led::animation::AfraidBlue animation_afraid_blue(ears, belt); led::animation::AfraidRed animation_afraid_red(ears, belt); +led::animation::Angry animation_angry(ears, belt); led::animation::AngryShort animation_angry_short(ears, belt); led::animation::Bubbles animation_bubbles(ears, belt); led::animation::Disgusted animation_disgusted(ears, belt); @@ -83,6 +85,9 @@ auto main() -> int ledkit.start(animation_angry_short); rtos::ThisThread::sleep_for(10s); + ledkit.start(animation_angry); + rtos::ThisThread::sleep_for(10s); + ledkit.stop(); rtos::ThisThread::sleep_for(1s); }