diff --git a/Src/Application/mode_handler.c b/Src/Application/mode_handler.c index 9531884..b4319de 100644 --- a/Src/Application/mode_handler.c +++ b/Src/Application/mode_handler.c @@ -89,9 +89,11 @@ mode_handler_mode_t mode_handler_handle(imu_data_t *imu_data, remote_data_t *rem /* * Setpoint selection */ - if (imu_active && remote_active && flightcomputer_active && !remote_data->override_active && - remote_data->is_armed) { - return MODE_FLIGHTCOMPUTER; + if (imu_active && remote_active && flightcomputer_active && !remote_data->override_active) { + if (remote_data->is_armed) { + return MODE_FLIGHTCOMPUTER; + } + return MODE_STABILISED_FAILSAVE; } if (remote_active) { diff --git a/Src/Application/mode_handler.h b/Src/Application/mode_handler.h index 7db4e1e..af8de4b 100644 --- a/Src/Application/mode_handler.h +++ b/Src/Application/mode_handler.h @@ -47,9 +47,10 @@ void mode_handler_init(void); * | IMU | Remote | FCP | Override | Armed | Mode | * | --- | ------ | --- | -------- | ----- | -------------------- | * | Y | Y | Y | N | Y | FCP | - * | | Y | | | | Remote | + * | Y | Y | Y | N | N | Stabilisied Failsave | * | Y | N | | | | Stabilisied Failsave | - * | N | N | | | | Failsave | + * | | Y | | | | Remote | + * | | | | | | Failsave | * * * @param imu_data out-parameter, contains the last valid imu measurement diff --git a/Tests/LowLevel/Application/mode_handler.cpp b/Tests/LowLevel/Application/mode_handler.cpp index ce00051..d9e3bd9 100644 --- a/Tests/LowLevel/Application/mode_handler.cpp +++ b/Tests/LowLevel/Application/mode_handler.cpp @@ -8,29 +8,6 @@ extern "C" { #include } -TEST(TEST_NAME, all_ok) { - auto imuHandle = mock::imu.getHandle(); - auto flightcomputerHandle = mock::flightcomputer.getHandle(); - auto remoteHandle = mock::remote.getHandle(); - auto errorHandlerHandle = mock::error_handler.getHandle(); - - imuHandle.overrideFunc([]() { return true; }); - imuHandle.overrideFunc([]() { return imu_data_t{.imu_ok = true}; }); - remoteHandle.overrideFunc([]() { return true; }); - remoteHandle.overrideFunc( - []() { return remote_data_t{.is_armed = true, .override_active = false, .remote_ok = true}; }); - flightcomputerHandle.overrideFunc([]() { return true; }); - flightcomputerHandle.overrideFunc([]() { return flightcomputer_setpoint_t{}; }); - - mode_handler_init(); - - imu_data_t imuData; - remote_data_t remoteData; - flightcomputer_setpoint_t flightcomputerSetpoint; - - EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), MODE_FLIGHTCOMPUTER); -} - TEST(TEST_NAME, imu_initial_timeout) { auto imuHandle = mock::imu.getHandle(); auto flightcomputerHandle = mock::flightcomputer.getHandle(); @@ -380,3 +357,87 @@ TEST(TEST_NAME, fcp_timeout) { EXPECT_FALSE(errorHandlerHandle.functionGotCalled(MODE_HANDLER, MODE_HANDLER_ERROR_NO_FCP_DATA)); } + +TEST(TEST_NAME, modeselection) { + auto imuHandle = mock::imu.getHandle(); + auto flightcomputerHandle = mock::flightcomputer.getHandle(); + auto remoteHandle = mock::remote.getHandle(); + auto errorHandlerHandle = mock::error_handler.getHandle(); + + imuHandle.overrideFunc([]() { return true; }); + remoteHandle.overrideFunc([]() { return true; }); + flightcomputerHandle.overrideFunc([]() { return flightcomputer_setpoint_t{}; }); + + struct availability_values { + bool imu, remote, fcp, override, arm; + }; + + const std::vector> decisionTable{ + {{false, false, false, false, false}, MODE_FAILSAVE}, + {{false, false, false, false, true}, MODE_FAILSAVE}, + {{false, false, false, true, false}, MODE_FAILSAVE}, + {{false, false, false, true, true}, MODE_FAILSAVE}, + {{false, false, true, false, false}, MODE_FAILSAVE}, + {{false, false, true, false, true}, MODE_FAILSAVE}, + {{false, false, true, true, false}, MODE_FAILSAVE}, + {{false, false, true, true, true}, MODE_FAILSAVE}, + {{false, true, false, false, false}, MODE_REMOTE}, + {{false, true, false, false, true}, MODE_REMOTE}, + {{false, true, false, true, false}, MODE_REMOTE}, + {{false, true, false, true, true}, MODE_REMOTE}, + {{false, true, true, false, false}, MODE_REMOTE}, + {{false, true, true, false, true}, MODE_REMOTE}, + {{false, true, true, true, false}, MODE_REMOTE}, + {{false, true, true, true, true}, MODE_REMOTE}, + {{true, false, false, false, false}, MODE_STABILISED_FAILSAVE}, + {{true, false, false, false, true}, MODE_STABILISED_FAILSAVE}, + {{true, false, false, true, false}, MODE_STABILISED_FAILSAVE}, + {{true, false, false, true, true}, MODE_STABILISED_FAILSAVE}, + {{true, false, true, false, false}, MODE_STABILISED_FAILSAVE}, + {{true, false, true, false, true}, MODE_STABILISED_FAILSAVE}, + {{true, false, true, true, false}, MODE_STABILISED_FAILSAVE}, + {{true, false, true, true, true}, MODE_STABILISED_FAILSAVE}, + {{true, true, false, false, false}, MODE_REMOTE}, + {{true, true, false, false, true}, MODE_REMOTE}, + {{true, true, false, true, false}, MODE_REMOTE}, + {{true, true, false, true, true}, MODE_REMOTE}, + {{true, true, true, false, false}, MODE_STABILISED_FAILSAVE}, + {{true, true, true, false, true}, MODE_FLIGHTCOMPUTER}, + {{true, true, true, true, false}, MODE_REMOTE}, + {{true, true, true, true, true}, MODE_REMOTE}, + }; + + for (auto [availability_value, expected_mode] : decisionTable) { + mode_handler_init(); + imuHandle.overrideFunc( + [availability_value]() { return imu_data_t{.imu_ok = availability_value.imu}; }); + remoteHandle.overrideFunc([availability_value]() { + return remote_data_t{.is_armed = availability_value.arm, + .override_active = availability_value.override, + .remote_ok = availability_value.remote}; + }); + flightcomputerHandle.overrideFunc( + [availability_value]() { return availability_value.fcp; }); + + imu_data_t imuData; + remote_data_t remoteData; + flightcomputer_setpoint_t flightcomputerSetpoint; + EXPECT_EQ(mode_handler_handle(&imuData, &remoteData, &flightcomputerSetpoint), expected_mode); + if (!availability_value.remote) { + EXPECT_TRUE(errorHandlerHandle.functionGotCalled( + MODE_HANDLER, MODE_HANDLER_ERROR_NO_REMOTE_DATA)); + } + if (!availability_value.imu) { + EXPECT_TRUE(errorHandlerHandle.functionGotCalled( + MODE_HANDLER, MODE_HANDLER_ERROR_NO_IMU_DATA)); + } + if (!availability_value.fcp) { + EXPECT_TRUE(errorHandlerHandle.functionGotCalled( + MODE_HANDLER, MODE_HANDLER_ERROR_NO_FCP_DATA)); + } + } +} + +TEST(TEST_NAME, fill_out_vars) { + EXPECT_FALSE(true); +} diff --git a/Tests/LowLevel/Mock/Lib/CMakeLists.txt b/Tests/LowLevel/Mock/Lib/CMakeLists.txt index d504242..5099150 100644 --- a/Tests/LowLevel/Mock/Lib/CMakeLists.txt +++ b/Tests/LowLevel/Mock/Lib/CMakeLists.txt @@ -2,4 +2,4 @@ project(MockLib) add_library(${PROJECT_NAME} INTERFACE) target_include_directories(${PROJECT_NAME} INTERFACE ..) -target_link_libraries(${PROJECT_NAME} PUBLIC gtest gmock pthread) +target_link_libraries(${PROJECT_NAME} INTERFACE gtest gmock pthread)