Fix waiting for homing of Selector after UnloadFilament
parent
c95c6677b1
commit
b685ec4aff
|
|
@ -25,7 +25,9 @@ public:
|
|||
|
||||
ErrorCode Error() const override;
|
||||
|
||||
#ifndef UNITTEST
|
||||
private:
|
||||
#endif
|
||||
void GoToFeedingToBondtech();
|
||||
|
||||
/// Common code for a correct completion of UnloadFilament
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ bool UnloadFilament::StepInner() {
|
|||
}
|
||||
return false;
|
||||
case ProgressCode::DisengagingIdler:
|
||||
if (!mi::idler.Engaged()) {
|
||||
if (!mi::idler.Engaged() && ms::selector.State() == ms::Selector::Ready) {
|
||||
FinishedCorrectly();
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -87,17 +87,21 @@ bool VerifyState2(SM &uf, mg::FilamentLoadState fls, uint8_t idlerSlotIndex, uin
|
|||
CHECKED_ELSE(mg::globals.FilamentLoaded() & fls) {
|
||||
return false;
|
||||
}
|
||||
CHECKED_ELSE(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(idlerSlotIndex).v) {
|
||||
return false;
|
||||
if( idlerSlotIndex < config::toolCount ){ // abusing invalid index to skip checking of slot and position
|
||||
CHECKED_ELSE(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(idlerSlotIndex).v) {
|
||||
return false;
|
||||
}
|
||||
CHECKED_ELSE(mi::idler.Engaged() == (idlerSlotIndex < config::toolCount)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
CHECKED_ELSE(mi::idler.Engaged() == (idlerSlotIndex < config::toolCount)) {
|
||||
return false;
|
||||
}
|
||||
CHECKED_ELSE(mm::axes[mm::Selector].pos == ms::Selector::SlotPosition(selectorSlotIndex).v) {
|
||||
return false;
|
||||
}
|
||||
CHECKED_ELSE(ms::selector.Slot() == selectorSlotIndex) {
|
||||
return false;
|
||||
if( selectorSlotIndex < config::toolCount ){ // abusing invalid index to skip checking of slot and position
|
||||
CHECKED_ELSE(mm::axes[mm::Selector].pos == ms::Selector::SlotPosition(selectorSlotIndex).v) {
|
||||
return false;
|
||||
}
|
||||
CHECKED_ELSE(ms::selector.Slot() == selectorSlotIndex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
CHECKED_ELSE(mf::finda.Pressed() == findaPressed) {
|
||||
return false;
|
||||
|
|
@ -116,10 +120,12 @@ bool VerifyState2(SM &uf, mg::FilamentLoadState fls, uint8_t idlerSlotIndex, uin
|
|||
return false;
|
||||
}
|
||||
} else {
|
||||
CHECKED_ELSE(ml::leds.Mode(ledCheckIndex, ml::red) == redLEDMode) {
|
||||
auto lmr = ml::leds.Mode(ledCheckIndex, ml::red);
|
||||
CHECKED_ELSE(lmr == redLEDMode) {
|
||||
return false;
|
||||
}
|
||||
CHECKED_ELSE(ml::leds.Mode(ledCheckIndex, ml::green) == greenLEDMode) {
|
||||
auto lmg = ml::leds.Mode(ledCheckIndex, ml::green);
|
||||
CHECKED_ELSE(lmg == greenLEDMode) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,20 @@ bool SimulateUnloadToFINDA(uint32_t step, uint32_t fsOff, uint32_t findaOff) {
|
|||
return mf::finda.Pressed();
|
||||
}
|
||||
|
||||
bool SimulateFeedToFINDA(uint32_t step, uint32_t findaOn) {
|
||||
if (step == findaOn) {
|
||||
hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::high);
|
||||
}
|
||||
return !mf::finda.Pressed();
|
||||
}
|
||||
|
||||
bool SimulateRetractFromFINDA(uint32_t step, uint32_t findaOff) {
|
||||
if (step == findaOff) {
|
||||
hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::low);
|
||||
}
|
||||
return mf::finda.Pressed();
|
||||
}
|
||||
|
||||
void PressButtonAndDebounce(logic::CommandBase &cb, uint8_t btnIndex) {
|
||||
hal::adc::SetADC(config::buttonsADCIndex, config::buttonADCLimits[btnIndex][0] + 1);
|
||||
while (!mb::buttons.ButtonPressed(btnIndex)) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ void EnsureActiveSlotIndex(uint8_t slot, modules::globals::FilamentLoadState loa
|
|||
|
||||
void SetFINDAStateAndDebounce(bool press);
|
||||
bool SimulateUnloadToFINDA(uint32_t step, uint32_t fsOff, uint32_t findaOff);
|
||||
bool SimulateFeedToFINDA(uint32_t step, uint32_t findaOn);
|
||||
bool SimulateRetractFromFINDA(uint32_t step, uint32_t findaOff);
|
||||
|
||||
void PressButtonAndDebounce(logic::CommandBase &cb, uint8_t btnIndex);
|
||||
void ClearButtons(logic::CommandBase &cb);
|
||||
|
|
|
|||
|
|
@ -14,25 +14,30 @@
|
|||
|
||||
#include "../../modules/stubs/stub_adc.h"
|
||||
|
||||
#include "../stubs/homing.h"
|
||||
#include "../stubs/main_loop_stub.h"
|
||||
#include "../stubs/stub_motion.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
using Catch::Matchers::Equals;
|
||||
using namespace std::placeholders;
|
||||
|
||||
#include "../helpers/helpers.ipp"
|
||||
|
||||
// needs to be a separate function otherwise gdb has issues setting breakpoints inside
|
||||
bool FeedingToFindaStep(logic::CommandBase &tc, uint32_t step, uint32_t triggerAt) {
|
||||
if (step == triggerAt) { // on specified stepNr make FINDA trigger
|
||||
hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::high);
|
||||
} else if (step >= triggerAt + config::findaDebounceMs + 2) {
|
||||
REQUIRE(mf::finda.Pressed() == true);
|
||||
}
|
||||
return tc.TopLevelState() == ProgressCode::FeedingToFinda;
|
||||
}
|
||||
|
||||
void FeedingToFinda(logic::ToolChange &tc, uint8_t toSlot, uint32_t triggerAt = 1000) {
|
||||
// feeding to finda
|
||||
REQUIRE(WhileCondition(
|
||||
tc,
|
||||
[&](uint32_t step) -> bool {
|
||||
if(step == triggerAt){ // on specified stepNr make FINDA trigger
|
||||
hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::high);
|
||||
} else if(step >= triggerAt + config::findaDebounceMs + 1){
|
||||
REQUIRE(mf::finda.Pressed() == true);
|
||||
}
|
||||
return tc.TopLevelState() == ProgressCode::FeedingToFinda; },
|
||||
200000UL));
|
||||
REQUIRE(WhileCondition(tc, std::bind(FeedingToFindaStep, std::ref(tc), _1, triggerAt), 200'000UL));
|
||||
REQUIRE(VerifyState(tc, mg::FilamentLoadState::InSelector, toSlot, toSlot, true, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::FeedingToBondtech));
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +63,8 @@ void CheckFinishedCorrectly(logic::ToolChange &tc, uint8_t toSlot) {
|
|||
void ToolChange(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) {
|
||||
ForceReinitAllAutomata();
|
||||
|
||||
SetFINDAStateAndDebounce(true);
|
||||
mfs::fsensor.ProcessMessage(true);
|
||||
EnsureActiveSlotIndex(fromSlot, mg::FilamentLoadState::InNozzle);
|
||||
|
||||
// restart the automaton
|
||||
|
|
@ -86,9 +93,11 @@ void NoToolChange(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) {
|
|||
ForceReinitAllAutomata();
|
||||
|
||||
// the filament is LOADED
|
||||
SetFINDAStateAndDebounce(true);
|
||||
mfs::fsensor.ProcessMessage(true);
|
||||
EnsureActiveSlotIndex(fromSlot, mg::FilamentLoadState::InNozzle);
|
||||
|
||||
REQUIRE(VerifyEnvironmentState(mg::FilamentLoadState::InNozzle, mi::Idler::IdleSlotIndex(), toSlot, false, false, ml::off, ml::off));
|
||||
REQUIRE(VerifyEnvironmentState(mg::FilamentLoadState::InNozzle, mi::Idler::IdleSlotIndex(), toSlot, true, false, ml::off, ml::off));
|
||||
|
||||
// restart the automaton
|
||||
tc.Reset(toSlot);
|
||||
|
|
@ -162,19 +171,15 @@ TEST_CASE("tool_change::same_slot_just_unloaded_filament", "[tool_change]") {
|
|||
void ToolChangeFailLoadToFinda(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) {
|
||||
ForceReinitAllAutomata();
|
||||
|
||||
SetFINDAStateAndDebounce(true);
|
||||
mfs::fsensor.ProcessMessage(true);
|
||||
EnsureActiveSlotIndex(fromSlot, mg::FilamentLoadState::InNozzle);
|
||||
|
||||
// restart the automaton
|
||||
tc.Reset(toSlot);
|
||||
|
||||
REQUIRE(WhileCondition(
|
||||
tc,
|
||||
[&](uint32_t step) -> bool {
|
||||
if(step == 2000){ // on 2000th step make FINDA trigger
|
||||
hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::low);
|
||||
}
|
||||
return tc.TopLevelState() == ProgressCode::UnloadingFilament; },
|
||||
200000UL));
|
||||
REQUIRE(WhileCondition(tc, std::bind(SimulateUnloadToFINDA, _1, 100, 2'000), 200'000));
|
||||
REQUIRE(WhileTopState(tc, ProgressCode::UnloadingFilament, 5000));
|
||||
|
||||
REQUIRE(mg::globals.FilamentLoaded() == mg::FilamentLoadState::AtPulley);
|
||||
|
||||
|
|
@ -316,3 +321,75 @@ TEST_CASE("tool_change::load_fail_FINDA_resolve_btnR_FINDA", "[tool_change]") {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ToolChangeFailFSensor(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) {
|
||||
using namespace std::placeholders;
|
||||
ForceReinitAllAutomata();
|
||||
|
||||
SetFINDAStateAndDebounce(true);
|
||||
mfs::fsensor.ProcessMessage(true);
|
||||
EnsureActiveSlotIndex(fromSlot, mg::FilamentLoadState::InNozzle);
|
||||
|
||||
// restart the automaton
|
||||
tc.Reset(toSlot);
|
||||
|
||||
REQUIRE(VerifyState(tc, mg::FilamentLoadState::InNozzle, mi::idler.IdleSlotIndex(), fromSlot, true, true, ml::off, ml::off, ErrorCode::RUNNING, ProgressCode::UnloadingFilament));
|
||||
// simulate unload to finda but fail the fsensor test
|
||||
REQUIRE(WhileCondition(tc, std::bind(SimulateUnloadToFINDA, _1, 500'000, 10'000), 200'000));
|
||||
REQUIRE(VerifyState(tc, mg::FilamentLoadState::InSelector, mi::idler.IdleSlotIndex(), fromSlot, false, false, ml::off, ml::blink0, ErrorCode::FSENSOR_DIDNT_SWITCH_OFF, ProgressCode::UnloadingFilament));
|
||||
REQUIRE(tc.unl.State() == ProgressCode::ERRWaitingForUser);
|
||||
}
|
||||
|
||||
void ToolChangeFailFSensorMiddleBtn(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) {
|
||||
using namespace std::placeholders;
|
||||
|
||||
// user pulls filament out from the fsensor and presses Retry
|
||||
mfs::fsensor.ProcessMessage(false);
|
||||
PressButtonAndDebounce(tc, mb::Middle);
|
||||
REQUIRE(VerifyState(tc, mg::FilamentLoadState::InSelector, mi::idler.IdleSlotIndex(), fromSlot, false, false, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::UnloadingFilament));
|
||||
REQUIRE(tc.unl.State() == ProgressCode::FeedingToFinda); // MMU must find out where the filament is FS is OFF, FINDA is OFF
|
||||
|
||||
// both movables should have their homing flag invalidated
|
||||
REQUIRE_FALSE(mi::idler.HomingValid());
|
||||
REQUIRE_FALSE(ms::selector.HomingValid());
|
||||
|
||||
// make FINDA trigger - Idler will rehome in this step, Selector must remain at its place
|
||||
SimulateIdlerHoming(tc);
|
||||
REQUIRE(mi::idler.HomingValid());
|
||||
REQUIRE_FALSE(ms::selector.HomingValid());
|
||||
// now trigger the FINDA
|
||||
REQUIRE(WhileCondition(tc, std::bind(SimulateFeedToFINDA, _1, 100), 5000));
|
||||
REQUIRE(VerifyState(tc, mg::FilamentLoadState::InSelector, fromSlot, fromSlot, true, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::UnloadingFilament));
|
||||
REQUIRE(tc.unl.State() == ProgressCode::RetractingFromFinda);
|
||||
|
||||
// make FINDA switch off
|
||||
REQUIRE(WhileCondition(tc, std::bind(SimulateRetractFromFINDA, _1, 100), 5000));
|
||||
REQUIRE(WhileCondition(
|
||||
tc, [&](uint32_t) { return tc.unl.State() == ProgressCode::RetractingFromFinda; }, 50000));
|
||||
|
||||
// Selector will start rehoming at this stage - that was the error this test was to find
|
||||
REQUIRE(VerifyState(tc, mg::FilamentLoadState::AtPulley, fromSlot, config::toolCount, false, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::UnloadingFilament));
|
||||
REQUIRE(tc.unl.State() == ProgressCode::DisengagingIdler);
|
||||
SimulateSelectorHoming(tc);
|
||||
|
||||
// Idler has probably engaged meanwhile, ignore its position check
|
||||
REQUIRE(WhileTopState(tc, ProgressCode::UnloadingFilament, 50000));
|
||||
REQUIRE(VerifyState2(tc, mg::FilamentLoadState::AtPulley, config::toolCount, fromSlot, false, false, toSlot, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::FeedingToFinda));
|
||||
|
||||
// after that, perform a normal load
|
||||
FeedingToFinda(tc, toSlot, 100);
|
||||
FeedingToBondtech(tc, toSlot);
|
||||
CheckFinishedCorrectly(tc, toSlot);
|
||||
}
|
||||
|
||||
TEST_CASE("tool_change::load_fail_FSensor_resolve_btnM", "[tool_change]") {
|
||||
logic::ToolChange tc;
|
||||
for (uint8_t fromSlot = 0; fromSlot < config::toolCount; ++fromSlot) {
|
||||
for (uint8_t toSlot = 0; toSlot < config::toolCount; ++toSlot) {
|
||||
if (fromSlot != toSlot) {
|
||||
ToolChangeFailFSensor(tc, fromSlot, toSlot);
|
||||
ToolChangeFailFSensorMiddleBtn(tc, fromSlot, toSlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue