diff --git a/app/os/main.cpp b/app/os/main.cpp index 210d0242ce..280451a96b 100644 --- a/app/os/main.cpp +++ b/app/os/main.cpp @@ -42,6 +42,7 @@ #include "EventLoopKit.h" #include "FATFileSystem.h" #include "FirmwareKit.h" +#include "FoodRecognition.h" #include "HelloWorld.h" #include "LedColorRecognition.h" #include "LogKit.h" @@ -342,6 +343,7 @@ namespace activities { auto led_color_recognition = leka::activity::LedColorRecognition(rfidkit, display::videokit, reinforcerkit, leds::belt); auto emotion_recognition = leka::activity::EmotionRecognition(rfidkit, display::videokit, reinforcerkit); + auto food_recognition = leka::activity::FoodRecognition(rfidkit, display::videokit, reinforcerkit); } // namespace internal @@ -352,6 +354,7 @@ namespace activities { {MagicCard::number_2, &internal::picto_color_recognition}, {MagicCard::number_3, &internal::led_color_recognition}, {MagicCard::number_4, &internal::emotion_recognition}, + {MagicCard::number_5, &internal::food_recognition}, }; } // namespace activities diff --git a/libs/ActivityKit/CMakeLists.txt b/libs/ActivityKit/CMakeLists.txt index 6cac331367..a66389b97b 100644 --- a/libs/ActivityKit/CMakeLists.txt +++ b/libs/ActivityKit/CMakeLists.txt @@ -20,6 +20,7 @@ target_sources(ActivityKit source/activities/LedColorRecognition.cpp source/activities/ChooseReinforcer.cpp source/activities/EmotionRecognition.cpp + source/activities/FoodRecognition.cpp ) target_link_libraries(ActivityKit diff --git a/libs/ActivityKit/include/activities/FoodRecognition.h b/libs/ActivityKit/include/activities/FoodRecognition.h new file mode 100644 index 0000000000..42c87f117e --- /dev/null +++ b/libs/ActivityKit/include/activities/FoodRecognition.h @@ -0,0 +1,51 @@ +// Leka - LekaOS +// Copyright 2022 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +// LCOV_EXCL_START + +#include + +#include "RFIDKit.h" +#include "ReinforcerKit.h" +#include "include/Food.h" +#include "interface/Activity.h" +#include "interface/libs/VideoKit.h" + +namespace leka::activity { + +class FoodRecognition : public interface::Activity +{ + public: + explicit FoodRecognition(RFIDKit &rfidkit, interface::VideoKit &videokit, ReinforcerKit &reinforcerkit) + : _rfidkit(rfidkit), _videokit(videokit), _reinforcerkit(reinforcerkit) {}; + + void start() final; + void stop() final; + + private: + void processCard(const MagicCard &card); + void launchNextRound(); + + RFIDKit &_rfidkit; + interface::VideoKit &_videokit; + ReinforcerKit &_reinforcerkit; + + static constexpr uint8_t kScoreToWin = 10; + static constexpr uint8_t kSizeOfFoodsTable = 9 * 2; + + uint8_t _current_round = 0; + std::optional _current_food {}; + std::function _backup_callback {}; + std::array _foods = { + Food::apple, Food::apple, Food::banana, Food::banana, Food::grapes, Food::grapes, + Food::mushroom, Food::mushroom, Food::salad, Food::salad, Food::carrot, Food::carrot, + Food::cherry, Food::cherry, Food::strawberry, Food::strawberry, Food::potato, Food::potato, + }; +}; + +} // namespace leka::activity + +// LCOV_EXCL_STOP diff --git a/libs/ActivityKit/source/activities/FoodRecognition.cpp b/libs/ActivityKit/source/activities/FoodRecognition.cpp new file mode 100644 index 0000000000..223a5b7f86 --- /dev/null +++ b/libs/ActivityKit/source/activities/FoodRecognition.cpp @@ -0,0 +1,56 @@ +// Leka - LekaOS +// Copyright 2022 APF France handicap +// SPDX-License-Identifier: Apache-2.0 + +// LCOV_EXCL_START + +#include "FoodRecognition.h" +#include + +namespace leka::activity { + +void FoodRecognition::start() +{ + _current_round = 0; + _current_food = {}; + + _backup_callback = _rfidkit.getCallback(); + std::shuffle(_foods.begin(), _foods.end(), std::mt19937(static_cast(time(nullptr)))); + launchNextRound(); + + _rfidkit.onTagActivated([this](const MagicCard &card) { processCard(card); }); +} + +void FoodRecognition::stop() +{ + _rfidkit.onTagActivated(_backup_callback); +} + +void FoodRecognition::processCard(const MagicCard &card) +{ + if (card == _current_food->card) { + _reinforcerkit.playDefault(); + ++_current_round; + + if (_current_round == kScoreToWin) { + _backup_callback(MagicCard::dice_roll); + return; + } + + launchNextRound(); + } else { + _backup_callback(card); + } +} + +void FoodRecognition::launchNextRound() +{ + _current_food = _foods.at(_current_round); + + auto full_path = "/fs/home/img/id/" + std::string(_current_food->id) + ".jpg"; + _videokit.fillWhiteBackgroundAndDisplayImage(full_path); +} + +} // namespace leka::activity + +// LCOV_EXCL_STOP