Update unit tests

pull/261/head
D.R.racer 2023-02-28 16:24:57 +01:00
parent fd6826787d
commit 2d08b95527
8 changed files with 64 additions and 27 deletions

View File

@ -62,7 +62,7 @@ void Idler::FinishMove() {
} }
Idler::OperationResult Idler::Disengage() { Idler::OperationResult Idler::Disengage() {
if (state == Moving) { if (state == Moving || state == OnHold) {
dbg_logic_P(PSTR("Moving --> Disengage refused")); dbg_logic_P(PSTR("Moving --> Disengage refused"));
return OperationResult::Refused; return OperationResult::Refused;
} }
@ -94,7 +94,7 @@ Idler::OperationResult Idler::Engage(uint8_t slot) {
} }
Idler::OperationResult Idler::PlanMoveInner(uint8_t slot, Operation plannedOp) { Idler::OperationResult Idler::PlanMoveInner(uint8_t slot, Operation plannedOp) {
if (state == Moving) { if (state == Moving || state == OnHold) {
dbg_logic_P(PSTR("Moving --> Engage refused")); dbg_logic_P(PSTR("Moving --> Engage refused"));
return OperationResult::Refused; return OperationResult::Refused;
} }

View File

@ -22,10 +22,12 @@ public:
/// Plan engaging of the idler to a specific filament slot /// Plan engaging of the idler to a specific filament slot
/// @param slot index to be activated /// @param slot index to be activated
/// @returns #OperationResult /// @returns #OperationResult
/// @note if(state==OnHold) all attempts to Engage are rejected with OperationResult::Rejected
OperationResult Engage(uint8_t slot); OperationResult Engage(uint8_t slot);
/// Plan disengaging of the idler, i.e. parking the idler /// Plan disengaging of the idler, i.e. parking the idler
/// @returns #OperationResult /// @returns #OperationResult
/// @note if(state==OnHold) all attempts to Disengage are rejected with OperationResult::Rejected
OperationResult Disengage(); OperationResult Disengage();
/// Plan partial disengaging of the idler /// Plan partial disengaging of the idler

View File

@ -6,8 +6,10 @@
namespace modules { namespace modules {
namespace motion { namespace motion {
void MovableBase::PlanHome() { MovableBase::OperationResult MovableBase::PlanHome() {
InvalidateHoming(); InvalidateHoming();
if (state == OnHold)
return OperationResult::Refused;
// switch to normal mode on this axis // switch to normal mode on this axis
@ -21,6 +23,7 @@ void MovableBase::PlanHome() {
state = HomeForward; // beware - the derived class may change the state if necessary state = HomeForward; // beware - the derived class may change the state if necessary
currentSlot = -1; // important - other state machines may be waiting for a valid Slot() which is not yet correct while homing in progress currentSlot = -1; // important - other state machines may be waiting for a valid Slot() which is not yet correct while homing in progress
PlanHomingMoveForward(); PlanHomingMoveForward();
return OperationResult::Accepted;
} }
void __attribute__((noinline)) MovableBase::SetCurrents(uint8_t iRun, uint8_t iHold) { void __attribute__((noinline)) MovableBase::SetCurrents(uint8_t iRun, uint8_t iHold) {

View File

@ -63,7 +63,8 @@ public:
inline void InvalidateHoming() { homingValid = false; } inline void InvalidateHoming() { homingValid = false; }
/// Prepare a homing move of the axis /// Prepare a homing move of the axis
void PlanHome(); /// @returns true if the move has been planned successfully (i.e. movable is NOT on-hold)
OperationResult PlanHome();
inline bool HomingValid() const { return homingValid; } inline bool HomingValid() const { return homingValid; }

View File

@ -20,6 +20,7 @@ public:
/// Plan move of the selector to a specific filament slot /// Plan move of the selector to a specific filament slot
/// @param slot index to move to /// @param slot index to move to
/// @returns false in case an operation is already underway /// @returns false in case an operation is already underway
/// @note if(state==OnHold) all attempts to move the selector are rejected with OperationResult::Rejected
OperationResult MoveToSlot(uint8_t slot); OperationResult MoveToSlot(uint8_t slot);
/// Performs one step of the state machine according to currently planned operation. /// Performs one step of the state machine according to currently planned operation.

View File

@ -153,3 +153,45 @@ TEST_CASE("homing::refused_home", "[homing]") {
REQUIRE(RefusedHome(slot)); REQUIRE(RefusedHome(slot));
} }
} }
bool OnHold(uint8_t slot) {
// prepare startup conditions
ForceReinitAllAutomata();
// change the startup to what we need here
HomeIdlerAndSelector();
SetFINDAStateAndDebounce(true);
mg::globals.SetFilamentLoaded(slot, mg::FilamentLoadState::InSelector);
// now put movables on hold
logic::CommandBase::HoldIdlerSelector();
REQUIRE(mi::idler.state == mi::Idler::OnHold);
REQUIRE(ms::selector.state == ms::Selector::OnHold);
// both movables should ignore all attempts to perform moves
REQUIRE(mi::idler.PlanHome() == mi::Idler::OperationResult::Refused);
REQUIRE(mi::idler.state == mi::Idler::OnHold);
REQUIRE(mi::idler.Disengaged());
REQUIRE(ms::selector.PlanHome() == ms::Selector::OperationResult::Refused);
REQUIRE(ms::selector.state == ms::Selector::OnHold);
REQUIRE(mi::idler.Disengage() == mi::Idler::OperationResult::Refused);
REQUIRE(mi::idler.state == mi::Idler::OnHold);
REQUIRE(mi::idler.Engage(slot) == mi::Idler::OperationResult::Refused);
REQUIRE(mi::idler.state == mi::Idler::OnHold);
REQUIRE(mi::idler.Disengaged());
REQUIRE(ms::selector.MoveToSlot((slot + 1) % config::toolCount) == ms::Selector::OperationResult::Refused);
REQUIRE(ms::selector.state == ms::Selector::OnHold);
return true;
}
TEST_CASE("homing::on-hold", "[homing]") {
for (uint8_t slot = 0; slot < config::toolCount; ++slot) {
REQUIRE(OnHold(slot));
}
}

View File

@ -170,18 +170,6 @@ void FailedLoadToFindaResolveManual(uint8_t slot, logic::LoadFilament &lf) {
REQUIRE(VerifyState(lf, mg::FilamentLoadState::AtPulley, mi::Idler::IdleSlotIndex(), slot, false, false, ml::off, ml::off, ErrorCode::OK, ProgressCode::OK)); REQUIRE(VerifyState(lf, mg::FilamentLoadState::AtPulley, mi::Idler::IdleSlotIndex(), slot, false, false, ml::off, ml::off, ErrorCode::OK, ProgressCode::OK));
} }
void FailedLoadToFindaResolveManualNoFINDA(uint8_t slot, logic::LoadFilament &lf) {
// Perform press on button 2 + debounce + keep FINDA OFF (i.e. the user didn't solve anything)
PressButtonAndDebounce(lf, mb::Right, false);
SimulateIdlerHoming(lf);
ClearButtons(lf);
// pulling filament back
REQUIRE(VerifyState(lf, mg::FilamentLoadState::InSelector, mi::Idler::IdleSlotIndex(), slot, false, false, ml::off, ml::blink0, ErrorCode::FINDA_DIDNT_SWITCH_ON, ProgressCode::ERRWaitingForUser));
}
void FailedLoadToFindaResolveTryAgain(uint8_t slot, logic::LoadFilament &lf) { void FailedLoadToFindaResolveTryAgain(uint8_t slot, logic::LoadFilament &lf) {
PressButtonAndDebounce(lf, mb::Middle, false); PressButtonAndDebounce(lf, mb::Middle, false);
@ -218,15 +206,6 @@ TEST_CASE("load_filament::state_machine_reusal", "[load_filament]") {
} }
} }
TEST_CASE("load_filament::failed_load_to_finda_0-4_resolve_manual_no_FINDA", "[load_filament]") {
for (uint8_t slot = 0; slot < config::toolCount; ++slot) {
logic::LoadFilament lf;
LoadFilamentCommonSetup(slot, lf, true);
FailedLoadToFinda(slot, lf);
FailedLoadToFindaResolveManualNoFINDA(slot, lf);
}
}
TEST_CASE("load_filament::failed_load_to_finda_0-4_try_again", "[load_filament]") { TEST_CASE("load_filament::failed_load_to_finda_0-4_try_again", "[load_filament]") {
for (uint8_t slot = 0; slot < config::toolCount; ++slot) { for (uint8_t slot = 0; slot < config::toolCount; ++slot) {
logic::LoadFilament lf; logic::LoadFilament lf;

View File

@ -426,8 +426,17 @@ void ToolChangeWithFlickeringFINDA(logic::ToolChange &tc, uint8_t fromSlot, uint
// we should remain in the same error state // we should remain in the same error state
REQUIRE(VerifyState2(tc, mg::FilamentLoadState::AtPulley, mi::idler.IdleSlotIndex(), fromSlot, true, false, toSlot, ml::off, ml::blink0, ErrorCode::RUNNING, ProgressCode::ERRDisengagingIdler)); REQUIRE(VerifyState2(tc, mg::FilamentLoadState::AtPulley, mi::idler.IdleSlotIndex(), fromSlot, true, false, toSlot, ml::off, ml::blink0, ErrorCode::RUNNING, ProgressCode::ERRDisengagingIdler));
// Idler will try to rehome, allow it // Idler would like to rehome at this spot - theoretically it is free to do so and actually will have the homing move planned.
SimulateIdlerHoming(tc); // In reality, one main cycle of the FW takes ~1ms so the Idler will never really move - which is exactly what we want to leverage
// perform just one step to fall into the same error again
main_loop();
tc.Step();
// now both Idler and Selector are on hold again
REQUIRE(mi::idler.state == mi::Idler::OnHold);
REQUIRE(ms::selector.state == ms::Selector::OnHold);
REQUIRE(VerifyState2(tc, mg::FilamentLoadState::AtPulley, mi::idler.IdleSlotIndex(), fromSlot, true, false, toSlot, ml::off, ml::blink0, ErrorCode::FINDA_FLICKERS, ProgressCode::ERRWaitingForUser)); REQUIRE(VerifyState2(tc, mg::FilamentLoadState::AtPulley, mi::idler.IdleSlotIndex(), fromSlot, true, false, toSlot, ml::off, ml::blink0, ErrorCode::FINDA_FLICKERS, ProgressCode::ERRWaitingForUser));
// now "fix" FINDA and the command shall finish correctly // now "fix" FINDA and the command shall finish correctly