Improve and verify Load filament alg and unit tests

pull/37/head
D.R.racer 2021-06-23 18:35:54 +02:00 committed by DRracer
parent 46a40f7488
commit f6e5d4ae76
10 changed files with 234 additions and 104 deletions

View File

@ -37,7 +37,8 @@ bool FeedToBondtech::Step() {
case PushingFilament: case PushingFilament:
if (mfs::fsensor.Pressed()) { if (mfs::fsensor.Pressed()) {
mm::motion.AbortPlannedMoves(); // stop pushing filament mm::motion.AbortPlannedMoves(); // stop pushing filament
state = DisengagingIdler; // mi::idler.Disengage();
state = OK;
} else if (mm::motion.StallGuard(mm::Pulley)) { } else if (mm::motion.StallGuard(mm::Pulley)) {
// stall guard occurred during movement - the filament got stuck // stall guard occurred during movement - the filament got stuck
state = Failed; // @@TODO may be even report why it failed state = Failed; // @@TODO may be even report why it failed
@ -45,12 +46,12 @@ bool FeedToBondtech::Step() {
state = Failed; state = Failed;
} }
return false; return false;
case DisengagingIdler: // case DisengagingIdler:
if (!mi::idler.Engaged()) { // if (!mi::idler.Engaged()) {
state = OK; // state = OK;
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::Color::green, ml::on); // ml::leds.SetMode(mg::globals.ActiveSlot(), ml::Color::green, ml::on);
} // }
return false; // return false;
case OK: case OK:
case Failed: case Failed:
default: default:

View File

@ -51,14 +51,14 @@ bool FeedToFinda::Step() {
return false; return false;
case UnloadBackToPTFE: case UnloadBackToPTFE:
if (mm::motion.QueueEmpty()) { // all moves have been finished if (mm::motion.QueueEmpty()) { // all moves have been finished
state = DisengagingIdler; // state = DisengagingIdler;
mi::idler.Disengage(); // mi::idler.Disengage();
} // }
return false; // return false;
case DisengagingIdler: // case DisengagingIdler:
if (!mi::idler.Engaged()) { // if (!mi::idler.Engaged()) {
state = OK; state = OK;
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::Color::green, ml::on); // ml::leds.SetMode(mg::globals.ActiveSlot(), ml::Color::green, ml::on);
} }
// @@TODO FINDA must be reported as OFF again as we are pulling the filament from it - is this correct? // @@TODO FINDA must be reported as OFF again as we are pulling the filament from it - is this correct?
return false; return false;

View File

