Update unit tests

pull/262/head
D.R.racer 2023-02-28 16:24:57 +01:00 committed by DRracer
parent d75119c8d6
commit ea41fd6b83
8 changed files with 64 additions and 27 deletions

View File

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

View File

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

View File

@ -6,8 +6,10 @@
namespace modules {
namespace motion {
void MovableBase::PlanHome() {
MovableBase::OperationResult MovableBase::PlanHome() {
InvalidateHoming();
if (state == OnHold)
return OperationResult::Refused;
// 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
currentSlot = -1; // important - other state machines may be waiting for a valid Slot() which is not yet correct while homing in progress
PlanHomingMoveForward();
return OperationResult::Accepted;
}
void __attribute__((noinline)) MovableBase::SetCurrents(uint8_t iRun, uint8_t iHold) {

View File

@ -63,7 +63,8 @@ public:
inline void InvalidateHoming() { homingValid = false; }
/// 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; }

View File

@ -20,6 +20,7 @@ public:
/// Plan move of the selector to a specific filament slot
/// @param slot index to move to
/// @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);
/// 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));
}
}
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));
}
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) {
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]") {
for (uint8_t slot = 0; slot < config::toolCount; ++slot) {
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
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
SimulateIdlerHoming(tc);
// Idler would like to rehome at this spot - theoretically it is free to do so and actually will have the homing move planned.
// 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));
// now "fix" FINDA and the command shall finish correctly