diff --git a/libs/TouchSensorKit/CMakeLists.txt b/libs/TouchSensorKit/CMakeLists.txt index 8b09ddaf4b..f32174b5ab 100644 --- a/libs/TouchSensorKit/CMakeLists.txt +++ b/libs/TouchSensorKit/CMakeLists.txt @@ -6,27 +6,22 @@ add_library(TouchSensorKit STATIC) target_include_directories(TouchSensorKit PUBLIC - include + include ) target_sources(TouchSensorKit PRIVATE - source/TouchSensorKit.cpp + source/TouchSensorKit.cpp ) target_link_libraries(TouchSensorKit mbed-os - IOKit - CoreI2C - CoreIOExpander - CoreQDAC + CoreEventQueue CoreTouchSensor ) -if (${CMAKE_PROJECT_NAME} STREQUAL "LekaOSUnitTests") - +if(${CMAKE_PROJECT_NAME} STREQUAL "LekaOSUnitTests") leka_unit_tests_sources( tests/TouchSensorKit_test.cpp ) - endif() diff --git a/libs/TouchSensorKit/include/TouchSensorKit.h b/libs/TouchSensorKit/include/TouchSensorKit.h index 5fecb5cdee..f5d05630d1 100644 --- a/libs/TouchSensorKit/include/TouchSensorKit.h +++ b/libs/TouchSensorKit/include/TouchSensorKit.h @@ -4,48 +4,45 @@ #pragma once +#include + +#include "CoreEventQueue.h" #include "Position.h" #include "interface/drivers/TouchSensor.h" -#include "interface/libs/EventLoop.h" namespace leka { class TouchSensorKit { public: - static constexpr auto kNumberOfSensors = uint8_t {6}; - - explicit TouchSensorKit(interface::EventLoop &event_loop, interface::TouchSensor &ear_left, - interface::TouchSensor &ear_right, interface::TouchSensor &belt_left_back, - interface::TouchSensor &belt_left_front, interface::TouchSensor &belt_right_back, - interface::TouchSensor &belt_right_front) - : _event_loop(event_loop), - _ear_left(ear_left), + explicit TouchSensorKit(interface::TouchSensor &ear_left, interface::TouchSensor &ear_right, + interface::TouchSensor &belt_left_back, interface::TouchSensor &belt_left_front, + interface::TouchSensor &belt_right_back, interface::TouchSensor &belt_right_front) + : _ear_left(ear_left), _ear_right(ear_right), _belt_left_back(belt_left_back), _belt_left_front(belt_left_front), _belt_right_back(belt_right_back), _belt_right_front(belt_right_front) {}; - void init(); - void start(); - void stop(); - auto isRunning() -> bool; + void initialize(); + + void setRefreshDelay(std::chrono::milliseconds delay); + void enable(); + void disable(); - void registerOnStartRead(std::function const &on_start_read_callback); void registerOnSensorTouched(std::function const &on_sensor_touched_callback); void registerOnSensorReleased(std::function const &on_sensor_released_callback); - void registerOnEndRead(std::function const &on_end_read_callback); + + auto isTouched(Position position) -> bool; private: void run(); - auto readAtPosition(Position position) -> bool; - void resetAtPosition(Position position); - void setSensitivityAtPosition(Position position, uint16_t value); + void setSensitivity(Position position, float value); - interface::EventLoop &_event_loop; - bool _running = false; + CoreEventQueue _event_queue {}; + std::chrono::milliseconds _refresh_delay {100}; interface::TouchSensor &_ear_left; interface::TouchSensor &_ear_right; @@ -55,11 +52,10 @@ class TouchSensorKit interface::TouchSensor &_belt_right_front; static constexpr auto default_max_sensitivity_value = float {1.F}; - static constexpr auto default_min_sensitivity_value = float {0.6F}; - std::function _on_start_read_callback {}; + std::map _previous_is_touched {}; + std::function _on_sensor_touched_callback {}; std::function _on_sensor_released_callback {}; - std::function _on_end_read_callback {}; }; } // namespace leka diff --git a/libs/TouchSensorKit/source/TouchSensorKit.cpp b/libs/TouchSensorKit/source/TouchSensorKit.cpp index ff26cfca29..fdf92a4959 100644 --- a/libs/TouchSensorKit/source/TouchSensorKit.cpp +++ b/libs/TouchSensorKit/source/TouchSensorKit.cpp @@ -10,7 +10,7 @@ using namespace leka; using namespace std::chrono_literals; -void TouchSensorKit::init() +void TouchSensorKit::initialize() { _ear_left.init(); _ear_right.init(); @@ -19,63 +19,50 @@ void TouchSensorKit::init() _belt_right_back.init(); _belt_right_front.init(); - _ear_left.setSensitivity(default_max_sensitivity_value); - _ear_right.setSensitivity(default_max_sensitivity_value); - _belt_left_back.setSensitivity(default_max_sensitivity_value); - _belt_left_front.setSensitivity(default_max_sensitivity_value); - _belt_right_back.setSensitivity(default_max_sensitivity_value); - _belt_right_front.setSensitivity(default_max_sensitivity_value); + setSensitivity(Position::ear_left, default_max_sensitivity_value); + setSensitivity(Position::ear_right, default_max_sensitivity_value); + setSensitivity(Position::belt_left_back, default_max_sensitivity_value); + setSensitivity(Position::belt_left_front, default_max_sensitivity_value); + setSensitivity(Position::belt_right_back, default_max_sensitivity_value); + setSensitivity(Position::belt_right_front, default_max_sensitivity_value); - _event_loop.registerCallback([this] { run(); }); + _event_queue.dispatch_forever(); } -void TouchSensorKit::start() +void TouchSensorKit::setRefreshDelay(std::chrono::milliseconds delay) { - stop(); - _running = true; - _event_loop.start(); + _refresh_delay = delay; } -void TouchSensorKit::stop() +void TouchSensorKit::enable() { - _event_loop.stop(); + disable(); + _event_queue.call_every(_refresh_delay, [this] { run(); }); +} + +void TouchSensorKit::disable() +{ + _event_queue.cancelLastCall(); } void TouchSensorKit::run() { auto constexpr positions = - std::array {Position::ear_left, Position::ear_right, Position::belt_left_back, - Position::belt_left_front, Position::belt_right_back, Position::belt_right_front}; - bool state = false; - while (isRunning()) { - if (_on_start_read_callback != nullptr) { - _on_start_read_callback(); - } - for (Position position: positions) { - state = readAtPosition(position); - if (state && _on_sensor_touched_callback != nullptr) { - _on_sensor_touched_callback(position); - } - if (!state && _on_sensor_released_callback != nullptr) { - _on_sensor_released_callback(position); - } + std::to_array({Position::ear_left, Position::ear_right, Position::belt_left_back, + Position::belt_left_front, Position::belt_right_back, Position::belt_right_front}); + + for (Position position: positions) { + auto is_touched = isTouched(position); + if (is_touched && !_previous_is_touched[position] && _on_sensor_touched_callback != nullptr) { + _on_sensor_touched_callback(position); } - if (_on_end_read_callback != nullptr) { - _on_end_read_callback(); + if (!is_touched && _previous_is_touched[position] && _on_sensor_released_callback != nullptr) { + _on_sensor_released_callback(position); } + _previous_is_touched[position] = is_touched; } } -auto TouchSensorKit::isRunning() -> bool -{ - return _running; -} - -void TouchSensorKit::registerOnStartRead(std::function const &on_start_read_callback) -{ - _on_start_read_callback = on_start_read_callback; -} - void TouchSensorKit::registerOnSensorTouched(std::function const &on_sensor_touched_callback) { _on_sensor_touched_callback = on_sensor_touched_callback; @@ -86,12 +73,7 @@ void TouchSensorKit::registerOnSensorReleased(std::function const &on_end_read_callback) -{ - _on_end_read_callback = on_end_read_callback; -} - -auto TouchSensorKit::readAtPosition(Position position) -> bool +auto TouchSensorKit::isTouched(Position position) -> bool { auto read = bool {}; switch (position) { @@ -119,33 +101,7 @@ auto TouchSensorKit::readAtPosition(Position position) -> bool return read; } -void TouchSensorKit::resetAtPosition(Position position) -{ - switch (position) { - case Position::ear_left: - _ear_left.reset(); - break; - case Position::ear_right: - _ear_right.reset(); - break; - case Position::belt_left_back: - _belt_left_back.reset(); - break; - case Position::belt_left_front: - _belt_left_front.reset(); - break; - case Position::belt_right_back: - _belt_right_back.reset(); - break; - case Position::belt_right_front: - _belt_right_front.reset(); - break; - default: - break; - } -} - -void TouchSensorKit::setSensitivityAtPosition(Position position, uint16_t value) +void TouchSensorKit::setSensitivity(Position position, float value) { switch (position) { case Position::ear_left: diff --git a/libs/TouchSensorKit/tests/TouchSensorKit_test.cpp b/libs/TouchSensorKit/tests/TouchSensorKit_test.cpp index ae633c2097..d5b77fc775 100644 --- a/libs/TouchSensorKit/tests/TouchSensorKit_test.cpp +++ b/libs/TouchSensorKit/tests/TouchSensorKit_test.cpp @@ -6,39 +6,53 @@ #include "gtest/gtest.h" #include "mocks/leka/CoreTouchSensor.h" -#include "stubs/leka/EventLoopKit.h" +#include "mocks/leka/EventQueue.h" using namespace leka; +using ::testing::MockFunction; +using ::testing::Return; + class TouchSensorKitTest : public ::testing::Test { protected: TouchSensorKitTest() = default; - // void SetUp() override {} + void SetUp() override + { + expectedCallsInitialize(); + touch_sensor_kit.initialize(); + } // void TearDown() override {} mock::CoreTouchSensor mock_ear_left; mock::CoreTouchSensor mock_ear_right; - mock::CoreTouchSensor mock_belt_left_front; mock::CoreTouchSensor mock_belt_left_back; - mock::CoreTouchSensor mock_belt_right_front; + mock::CoreTouchSensor mock_belt_left_front; mock::CoreTouchSensor mock_belt_right_back; + mock::CoreTouchSensor mock_belt_right_front; - stub::EventLoopKit stub_event_loop {}; - - TouchSensorKit touch_sensor_kit {stub_event_loop, mock_ear_left, mock_ear_right, - mock_belt_left_front, mock_belt_left_back, mock_belt_right_front, - mock_belt_right_back}; - - static void spy_onStartRead_func() {}; - std::function OnStartReadCallback = spy_onStartRead_func; - static void spy_onSensorTouched_func(Position position) {}; - std::function OnSensorTouchedCallback = spy_onSensorTouched_func; - static void spy_onSensorReleased_func(Position position) {}; - std::function OnSensorReleasedCallback = spy_onSensorReleased_func; - static void spy_onEndRead_func() {}; - std::function OnEndReadCallback = spy_onEndRead_func; + mock::EventQueue event_queue {}; + + TouchSensorKit touch_sensor_kit {mock_ear_left, mock_ear_right, mock_belt_left_back, + mock_belt_left_front, mock_belt_right_back, mock_belt_right_front}; + + void expectedCallsInitialize() + { + EXPECT_CALL(mock_ear_left, init).Times(1); + EXPECT_CALL(mock_ear_right, init).Times(1); + EXPECT_CALL(mock_belt_left_front, init).Times(1); + EXPECT_CALL(mock_belt_left_back, init).Times(1); + EXPECT_CALL(mock_belt_right_front, init).Times(1); + EXPECT_CALL(mock_belt_right_back, init).Times(1); + + EXPECT_CALL(mock_ear_left, setSensitivity).Times(1); + EXPECT_CALL(mock_ear_right, setSensitivity).Times(1); + EXPECT_CALL(mock_belt_left_front, setSensitivity).Times(1); + EXPECT_CALL(mock_belt_left_back, setSensitivity).Times(1); + EXPECT_CALL(mock_belt_right_front, setSensitivity).Times(1); + EXPECT_CALL(mock_belt_right_back, setSensitivity).Times(1); + } }; TEST_F(TouchSensorKitTest, initializationDefault) @@ -46,7 +60,7 @@ TEST_F(TouchSensorKitTest, initializationDefault) ASSERT_NE(&touch_sensor_kit, nullptr); } -TEST_F(TouchSensorKitTest, init) +TEST_F(TouchSensorKitTest, initialize) { EXPECT_CALL(mock_ear_left, init).Times(1); EXPECT_CALL(mock_ear_right, init).Times(1); @@ -62,39 +76,101 @@ TEST_F(TouchSensorKitTest, init) EXPECT_CALL(mock_belt_right_front, setSensitivity).Times(1); EXPECT_CALL(mock_belt_right_back, setSensitivity).Times(1); - touch_sensor_kit.init(); + touch_sensor_kit.initialize(); } -TEST_F(TouchSensorKitTest, start) +TEST_F(TouchSensorKitTest, setRefreshDelay) { - EXPECT_FALSE(touch_sensor_kit.isRunning()); - touch_sensor_kit.start(); - EXPECT_TRUE(touch_sensor_kit.isRunning()); + touch_sensor_kit.setRefreshDelay(std::chrono::milliseconds {100}); + + // nothing expected } -TEST_F(TouchSensorKitTest, stop) +TEST_F(TouchSensorKitTest, enable) { - touch_sensor_kit.stop(); - - // nothing expected + EXPECT_CALL(mock_ear_left, read).Times(1); + EXPECT_CALL(mock_ear_right, read).Times(1); + EXPECT_CALL(mock_belt_left_front, read).Times(1); + EXPECT_CALL(mock_belt_left_back, read).Times(1); + EXPECT_CALL(mock_belt_right_front, read).Times(1); + EXPECT_CALL(mock_belt_right_back, read).Times(1); + + touch_sensor_kit.enable(); } -TEST_F(TouchSensorKitTest, registerOnStartRead) +TEST_F(TouchSensorKitTest, disable) { - touch_sensor_kit.registerOnStartRead(OnStartReadCallback); + touch_sensor_kit.disable(); + + // nothing expected } TEST_F(TouchSensorKitTest, registerOnSensorTouched) { - touch_sensor_kit.registerOnSensorTouched(OnSensorTouchedCallback); + MockFunction mock_callback; + touch_sensor_kit.registerOnSensorTouched(mock_callback.AsStdFunction()); + + EXPECT_CALL(mock_ear_left, read).WillOnce(Return(false)); + EXPECT_CALL(mock_ear_right, read).WillOnce(Return(false)); + EXPECT_CALL(mock_belt_left_front, read).WillOnce(Return(false)); + EXPECT_CALL(mock_belt_left_back, read).WillOnce(Return(false)); + EXPECT_CALL(mock_belt_right_front, read).WillOnce(Return(false)); + EXPECT_CALL(mock_belt_right_back, read).WillOnce(Return(false)); + + touch_sensor_kit.enable(); + + EXPECT_CALL(mock_ear_left, read).WillOnce(Return(true)); + EXPECT_CALL(mock_callback, Call(Position::ear_left)).Times(1); + + EXPECT_CALL(mock_ear_right, read).WillOnce(Return(false)); + EXPECT_CALL(mock_callback, Call(Position::ear_right)).Times(0); + + EXPECT_CALL(mock_belt_left_front, read).WillOnce(Return(true)); + EXPECT_CALL(mock_callback, Call(Position::belt_left_front)).Times(1); + + EXPECT_CALL(mock_belt_left_back, read).WillOnce(Return(false)); + EXPECT_CALL(mock_callback, Call(Position::belt_left_back)).Times(0); + + EXPECT_CALL(mock_belt_right_front, read).WillOnce(Return(true)); + EXPECT_CALL(mock_callback, Call(Position::belt_right_front)).Times(1); + + EXPECT_CALL(mock_belt_right_back, read).WillOnce(Return(false)); + EXPECT_CALL(mock_callback, Call(Position::belt_right_back)).Times(0); + + touch_sensor_kit.enable(); } TEST_F(TouchSensorKitTest, registerOnSensorReleased) { - touch_sensor_kit.registerOnSensorReleased(OnSensorReleasedCallback); -} + MockFunction mock_callback; + touch_sensor_kit.registerOnSensorReleased(mock_callback.AsStdFunction()); -TEST_F(TouchSensorKitTest, registerOnEndRead) -{ - touch_sensor_kit.registerOnEndRead(OnEndReadCallback); + EXPECT_CALL(mock_ear_left, read).WillOnce(Return(true)); + EXPECT_CALL(mock_ear_right, read).WillOnce(Return(true)); + EXPECT_CALL(mock_belt_left_front, read).WillOnce(Return(true)); + EXPECT_CALL(mock_belt_left_back, read).WillOnce(Return(true)); + EXPECT_CALL(mock_belt_right_front, read).WillOnce(Return(true)); + EXPECT_CALL(mock_belt_right_back, read).WillOnce(Return(true)); + + touch_sensor_kit.enable(); + + EXPECT_CALL(mock_ear_left, read).WillOnce(Return(true)); + EXPECT_CALL(mock_callback, Call(Position::ear_left)).Times(0); + + EXPECT_CALL(mock_ear_right, read).WillOnce(Return(true)); + EXPECT_CALL(mock_callback, Call(Position::ear_right)).Times(0); + + EXPECT_CALL(mock_belt_left_front, read).WillOnce(Return(false)); + EXPECT_CALL(mock_callback, Call(Position::belt_left_front)).Times(1); + + EXPECT_CALL(mock_belt_left_back, read).WillOnce(Return(true)); + EXPECT_CALL(mock_callback, Call(Position::belt_left_back)).Times(0); + + EXPECT_CALL(mock_belt_right_front, read).WillOnce(Return(false)); + EXPECT_CALL(mock_callback, Call(Position::belt_right_front)).Times(1); + + EXPECT_CALL(mock_belt_right_back, read).WillOnce(Return(false)); + EXPECT_CALL(mock_callback, Call(Position::belt_right_back)).Times(1); + + touch_sensor_kit.enable(); }