@ -24,6 +24,8 @@ void LoadFilament::Reset(uint8_t param) {
error = ErrorCode::OK; error = ErrorCode::OK;
mg::globals.SetActiveSlot(param); mg::globals.SetActiveSlot(param);
mi::idler.Engage(mg::globals.ActiveSlot()); mi::idler.Engage(mg::globals.ActiveSlot());
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::blink0);
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::off);
} }
bool LoadFilament::Step() { bool LoadFilament::Step() {
@ -40,7 +42,9 @@ bool LoadFilament::Step() {
if (feed.State() == FeedToFinda::Failed) { if (feed.State() == FeedToFinda::Failed) {
// @@TODO - try to repeat 6x - push/pull sequence - probably something to put into feed_to_finda as an option // @@TODO - try to repeat 6x - push/pull sequence - probably something to put into feed_to_finda as an option
state = ProgressCode::ERR1DisengagingIdler; state = ProgressCode::ERR1DisengagingIdler;
error = ErrorCode::FINDA_DIDNT_TRIGGER;
mi::idler.Disengage(); mi::idler.Disengage();
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::Color::green, ml::Mode::off);
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::Color::red, ml::Mode::blink0); // signal loading error ml::leds.SetMode(mg::globals.ActiveSlot(), ml::Color::red, ml::Mode::blink0); // signal loading error
} else { } else {
state = ProgressCode::FeedingToBondtech; state = ProgressCode::FeedingToBondtech;
@ -62,13 +66,14 @@ bool LoadFilament::Step() {
case ProgressCode::DisengagingIdler: case ProgressCode::DisengagingIdler:
if (!mi::idler.Engaged()) { if (!mi::idler.Engaged()) {
state = ProgressCode::OK; state = ProgressCode::OK;
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::off);
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::on);
mg::globals.SetFilamentLoaded(true);
} }
break; break;
case ProgressCode::OK: case ProgressCode::OK:
mg::globals.SetFilamentLoaded(true);
return true; return true;
case ProgressCode::ERR1DisengagingIdler: // couldn't unload to FINDA case ProgressCode::ERR1DisengagingIdler: // couldn't unload to FINDA
error = ErrorCode::FINDA_DIDNT_TRIGGER;
if (!mi::idler.Engaged()) { if (!mi::idler.Engaged()) {
state = ProgressCode::ERR1WaitingForUser; state = ProgressCode::ERR1WaitingForUser;
} }
@ -80,12 +85,13 @@ bool LoadFilament::Step() {
bool userResolved = modules::buttons::buttons.ButtonPressed(modules::buttons::Right) /*|| command_userResolved()*/; bool userResolved = modules::buttons::buttons.ButtonPressed(modules::buttons::Right) /*|| command_userResolved()*/;
if (help) { if (help) {
// try to manually load just a tiny bit - help the filament with the pulley // try to manually load just a tiny bit - help the filament with the pulley
//@@TODO state = ProgressCode::ERR1EngagingIdler;
mi::idler.Engage(mg::globals.ActiveSlot());
} else if (tryAgain) { } else if (tryAgain) {
// try again the whole sequence // try again the whole sequence
Reset(0); // @@TODO param Reset(mg::globals.ActiveSlot());
} else if (userResolved) { } else if (userResolved) {
// problem resolved - the user pulled the fillament by hand // problem resolved - the user pushed the fillament by hand?
modules::leds::leds.SetMode(mg::globals.ActiveSlot(), modules::leds::red, modules::leds::off); modules::leds::leds.SetMode(mg::globals.ActiveSlot(), modules::leds::red, modules::leds::off);
modules::leds::leds.SetMode(mg::globals.ActiveSlot(), modules::leds::green, modules::leds::on); modules::leds::leds.SetMode(mg::globals.ActiveSlot(), modules::leds::green, modules::leds::on);
// mm::motion.PlanMove(mm::Pulley, 450, 5000); // @@TODO constants // mm::motion.PlanMove(mm::Pulley, 450, 5000); // @@TODO constants
@ -93,6 +99,26 @@ bool LoadFilament::Step() {
} }
return false; return false;
} }
case ProgressCode::ERR1EngagingIdler:
if (mi::idler.Engaged()) {
state = ProgressCode::ERR1HelpingFilament;
mm::motion.PlanMove(mm::Pulley, 450, 5000); //@@TODO constants
}
return false;
case ProgressCode::ERR1HelpingFilament:
if (mf::finda.Pressed()) {
// the help was enough to press the FINDA, we are ok, continue normally
state = ProgressCode::FeedingToBondtech;
error = ErrorCode::OK;
} else if (mm::motion.QueueEmpty()) {
// helped a bit, but FINDA didn't trigger, return to the main error state
state = ProgressCode::ERR1DisengagingIdler;
}
return false;
default: // we got into an unhandled state, better report it
state = ProgressCode::ERRInternal;
error = ErrorCode::INTERNAL;
return true;
} }
return false; return false;
} }

View File

@ -84,7 +84,7 @@ bool UnloadFilament::Step() {
mi::idler.Engage(mg::globals.ActiveSlot()); mi::idler.Engage(mg::globals.ActiveSlot());
} else if (tryAgain) { } else if (tryAgain) {
// try again the whole sequence // try again the whole sequence
Reset(0); Reset(0); //@@TODO validate the reset parameter
} else if (userResolved) { } else if (userResolved) {
// problem resolved - the user pulled the fillament by hand // problem resolved - the user pulled the fillament by hand
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::off); ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::off);

View File

