MMU-239 Add unit test for ejecting slots 0-4

This test ejects slots 0 to 4 and goes through the state machine
without creating any errors like FINDA_FLICKERS.

It also verifies the selector parking position is correct for each
ejected filament slot.
pull/278/head
Guðni Már Gilbert 2023-05-29 12:44:22 +00:00
parent f01928ebe2
commit 0c8ba878f3
1 changed files with 36 additions and 28 deletions

View File

@ -1,4 +1,5 @@
#include "catch2/catch_test_macros.hpp" #include "catch2/catch_test_macros.hpp"
#include "catch2/generators/catch_generators.hpp"
#include "../../../../src/modules/buttons.h" #include "../../../../src/modules/buttons.h"
#include "../../../../src/modules/finda.h" #include "../../../../src/modules/finda.h"
@ -19,53 +20,60 @@
#include "../helpers/helpers.ipp" #include "../helpers/helpers.ipp"
// temporarily disabled TEST_CASE("eject_filament::eject0-4", "[eject_filament]") {
TEST_CASE("eject_filament::eject0", "[eject_filament][.]") {
using namespace logic; using namespace logic;
uint8_t ejectSlot = GENERATE(0, 1, 2, 3, 4);
uint8_t selectorParkedPos = (ejectSlot <= 2) ? 4 : 0;
ForceReinitAllAutomata(); ForceReinitAllAutomata();
REQUIRE(EnsureActiveSlotIndex(0, mg::FilamentLoadState::AtPulley));
REQUIRE(EnsureActiveSlotIndex(ejectSlot, mg::FilamentLoadState::AtPulley));
EjectFilament ef; EjectFilament ef;
// restart the automaton // restart the automaton
ef.Reset(0); ef.Reset(ejectSlot);
main_loop(); main_loop();
// it should have instructed the selector and idler to move to slot 1 // Start at UnloadingFilament
// check if the idler and selector have the right command REQUIRE(ef.TopLevelState() == ProgressCode::UnloadingFilament);
CHECK(mm::AxisNearestTargetPos(mm::Idler) == mi::Idler::SlotPosition(0).v);
CHECK(mm::AxisNearestTargetPos(mm::Selector) == ms::Selector::SlotPosition(4).v);
// now cycle at most some number of cycles (to be determined yet) and then verify, that the idler and selector reached their target positions REQUIRE(WhileTopState(ef, ProgressCode::UnloadingFilament, 5000));
REQUIRE(WhileTopState(ef, ProgressCode::SelectingFilamentSlot, 5000));
// idler and selector reached their target positions and the CF automaton will start feeding to FINDA as the next step REQUIRE(ef.TopLevelState() == ProgressCode::ParkingSelector);
REQUIRE(ef.TopLevelState() == ProgressCode::FeedingToFinda);
// prepare for simulated finda trigger
hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::high);
REQUIRE(WhileTopState(ef, ProgressCode::FeedingToFinda, 50000));
// filament fed into FINDA, cutting... REQUIRE(WhileTopState(ef, ProgressCode::ParkingSelector, selectorMoveMaxSteps));
REQUIRE(ef.TopLevelState() == ProgressCode::PreparingBlade);
REQUIRE(WhileTopState(ef, ProgressCode::PreparingBlade, 5000));
// Engaging idler
REQUIRE(ef.TopLevelState() == ProgressCode::EngagingIdler); REQUIRE(ef.TopLevelState() == ProgressCode::EngagingIdler);
REQUIRE(WhileTopState(ef, ProgressCode::EngagingIdler, 5000)); REQUIRE(WhileTopState(ef, ProgressCode::EngagingIdler, 5000));
// the idler should be at the active slot @@TODO REQUIRE(mi::idler.Engaged());
REQUIRE(ef.TopLevelState() == ProgressCode::PushingFilament); REQUIRE(ef.TopLevelState() == ProgressCode::EjectingFilament);
REQUIRE(WhileTopState(ef, ProgressCode::PushingFilament, 5000));
// filament pushed - performing cut REQUIRE(WhileTopState(ef, ProgressCode::EjectingFilament, 5000));
REQUIRE(ef.TopLevelState() == ProgressCode::PerformingCut);
REQUIRE(WhileTopState(ef, ProgressCode::PerformingCut, 5000));
// returning selector // should end up in error disengage idler
REQUIRE(ef.TopLevelState() == ProgressCode::ReturningSelector); REQUIRE(VerifyState2(ef, mg::FilamentLoadState::AtPulley, ejectSlot, selectorParkedPos, false, true, ejectSlot, ml::off, ml::blink0, ErrorCode::RUNNING, ProgressCode::ERRDisengagingIdler));
REQUIRE(WhileTopState(ef, ProgressCode::ReturningSelector, 5000));
// the next states are still @@TODO SimulateErrDisengagingIdler(ef, ErrorCode::FILAMENT_EJECTED);
// Pulley should now be disabled
REQUIRE(VerifyState2(ef, mg::FilamentLoadState::AtPulley, mi::idler.IdleSlotIndex(), selectorParkedPos, false, false, ejectSlot, ml::off, ml::blink0, ErrorCode::FILAMENT_EJECTED, ProgressCode::ERRWaitingForUser));
// Now press Done button
PressButtonAndDebounce(ef, mb::Middle, true);
ClearButtons(ef);
// Idler and Selector are not on HOLD state
REQUIRE(mi::idler.State() != mm::MovableBase::OnHold);
REQUIRE(ms::selector.State() != mm::MovableBase::OnHold);
// Error code is now OK
// LEDs turn off at the ejected slot
REQUIRE(VerifyState2(ef, mg::FilamentLoadState::AtPulley, mi::idler.IdleSlotIndex(), selectorParkedPos, false, false, ejectSlot, ml::off, ml::off, ErrorCode::OK, ProgressCode::OK));
} }
TEST_CASE("eject_filament::invalid_slot", "[eject_filament]") { TEST_CASE("eject_filament::invalid_slot", "[eject_filament]") {