diff --git a/app/os/main.cpp b/app/os/main.cpp index 00b64abe60..560aca3815 100644 --- a/app/os/main.cpp +++ b/app/os/main.cpp @@ -10,6 +10,7 @@ #include "rtos/Thread.h" #include "ActivityKit.h" +#include "BatteryKit.h" #include "ChooseReinforcer.h" #include "CoreBattery.h" #include "CoreBufferedSerial.h" @@ -89,6 +90,7 @@ namespace battery { } auto cells = CoreBattery {PinName::BATTERY_VOLTAGE, battery::charge::status_input}; + auto kit = BatteryKit {battery::cells}; } // namespace battery @@ -418,7 +420,7 @@ namespace robot { internal::timeout_state_internal, internal::timeout_state_transition, internal::timeout_autonomous_activities, - battery::cells, + battery::kit, internal::serialnumberkit, firmware::kit, motors::left::motor, diff --git a/libs/RobotKit/include/RobotController.h b/libs/RobotKit/include/RobotController.h index 71e1236c71..0e194a3a5d 100644 --- a/libs/RobotKit/include/RobotController.h +++ b/libs/RobotKit/include/RobotController.h @@ -30,12 +30,12 @@ #include "SerialNumberKit.h" #include "StateMachine.h" #include "interface/RobotController.h" -#include "interface/drivers/Battery.h" #include "interface/drivers/DeepSleepEnabled.h" #include "interface/drivers/FirmwareUpdate.h" #include "interface/drivers/LCD.hpp" #include "interface/drivers/Motor.h" #include "interface/drivers/Timeout.h" +#include "interface/libs/BatteryKit.h" #include "interface/libs/LedKit.h" #include "interface/libs/VideoKit.h" @@ -51,7 +51,7 @@ class RobotController : public interface::RobotController sm_t state_machine {static_cast(*this), logger}; explicit RobotController(interface::Timeout &timeout_state_internal, interface::Timeout &timeout_state_transition, - interface::Timeout &timeout_autonomous_activities, interface::Battery &battery, + interface::Timeout &timeout_autonomous_activities, interface::BatteryKit &batterykit, SerialNumberKit &serialnumberkit, interface::FirmwareUpdate &firmware_update, interface::Motor &motor_left, interface::Motor &motor_right, interface::LED &ears, interface::LED &belt, interface::LedKit &ledkit, interface::LCD &lcd, @@ -60,7 +60,7 @@ class RobotController : public interface::RobotController : _timeout_state_internal(timeout_state_internal), _timeout_state_transition(timeout_state_transition), _timeout_autonomous_activities(timeout_autonomous_activities), - _battery(battery), + _batterykit(batterykit), _serialnumberkit(serialnumberkit), _firmware_update(firmware_update), _motor_left(motor_left), @@ -155,7 +155,7 @@ class RobotController : public interface::RobotController auto isCharging() -> bool final { - auto is_charging = _battery.isCharging(); + auto is_charging = _batterykit.isCharging(); _service_monitoring.setChargingStatus(is_charging); @@ -181,7 +181,7 @@ class RobotController : public interface::RobotController { using namespace std::chrono_literals; - onChargingBehavior(_battery_kit.level()); + onChargingBehavior(_batterykit.level()); _behaviorkit.blinkOnCharge(); rtos::ThisThread::sleep_for(500ms); _lcd.turnOn(); @@ -202,7 +202,7 @@ class RobotController : public interface::RobotController { using namespace std::chrono_literals; stopActuators(); - if (_battery.isCharging()) { + if (_batterykit.isCharging()) { _behaviorkit.bleConnectionWithoutVideo(); rtos::ThisThread::sleep_for(5s); _behaviorkit.blinkOnCharge(); @@ -215,7 +215,7 @@ class RobotController : public interface::RobotController void startDisconnectionBehavior() final { stopActuators(); - if (_battery.isCharging()) { + if (_batterykit.isCharging()) { _behaviorkit.blinkOnCharge(); } } @@ -238,7 +238,7 @@ class RobotController : public interface::RobotController void startFileExchange() final { _behaviorkit.fileExchange(); - if (_battery.isCharging()) { + if (_batterykit.isCharging()) { _behaviorkit.blinkOnCharge(); } _lcd.turnOn(); @@ -274,7 +274,7 @@ class RobotController : public interface::RobotController auto isReadyToFileExchange() -> bool final { - auto is_robot_ready = (_battery.isCharging() && _battery.level() > _minimal_battery_level_to_update); + auto is_robot_ready = (_batterykit.isCharging() && _batterykit.level() > _minimal_battery_level_to_update); if (!is_robot_ready) { _service_file_exchange.setFileExchangeState(false); @@ -285,7 +285,7 @@ class RobotController : public interface::RobotController auto isReadyToUpdate() -> bool final { - auto is_robot_ready = _battery.isCharging() && _battery.level() > _minimal_battery_level_to_update; + auto is_robot_ready = _batterykit.isCharging() && _batterykit.level() > _minimal_battery_level_to_update; auto firmware_version = _service_update.getVersion(); auto is_version_available = _firmware_update.isVersionAvailable(firmware_version); @@ -460,8 +460,8 @@ class RobotController : public interface::RobotController _activitykit.registerBeforeProcessCallback([this] { resetAutonomousActivitiesTimeout(); }); - _battery_kit.onDataUpdated([this](uint8_t level) { - auto is_charging = _battery.isCharging(); + _batterykit.onDataUpdated([this](uint8_t level) { + auto is_charging = _batterykit.isCharging(); auto advertising_data = _ble.getAdvertisingData(); advertising_data.battery = level; @@ -477,18 +477,17 @@ class RobotController : public interface::RobotController } }); - auto on_low_battery = [this] { - if (!_battery.isCharging()) { + _batterykit.onLowBattery([this] { + if (!_batterykit.isCharging()) { _behaviorkit.lowBattery(); } - if (_battery.level() == 0) { + if (_batterykit.level() == 0) { system_reset(); } - }; - _battery_kit.onLowBattery(on_low_battery); + }); - _battery_kit.startEventHandler(); + _batterykit.startEventHandler(); _ble.onConnectionCallback([this] { raise(event::ble_connection {}); }); @@ -498,11 +497,9 @@ class RobotController : public interface::RobotController // Setup callbacks for each State Machine events - auto on_charge_did_start = [this]() { raise(event::charge_did_start {}); }; - _battery.onChargeDidStart(on_charge_did_start); + _batterykit.onChargeDidStart([this] { raise(event::charge_did_start {}); }); - auto on_charge_did_stop = [this]() { raise(event::charge_did_stop {}); }; - _battery.onChargeDidStop(on_charge_did_stop); + _batterykit.onChargeDidStop([this] { raise(event::charge_did_stop {}); }); _service_monitoring.onSoftReboot([] { system_reset(); }); @@ -512,7 +509,7 @@ class RobotController : public interface::RobotController std::ignore = _configkit.write(config_robot_name, robot_name); }); - auto on_commands_received = [this](std::span _buffer) { + _service_commands.onCommandsReceived([this](std::span _buffer) { raise(event::command_received {}); if (!isCharging()) { @@ -521,8 +518,7 @@ class RobotController : public interface::RobotController _cmdkit.push(std::span {_buffer.data(), std::size(_buffer)}); } - }; - _service_commands.onCommandsReceived(on_commands_received); + }); _service_file_exchange.onSetFileExchangeState([this](bool file_exchange_requested) { if (file_exchange_requested) { @@ -532,8 +528,7 @@ class RobotController : public interface::RobotController } }); - auto on_update_requested = [this]() { raise(event::update_requested {}); }; - _service_update.onUpdateRequested(on_update_requested); + _service_update.onUpdateRequested([this] { raise(event::update_requested {}); }); raise(event::setup_complete {}); } @@ -573,8 +568,7 @@ class RobotController : public interface::RobotController rtos::Kernel::Clock::time_point start = rtos::Kernel::Clock::now(); rtos::Kernel::Clock::time_point stop = rtos::Kernel::Clock::now(); - interface::Battery &_battery; - BatteryKit _battery_kit {_battery}; + interface::BatteryKit &_batterykit; uint8_t _minimal_battery_level_to_update {25}; SerialNumberKit &_serialnumberkit; diff --git a/libs/RobotKit/tests/RobotController_test.h b/libs/RobotKit/tests/RobotController_test.h index 840c2f6eaa..2fe10f924b 100644 --- a/libs/RobotKit/tests/RobotController_test.h +++ b/libs/RobotKit/tests/RobotController_test.h @@ -21,7 +21,7 @@ #include "SerialNumberKit.h" #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "mocks/leka/Battery.h" +#include "mocks/leka/BatteryKit.h" #include "mocks/leka/CoreLCD.h" #include "mocks/leka/CoreLED.h" #include "mocks/leka/CoreMotor.h" @@ -79,7 +79,7 @@ class RobotControllerTest : public testing::Test mock::Timeout timeout_state_internal {}; mock::Timeout timeout_state_transition {}; mock::Timeout timeout_autonomous_activities {}; - mock::Battery battery {}; + mock::BatteryKit battery {}; mock::MCU mock_mcu {}; SerialNumberKit serialnumberkit {mock_mcu, SerialNumberKit::DEFAULT_CONFIG}; @@ -139,6 +139,8 @@ class RobotControllerTest : public testing::Test interface::Timeout::callback_t on_charging_start_timeout = {}; interface::Timeout::callback_t on_autonomous_activities_timeout = {}; + std::function on_data_updated {}; + std::function on_low_battery {}; std::function on_charge_did_start {}; std::function on_charge_did_stop {}; @@ -179,6 +181,7 @@ class RobotControllerTest : public testing::Test { EXPECT_CALL(battery, isCharging).Times(AnyNumber()); EXPECT_CALL(battery, level).Times(AnyNumber()); + EXPECT_CALL(battery, startEventHandler).Times(AnyNumber()); EXPECT_CALL(mock_ledkit, stop).Times(AnyNumber()); EXPECT_CALL(mock_motor_left, stop).Times(AnyNumber()); @@ -196,6 +199,8 @@ class RobotControllerTest : public testing::Test } // ? On Idle entry // Saved callback + EXPECT_CALL(battery, onDataUpdated).WillOnce(SaveArg<0>(&on_data_updated)); + EXPECT_CALL(battery, onLowBattery).WillOnce(SaveArg<0>(&on_low_battery)); EXPECT_CALL(battery, onChargeDidStart).WillOnce(SaveArg<0>(&on_charge_did_start)); EXPECT_CALL(battery, onChargeDidStop).WillOnce(SaveArg<0>(&on_charge_did_stop)); diff --git a/libs/RobotKit/tests/RobotController_test_hardware.cpp b/libs/RobotKit/tests/RobotController_test_hardware.cpp index a75b132a11..dca096f9a9 100644 --- a/libs/RobotKit/tests/RobotController_test_hardware.cpp +++ b/libs/RobotKit/tests/RobotController_test_hardware.cpp @@ -49,6 +49,60 @@ TEST_F(RobotControllerTest, wakeUp) // nothing expected } +TEST_F(RobotControllerTest, onDataUpdated) +{ + { + EXPECT_CALL(battery, isCharging).WillOnce(Return(false)); + + EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload); + // TODO: Specify which BLE service and what is expected if necessary + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(2); + } + + on_data_updated(0); + + { + EXPECT_CALL(battery, isCharging).WillOnce(Return(true)); + + EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload); + // TODO: Specify which BLE service and what is expected if necessary + EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(2); + + { + EXPECT_CALL( + mock_videokit, + displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-charging-empty_red.jpg"})); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, chargingEmpty); + } + + on_data_updated(0); +} + +TEST_F(RobotControllerTest, onLowBattery) +{ + { + EXPECT_CALL(battery, isCharging).WillOnce(Return(true)); + + EXPECT_CALL(battery, level).WillOnce(Return(1)); + } + on_low_battery(); + + { + EXPECT_CALL(battery, isCharging).WillOnce(Return(false)); + { + EXPECT_CALL(mock_ledkit, stop); + EXPECT_CALL( + mock_videokit, + displayImage(std::filesystem::path {"/fs/home/img/system/robot-battery-empty-must_be_charged.jpg"})); + EXPECT_CALL(mock_motor_left, stop); + EXPECT_CALL(mock_motor_right, stop); + } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, lowBattery); + + EXPECT_CALL(battery, level).WillOnce(Return(0)); + } + on_low_battery(); +} + TEST_F(RobotControllerTest, onChargeDidStart) { { diff --git a/libs/RobotKit/tests/RobotController_test_registerEvents.cpp b/libs/RobotKit/tests/RobotController_test_registerEvents.cpp index 6fa9ed018c..a743a40b56 100644 --- a/libs/RobotKit/tests/RobotController_test_registerEvents.cpp +++ b/libs/RobotKit/tests/RobotController_test_registerEvents.cpp @@ -4,65 +4,11 @@ #include "./RobotController_test.h" -TEST_F(RobotControllerTest, registerEventsIsNotCharging) +TEST_F(RobotControllerTest, registerEvents) { - // TODO: Add EXPECT_CALL(mock_batterykit, onDataUpdated); - // TODO: Add EXPECT_CALL(mock_batterykit, onLowBattery); - - { - EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(false)); - EXPECT_CALL(battery, level).WillRepeatedly(Return(0)); - - { - { - EXPECT_CALL(mock_ledkit, stop); - EXPECT_CALL(mock_videokit, displayImage(std::filesystem::path { - "/fs/home/img/system/robot-battery-empty-must_be_charged.jpg"})); - EXPECT_CALL(mock_motor_left, stop); - EXPECT_CALL(mock_motor_right, stop); - } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, lowBattery); - } // ? : on_data_updated callback call - - { - EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload); - // TODO: Specify which BLE service and what is expected if necessary - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(2); - } // ? : on_low_battery callback call - - } // TODO: Replace with EXPECT_CALL(mock_batterykit, startEventHandler); - - EXPECT_CALL(battery, onChargeDidStart); - EXPECT_CALL(battery, onChargeDidStop); - - rc.registerEvents(); - - // TODO: Expect raise call -} - -TEST_F(RobotControllerTest, registerEventsIsCharging) -{ - // TODO: Add EXPECT_CALL(mock_batterykit, onDataUpdated); - // TODO: Add EXPECT_CALL(mock_batterykit, onLowBattery); - - { - EXPECT_CALL(battery, isCharging).WillRepeatedly(Return(true)); - EXPECT_CALL(battery, level).WillRepeatedly(Return(100)); - - { - { - EXPECT_CALL(mock_videokit, displayImage(std::filesystem::path { - "/fs/home/img/system/robot-battery-charging-quarter_4-green.jpg"})); - } // TODO: Replace with EXPECT_CALL(mock_behaviorkit, chargingFull); - } // ? : on_data_updated callback call - - { - EXPECT_CALL(mbed_mock_gap, setAdvertisingPayload); - // TODO: Specify which BLE service and what is expected if necessary - EXPECT_CALL(mbed_mock_gatt, write(_, _, _, _)).Times(2); - } // ? : on_low_battery callback call - - } // TODO: Replace with EXPECT_CALL(mock_batterykit, startEventHandler); - + EXPECT_CALL(battery, onDataUpdated); + EXPECT_CALL(battery, onLowBattery); + EXPECT_CALL(battery, startEventHandler); EXPECT_CALL(battery, onChargeDidStart); EXPECT_CALL(battery, onChargeDidStop); diff --git a/tests/unit/mocks/mocks/leka/BatteryKit.h b/tests/unit/mocks/mocks/leka/BatteryKit.h index 096a31c51b..28670bbcf2 100644 --- a/tests/unit/mocks/mocks/leka/BatteryKit.h +++ b/tests/unit/mocks/mocks/leka/BatteryKit.h @@ -9,13 +9,13 @@ namespace leka::mock { -class Battery : public interface::BatteryKit +class BatteryKit : public interface::BatteryKit { public: MOCK_METHOD(void, startEventHandler, (), (override)); MOCK_METHOD(uint8_t, level, (), (override)); - MOCK_METHOD(void, onDataUpdated, (std::function const &), (override)); + MOCK_METHOD(void, onDataUpdated, (std::function const &), (override)); MOCK_METHOD(void, onLowBattery, (std::function const &), (override)); MOCK_METHOD(bool, isCharging, (), (override));