@ -62,26 +62,30 @@ TEST_CASE("feed_to_finda::feed_phase_unlimited", "[feed_to_finda]") {
// at least at the beginning the LED should shine green (it should be blinking, but this mode has been already verified in the LED's unit test) // at least at the beginning the LED should shine green (it should be blinking, but this mode has been already verified in the LED's unit test)
REQUIRE(ml::leds.LedOn(mg::globals.ActiveSlot(), ml::Color::green)); REQUIRE(ml::leds.LedOn(mg::globals.ActiveSlot(), ml::Color::green));
// @@TODO simulate incoming message from the printer - fsensor triggered
REQUIRE(WhileCondition( REQUIRE(WhileCondition(
fb, fb,
[&](int) { return fb.State() == FeedToBondtech::PushingFilament; }, [&](int step) {
if( step == 1000 ){
modules::fsensor::fsensor.ProcessMessage(true);
}
return fb.State() == FeedToBondtech::PushingFilament; },
1500)); 1500));
// disengaging idler REQUIRE(modules::fsensor::fsensor.Pressed());
REQUIRE(fb.State() == FeedToBondtech::DisengagingIdler);
REQUIRE(WhileCondition(
fb,
[&](int) { return fb.State() == FeedToBondtech::DisengagingIdler; },
5000));
CHECK(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(5)); // @@TODO constants // // disengaging idler
// REQUIRE(fb.State() == FeedToBondtech::DisengagingIdler);
// REQUIRE(WhileCondition(
// fb,
// [&](int) { return fb.State() == FeedToBondtech::DisengagingIdler; },
// 5000));
// CHECK(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(5)); // @@TODO constants
CHECK(mm::axes[mm::Selector].pos == ms::Selector::SlotPosition(0)); CHECK(mm::axes[mm::Selector].pos == ms::Selector::SlotPosition(0));
// state machine finished ok, the green LED should be on // state machine finished ok, the green LED should be on
REQUIRE(fb.State() == FeedToBondtech::OK); REQUIRE(fb.State() == FeedToBondtech::OK);
REQUIRE(ml::leds.LedOn(mg::globals.ActiveSlot(), ml::Color::green)); // REQUIRE(ml::leds.LedOn(mg::globals.ActiveSlot(), ml::Color::green));
REQUIRE(fb.Step() == true); // the automaton finished its work, any consecutive calls to Step must return true REQUIRE(fb.Step() == true); // the automaton finished its work, any consecutive calls to Step must return true
} }

View File

@ -79,19 +79,19 @@ TEST_CASE("feed_to_finda::feed_phase_unlimited", "[feed_to_finda]") {
[&](int) { return ff.State() == FeedToFinda::UnloadBackToPTFE; }, [&](int) { return ff.State() == FeedToFinda::UnloadBackToPTFE; },
5000)); 5000));
// disengaging idler // // disengaging idler
REQUIRE(ff.State() == FeedToFinda::DisengagingIdler); // REQUIRE(ff.State() == FeedToFinda::DisengagingIdler);
REQUIRE(WhileCondition( // REQUIRE(WhileCondition(
ff, // ff,
[&](int) { return mi::idler.Engaged(); }, // [&](int) { return mi::idler.Engaged(); },
5000)); // 5000));
CHECK(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(5)); // @@TODO constants CHECK(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(0)); // @@TODO constants
CHECK(mm::axes[mm::Selector].pos == ms::Selector::SlotPosition(0)); CHECK(mm::axes[mm::Selector].pos == ms::Selector::SlotPosition(0));
// state machine finished ok, the green LED should be on // state machine finished ok, the green LED should be on
REQUIRE(ff.State() == FeedToFinda::OK); REQUIRE(ff.State() == FeedToFinda::OK);
REQUIRE(ml::leds.LedOn(mg::globals.ActiveSlot(), ml::Color::green)); REQUIRE(ml::leds.Mode(mg::globals.ActiveSlot(), ml::green) == ml::blink0);
REQUIRE(ff.Step() == true); // the automaton finished its work, any consecutive calls to Step must return true REQUIRE(ff.Step() == true); // the automaton finished its work, any consecutive calls to Step must return true
} }

View File

@ -0,0 +1,15 @@
template<typename SM>
bool VerifyState(SM &uf, bool filamentLoaded, uint8_t idlerSlotIndex, uint8_t selectorSlotIndex,
bool findaPressed, ml::Mode greenLEDMode, ml::Mode redLEDMode, ErrorCode err, ProgressCode topLevelProgress) {
CHECKED_ELSE(mg::globals.FilamentLoaded() == filamentLoaded) { return false; }
CHECKED_ELSE(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(idlerSlotIndex)) { return false; }
CHECKED_ELSE(mi::idler.Engaged() == (idlerSlotIndex < 5)) { return false; }
CHECKED_ELSE(mm::axes[mm::Selector].pos == ms::Selector::SlotPosition(selectorSlotIndex)) { return false; }
CHECKED_ELSE(ms::selector.Slot() == selectorSlotIndex) { return false; }
CHECKED_ELSE(mf::finda.Pressed() == findaPressed) { return false; }
CHECKED_ELSE(ml::leds.Mode(selectorSlotIndex, ml::red) == redLEDMode) { return false; }
CHECKED_ELSE(ml::leds.Mode(selectorSlotIndex, ml::green) == greenLEDMode) { return false; }
CHECKED_ELSE(uf.Error() == err) { return false; }
CHECKED_ELSE(uf.TopLevelState() == topLevelProgress) { return false; }
return true;
}

