diff --git a/libs/LedKit/CMakeLists.txt b/libs/LedKit/CMakeLists.txt index 1dee5e7e77..7eaa70ef70 100644 --- a/libs/LedKit/CMakeLists.txt +++ b/libs/LedKit/CMakeLists.txt @@ -12,9 +12,10 @@ target_include_directories(LedKit target_sources(LedKit PRIVATE + source/Bubbles.cpp + source/Fly.cpp source/LedKit.cpp source/Singing.cpp - source/Bubbles.cpp ) target_link_libraries(LedKit diff --git a/libs/LedKit/include/internal/Fly.h b/libs/LedKit/include/internal/Fly.h new file mode 100644 index 0000000000..a46e9cf1c5 --- /dev/null +++ b/libs/LedKit/include/internal/Fly.h @@ -0,0 +1,64 @@ +// Leka - LekaOS +// Copyright 2022 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +// + Stage 0 + Stage 1 + Stage 2 + 3 + 4 +5 + 6 + 7 + +// | | | | | | | | | +// | | | | | | | | | +// | | |\ | | || | || | --- White +// | | /| \ | | |\ | || | +// | | / | \ | | /| || / || | +// | | / | \ | | || || | || | +// | | / | \ | | || \| | |\ | +// | | / | \ | | || |/ | | | +// | | / | \ | | / | || | | | +// | | / | \ | | | | | | \ | +// | | / | \ | | | | | | | | +// | | / | \ | | / | | | \ | +// | | / | \ | | | | | | || +// | | / | \ | | | | | | || +// | | / | \ | | | | | | \| +// | |/ | \| |/ | | | | +// |-----------| | |-------| | | | | --- Black +// | | | | | | | | | + +#pragma once + +// ? LCOV_EXCL_START - Exclude from coverage report + +#include "LEDAnimation.h" + +namespace leka::led::animation { + +class Fly : public interface::LEDAnimation +{ + public: + explicit Fly(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 = 0; + + [[nodiscard]] auto mapStep(uint8_t step, uint8_t val) const -> float; + + void stage0(); + void stage1(); + void stage2(); + void stage3(); + void stage4(); + void stage5(); + void stage6(); + void stage7(); + + void turnLedBlack(); +}; + +} // namespace leka::led::animation + +// ? LCOV_EXCL_STOP - Exclude from coverage report diff --git a/libs/LedKit/source/Fly.cpp b/libs/LedKit/source/Fly.cpp new file mode 100644 index 0000000000..882ba8cad1 --- /dev/null +++ b/libs/LedKit/source/Fly.cpp @@ -0,0 +1,170 @@ +// Leka - LekaOS +// Copyright 2022 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +// ? LCOV_EXCL_START - Exclude from coverage report + +#include "Fly.h" + +#include "MathUtils.h" + +namespace leka::led::animation { + +static constexpr auto kThresholdDown = 0.3F; + +void Fly::start() +{ + turnLedBlack(); +} + +void Fly::stop() +{ + turnLedBlack(); +} + +void Fly::run() +{ + switch (_stage) { + case 0: + stage0(); + break; + 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 Fly::mapStep(uint8_t step, uint8_t val) const -> float +{ + return utils::math::map(step, uint8_t {0}, val, 0.F, 1.F); +} + +void Fly::stage0() +{ + static constexpr auto kInputMaxStage0 = 50; + if (auto pos = mapStep(_step, kInputMaxStage0); pos != 1.F) { + ++_step; + } else { + _step = 0; + ++_stage; + } +} + +void Fly::stage1() +{ + static constexpr auto kInputMaxStage1to2 = 30; + if (auto pos = mapStep(_step, kInputMaxStage1to2); pos != 1.F) { + RGB color = ColorKit::colorGradient(RGB::black, RGB::white, pos); + _belt.setColor(color); + ++_step; + } else { + ++_stage; + } +} + +void Fly::stage2() +{ + static constexpr auto kInputMaxStage1to2 = 30; + if (auto pos = mapStep(_step, kInputMaxStage1to2); pos != 0.F) { + RGB color = ColorKit::colorGradient(RGB::black, RGB::white, pos); + _belt.setColor(color); + --_step; + } else { + _step = 0; + ++_stage; + } +} + +void Fly::stage3() +{ + static constexpr auto kInputMaxStage3 = 10; + if (auto pos = mapStep(_step, kInputMaxStage3); pos != 1.F) { + ++_step; + } else { + _step = 0; + ++_stage; + } +} + +void Fly::stage4() +{ + static constexpr auto kInputMaxValue4to7 = 6; + if (auto pos = mapStep(_step, kInputMaxValue4to7); pos != 1.F) { + RGB color = ColorKit::colorGradient(RGB::black, RGB::white, pos); + _belt.setColor(color); + ++_step; + } else { + ++_stage; + } +} + +void Fly::stage5() +{ + static constexpr auto kInputMaxValue4to7 = 6; + if (auto pos = mapStep(_step, kInputMaxValue4to7); pos >= kThresholdDown) { + RGB color = ColorKit::colorGradient(RGB::black, RGB::white, pos); + _belt.setColor(color); + --_step; + } else { + ++_stage; + } +} + +void Fly::stage6() +{ + static constexpr auto kInputMaxValue4to7 = 6; + if (auto pos = mapStep(_step, kInputMaxValue4to7); pos != 1.F) { + RGB color = ColorKit::colorGradient(RGB::black, RGB::white, pos); + _belt.setColor(color); + ++_step; + } else { + ++_stage; + } +} + +void Fly::stage7() +{ + static constexpr auto kInputMaxValue4to7 = 6; + if (auto pos = mapStep(_step, kInputMaxValue4to7); pos != 0.F) { + RGB color = ColorKit::colorGradient(RGB::black, RGB::white, pos); + _belt.setColor(color); + --_step; + } else { + RGB color = ColorKit::colorGradient(RGB::black, RGB::white, pos); + _belt.setColor(color); + ++_stage; + } +} + +void Fly::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 22d1c6a14a..7e56cb99e3 100644 --- a/spikes/lk_led_kit/main.cpp +++ b/spikes/lk_led_kit/main.cpp @@ -10,6 +10,7 @@ #include "Bubbles.h" #include "CoreLED.h" #include "CoreSPI.h" +#include "Fly.h" #include "HelloWorld.h" #include "LedKit.h" #include "LogKit.h" @@ -28,8 +29,10 @@ auto animation_thread = rtos::Thread {}; auto animation_event_queue = events::EventQueue {}; auto ledkit = LedKit {animation_thread, animation_event_queue, ears, belt}; + led::animation::Bubbles animation_bubbles(ears, belt); led::animation::Singing animation_singing(ears, belt); +led::animation::Fly animation_fly {ears, belt}; HelloWorld hello; @@ -43,7 +46,9 @@ auto main() -> int while (true) { ledkit.start(animation_singing); - rtos::ThisThread::sleep_for(40s); + rtos::ThisThread::sleep_for(10s); + ledkit.start(animation_fly); + rtos::ThisThread::sleep_for(10s); ledkit.stop(); rtos::ThisThread::sleep_for(1s);