View File

@ -27,30 +27,143 @@ namespace mb = modules::buttons;
namespace mg = modules::globals; namespace mg = modules::globals;
namespace ms = modules::selector; namespace ms = modules::selector;
TEST_CASE("unload_filament::unload0", "[unload_filament]") { #include "../helpers/helpers.ipp"
using namespace logic;
void LoadFilamentCommonSetup(uint8_t slot, logic::LoadFilament &lf) {
ForceReinitAllAutomata(); ForceReinitAllAutomata();
LoadFilament lf; // change the startup to what we need here
EnsureActiveSlotIndex(slot);
// verify startup conditions
REQUIRE(VerifyState(lf, false, 5, slot, false, ml::off, ml::off, ErrorCode::OK, ProgressCode::OK));
// restart the automaton // restart the automaton
lf.Reset(0); lf.Reset(slot);
main_loop(); // Stage 0 - verify state just after Reset()
// we assume the filament is not loaded
// idler should have been activated by the underlying automaton
// no change in selector's position
// FINDA off
// green LED should blink, red off
REQUIRE(VerifyState(lf, false, 5, slot, false, ml::blink0, ml::off, ErrorCode::OK, ProgressCode::EngagingIdler));
// REQUIRE(WhileCondition([&]() { return uf.TopLevelState() == ProgressCode::UnloadingToFinda; }, 5000)); // Stage 1 - engaging idler
REQUIRE(WhileTopState(lf, ProgressCode::EngagingIdler, 5000));
// REQUIRE(uf.TopLevelState() == ProgressCode::DisengagingIdler); REQUIRE(VerifyState(lf, false, slot, slot, false, ml::blink0, ml::off, ErrorCode::OK, ProgressCode::FeedingToFinda));
// REQUIRE(WhileCondition([&]() { return uf.TopLevelState() == ProgressCode::DisengagingIdler; }, 5000)); }
// CHECK(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(5)); void LoadFilamentSuccessful(uint8_t slot, logic::LoadFilament &lf) {
// Stage 2 - feeding to finda
// REQUIRE(uf.TopLevelState() == ProgressCode::AvoidingGrind); // we'll assume the finda is working correctly here
// REQUIRE(WhileCondition([&]() { return uf.TopLevelState() == ProgressCode::AvoidingGrind; }, 5000)); REQUIRE(WhileCondition(
lf,
// REQUIRE(uf.TopLevelState() == ProgressCode::FinishingMoves); [&](int step) -> bool {
// REQUIRE(WhileCondition([&]() { return uf.TopLevelState() == ProgressCode::FinishingMoves; }, 5000)); if(step == 100){ // on 100th step make FINDA trigger
hal::adc::SetADC(1, 1023);
// REQUIRE(uf.TopLevelState() == ProgressCode::OK); }
REQUIRE(modules::globals::globals.FilamentLoaded() == true); return lf.TopLevelState() == ProgressCode::FeedingToFinda; },
5000));
REQUIRE(VerifyState(lf, false, slot, slot, true, ml::blink0, ml::off, ErrorCode::OK, ProgressCode::FeedingToBondtech));
// Stage 3 - feeding to bondtech
// we'll make a fsensor switch during the process
REQUIRE(WhileCondition(
lf,
[&](int step) -> bool {
if(step == 100){ // on 100th step make fsensor trigger
modules::fsensor::fsensor.ProcessMessage(true);
}
return lf.TopLevelState() == ProgressCode::FeedingToBondtech; },
5000));
REQUIRE(VerifyState(lf, false, slot, slot, true, ml::blink0, ml::off, ErrorCode::OK, ProgressCode::DisengagingIdler));
// Stage 4 - disengaging idler
REQUIRE(WhileTopState(lf, ProgressCode::DisengagingIdler, 5000));
REQUIRE(VerifyState(lf, true, 5, slot, true, ml::on, ml::off, ErrorCode::OK, ProgressCode::OK));
}
TEST_CASE("load_filament::regular_load_to_slot_0-4", "[load_filament]") {
for (uint8_t slot = 0; slot < 5; ++slot) {
logic::LoadFilament lf;
LoadFilamentCommonSetup(slot, lf);
LoadFilamentSuccessful(slot, lf);
}
}
void FailedLoadToFinda(uint8_t slot, logic::LoadFilament &lf) {
// Stage 2 - feeding to finda
// we'll assume the finda is defective here and does not trigger
REQUIRE(WhileTopState(lf, ProgressCode::FeedingToFinda, 5000));
REQUIRE(VerifyState(lf, false, slot, slot, false, ml::off, ml::blink0, ErrorCode::FINDA_DIDNT_TRIGGER, ProgressCode::ERR1DisengagingIdler));
// Stage 3 - disengaging idler in error mode
REQUIRE(WhileTopState(lf, ProgressCode::ERR1DisengagingIdler, 5000));
REQUIRE(VerifyState(lf, false, 5, slot, false, ml::off, ml::blink0, ErrorCode::FINDA_DIDNT_TRIGGER, ProgressCode::ERR1WaitingForUser));
}
void FailedLoadToFindaResolveHelp(uint8_t slot, logic::LoadFilament &lf) {
// Stage 3 - the user has to do something
// there are 3 options:
// - help the filament a bit
// - try again the whole sequence
// - resolve the problem by hand - after pressing the button we shall check, that FINDA is off and we should do what?
// In this case we check the first option
// Perform press on button 1 + debounce
hal::adc::SetADC(0, 0);
while (!mb::buttons.ButtonPressed(0)) {
main_loop();
lf.Step();
}
REQUIRE(VerifyState(lf, false, 5, slot, false, ml::off, ml::blink0, ErrorCode::FINDA_DIDNT_TRIGGER, ProgressCode::ERR1EngagingIdler));
// Stage 4 - engage the idler
REQUIRE(WhileTopState(lf, ProgressCode::ERR1EngagingIdler, 5000));
REQUIRE(VerifyState(lf, false, slot, slot, false, ml::off, ml::blink0, ErrorCode::FINDA_DIDNT_TRIGGER, ProgressCode::ERR1HelpingFilament));
}
void FailedLoadToFindaResolveHelpFindaTriggered(uint8_t slot, logic::LoadFilament &lf) {
// Stage 5 - move the pulley a bit - simulate FINDA depress
REQUIRE(WhileCondition(
lf,
[&](int step) -> bool {
if(step == 100){ // on 100th step make FINDA trigger
hal::adc::SetADC(1, 1023);
}
return lf.TopLevelState() == ProgressCode::ERR1HelpingFilament; },
5000));
REQUIRE(VerifyState(lf, false, slot, slot, true, ml::off, ml::blink0, ErrorCode::OK, ProgressCode::FeedingToBondtech));
}
void FailedLoadToFindaResolveHelpFindaDidntTrigger(uint8_t slot, logic::LoadFilament &lf) {
// Stage 5 - move the pulley a bit - no FINDA change
REQUIRE(WhileTopState(lf, ProgressCode::ERR1HelpingFilament, 5000));
REQUIRE(VerifyState(lf, false, slot, slot, false, ml::off, ml::blink0, ErrorCode::FINDA_DIDNT_TRIGGER, ProgressCode::ERR1DisengagingIdler));
}
TEST_CASE("load_filament::failed_load_to_finda_0-4_resolve_help_second_ok", "[load_filament]") {
for (uint8_t slot = 0; slot < 5; ++slot) {
logic::LoadFilament lf;
LoadFilamentCommonSetup(slot, lf);
FailedLoadToFinda(slot, lf);
FailedLoadToFindaResolveHelp(slot, lf);
FailedLoadToFindaResolveHelpFindaTriggered(slot, lf);
}
}
TEST_CASE("load_filament::failed_load_to_finda_0-4_resolve_help_second_fail", "[load_filament]") {
for (uint8_t slot = 0; slot < 5; ++slot) {
logic::LoadFilament lf;
LoadFilamentCommonSetup(slot, lf);
FailedLoadToFinda(slot, lf);
FailedLoadToFindaResolveHelp(slot, lf);
FailedLoadToFindaResolveHelpFindaDidntTrigger(slot, lf);
}
} }

View File

@ -27,20 +27,7 @@ namespace mb = modules::buttons;
namespace mg = modules::globals; namespace mg = modules::globals;
namespace ms = modules::selector; namespace ms = modules::selector;
bool VerifyState(logic::UnloadFilament &uf, bool filamentLoaded, uint8_t idlerSlotIndex, uint8_t selectorSlotIndex, #include "../helpers/helpers.ipp"
bool findaPressed, ml::Mode greenLEDMode, ml::Mode redLEDMode, ErrorCode err, ProgressCode topLevelProgress) {
CHECKED_ELSE(mg::globals.FilamentLoaded() == filamentLoaded) { return false; }
CHECKED_ELSE(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(idlerSlotIndex)) { return false; }
CHECKED_ELSE(mi::idler.Engaged() == (idlerSlotIndex < 5)) { return false; }
CHECKED_ELSE(mm::axes[mm::Selector].pos == ms::Selector::SlotPosition(selectorSlotIndex)) { return false; }
CHECKED_ELSE(ms::selector.Slot() == selectorSlotIndex) { return false; }
CHECKED_ELSE(mf::finda.Pressed() == findaPressed) { return false; }
CHECKED_ELSE(ml::leds.Mode(selectorSlotIndex, ml::red) == redLEDMode) { return false; }
CHECKED_ELSE(ml::leds.Mode(selectorSlotIndex, ml::green) == greenLEDMode) { return false; }
CHECKED_ELSE(uf.Error() == err) { return false; }
CHECKED_ELSE(uf.TopLevelState() == topLevelProgress) { return false; }
return true;
}
void RegularUnloadFromSlot04Init(uint8_t slot, logic::UnloadFilament &uf) { void RegularUnloadFromSlot04Init(uint8_t slot, logic::UnloadFilament &uf) {
// prepare startup conditions // prepare startup conditions
@ -251,14 +238,16 @@ void FindaDidntTriggerResolveHelpFindaDidntTrigger(uint8_t slot, logic::UnloadFi
REQUIRE(VerifyState(uf, true, slot, slot, true, ml::off, ml::blink0, ErrorCode::FINDA_DIDNT_TRIGGER, ProgressCode::ERR1DisengagingIdler)); REQUIRE(VerifyState(uf, true, slot, slot, true, ml::off, ml::blink0, ErrorCode::FINDA_DIDNT_TRIGGER, ProgressCode::ERR1DisengagingIdler));
} }
TEST_CASE("unload_filament::finda_didnt_trigger_resolve_help", "[unload_filament]") { TEST_CASE("unload_filament::finda_didnt_trigger_resolve_help_second_ok", "[unload_filament]") {
for (uint8_t slot = 0; slot < 5; ++slot) { for (uint8_t slot = 0; slot < 5; ++slot) {
logic::UnloadFilament uf; logic::UnloadFilament uf;
FindaDidntTriggerCommonSetup(slot, uf); FindaDidntTriggerCommonSetup(slot, uf);
FindaDidntTriggerResolveHelp(slot, uf); FindaDidntTriggerResolveHelp(slot, uf);
FindaDidntTriggerResolveHelpFindaTriggered(slot, uf); FindaDidntTriggerResolveHelpFindaTriggered(slot, uf);
} }
}
TEST_CASE("unload_filament::finda_didnt_trigger_resolve_help_second_fail", "[unload_filament]") {
// the same with different end scenario // the same with different end scenario
for (uint8_t slot = 0; slot < 5; ++slot) { for (uint8_t slot = 0; slot < 5; ++slot) {
logic::UnloadFilament uf; logic::UnloadFilament uf;

View File

@ -30,25 +30,17 @@ namespace ms = modules::selector;
namespace ha = hal::adc; namespace ha = hal::adc;
TEST_CASE("unload_to_finda::regular_unload", "[unload_to_finda]") { TEST_CASE("unload_to_finda::regular_unload", "[unload_to_finda]") {
using namespace logic;
ForceReinitAllAutomata(); ForceReinitAllAutomata();
// we need finda ON // we need finda ON
hal::adc::ReinitADC(1, hal::adc::TADCData({ 1023 }), 1); SetFINDAStateAndDebounce(true);
UnloadToFinda ff; logic::UnloadToFinda ff;
// wait for FINDA to debounce
REQUIRE(WhileCondition(
ff,
[&](int) { return !mf::finda.Pressed(); },
5000));
// restart the automaton - just 1 attempt // restart the automaton - just 1 attempt
ff.Reset(1); ff.Reset(1);
REQUIRE(ff.State() == UnloadToFinda::EngagingIdler); REQUIRE(ff.State() == logic::UnloadToFinda::EngagingIdler);
// it should have instructed the selector and idler to move to slot 1 // it should have instructed the selector and idler to move to slot 1
// check if the idler and selector have the right command // check if the idler and selector have the right command
@ -63,51 +55,41 @@ TEST_CASE("unload_to_finda::regular_unload", "[unload_to_finda]") {
5000)); 5000));
// now pulling the filament until finda triggers // now pulling the filament until finda triggers
REQUIRE(ff.State() == UnloadToFinda::WaitingForFINDA); REQUIRE(ff.State() == logic::UnloadToFinda::WaitingForFINDA);
hal::adc::ReinitADC(1, hal::adc::TADCData({ 1023, 900, 800, 500, 0 }), 10); hal::adc::ReinitADC(1, hal::adc::TADCData({ 1023, 900, 800, 500, 0 }), 10);
REQUIRE(WhileCondition( REQUIRE(WhileCondition(
ff, ff,
[&](int) { return mf::finda.Pressed(); }, [&](int) { return mf::finda.Pressed(); },
50000)); 50000));
REQUIRE(ff.State() == UnloadToFinda::OK); REQUIRE(ff.State() == logic::UnloadToFinda::OK);
} }
TEST_CASE("unload_to_finda::no_sense_FINDA_upon_start", "[unload_to_finda]") { TEST_CASE("unload_to_finda::no_sense_FINDA_upon_start", "[unload_to_finda]") {
using namespace logic;
ForceReinitAllAutomata(); // that implies FINDA OFF which should really not happen for an unload call ForceReinitAllAutomata(); // that implies FINDA OFF which should really not happen for an unload call
UnloadToFinda ff; logic::UnloadToFinda ff;
// restart the automaton - just 1 attempt // restart the automaton - just 1 attempt
ff.Reset(1); ff.Reset(1);
// the state machine should accept the unpressed FINDA as no-fillament-loaded // the state machine should accept the unpressed FINDA as no-fillament-loaded
// thus should immediately end in the OK state // thus should immediately end in the OK state
REQUIRE(ff.State() == UnloadToFinda::OK); REQUIRE(ff.State() == logic::UnloadToFinda::OK);
} }
TEST_CASE("unload_to_finda::unload_without_FINDA_trigger", "[unload_to_finda]") { TEST_CASE("unload_to_finda::unload_without_FINDA_trigger", "[unload_to_finda]") {
using namespace logic;
ForceReinitAllAutomata(); ForceReinitAllAutomata();
// we need finda ON // we need finda ON
hal::adc::ReinitADC(1, hal::adc::TADCData({ 1023 }), 1); SetFINDAStateAndDebounce(true);
UnloadToFinda ff; logic::UnloadToFinda ff;
// wait for FINDA to debounce
REQUIRE(WhileCondition(
ff,
[&](int) { return !mf::finda.Pressed(); },
5000));
// restart the automaton - just 1 attempt // restart the automaton - just 1 attempt
ff.Reset(1); ff.Reset(1);
REQUIRE(ff.State() == UnloadToFinda::EngagingIdler); REQUIRE(ff.State() == logic::UnloadToFinda::EngagingIdler);
// it should have instructed the selector and idler to move to slot 1 // it should have instructed the selector and idler to move to slot 1
// check if the idler and selector have the right command // check if the idler and selector have the right command
@ -122,7 +104,7 @@ TEST_CASE("unload_to_finda::unload_without_FINDA_trigger", "[unload_to_finda]")
5000)); 5000));
// now pulling the filament until finda triggers // now pulling the filament until finda triggers
REQUIRE(ff.State() == UnloadToFinda::WaitingForFINDA); REQUIRE(ff.State() == logic::UnloadToFinda::WaitingForFINDA);
// no changes to FINDA during unload - we'll pretend it never triggers // no changes to FINDA during unload - we'll pretend it never triggers
REQUIRE(!WhileCondition( REQUIRE(!WhileCondition(
@ -130,5 +112,5 @@ TEST_CASE("unload_to_finda::unload_without_FINDA_trigger", "[unload_to_finda]")
[&](int) { return mf::finda.Pressed(); }, [&](int) { return mf::finda.Pressed(); },
50000)); 50000));
REQUIRE(ff.State() == UnloadToFinda::Failed); REQUIRE(ff.State() == logic::UnloadToFinda::Failed);
} }