Make ToolChange retry 3x before throwing out an error

pull/188/head
D.R.racer 2022-06-22 16:07:16 +02:00
parent 26151fb176
commit 6bb4a7b4b8
4 changed files with 35 additions and 5 deletions

View File

@ -67,6 +67,10 @@ static constexpr uint16_t stepTimerQuantum = 256; // 256 = 128us
/// Max retries of FeedToBondtech used in LoadFilament
static constexpr uint8_t feedToBondtechMaxRetries = 2;
/// Max attempts of ToolChange before throwing out an error - obviously, this has to be >= 1
static constexpr uint8_t toolChangeAttempts = 3;
static_assert(toolChangeAttempts >= 1);
/// Distances
static constexpr U_mm pulleyToCuttingEdge = 33.0_mm; /// 33.0_mm /// Pulley to cutting edge.
/// Case 1: FINDA working: This should be the max retraction after FINDA un-triggers.

View File

@ -17,6 +17,10 @@ namespace logic {
ToolChange toolChange;
ToolChange::ToolChange()
: CommandBase()
, attempts(config::toolChangeAttempts) {}
bool ToolChange::Reset(uint8_t param) {
if (!CheckToolIndex(param)) {
return false;
@ -28,6 +32,10 @@ bool ToolChange::Reset(uint8_t param) {
return true;
}
return Reset(param, config::toolChangeAttempts);
}
bool ToolChange::Reset(uint8_t param, uint8_t att) {
// @@TODO establish printer in charge of UI processing for the ToolChange command only.
// We'll see how that works and then probably we'll introduce some kind of protocol settings to switch UI handling.
mui::userInput.SetPrinterInCharge(true);
@ -35,6 +43,7 @@ bool ToolChange::Reset(uint8_t param) {
// we are either already at the correct slot, just the filament is not loaded - load the filament directly
// or we are standing at another slot ...
plannedSlot = param;
attempts = att;
if (mg::globals.FilamentLoaded() >= mg::FilamentLoadState::InSelector) {
dbg_logic_P(PSTR("Filament is loaded --> unload"));
@ -50,6 +59,14 @@ bool ToolChange::Reset(uint8_t param) {
return true;
}
void ToolChange::GoToRetryIfPossible(ErrorCode ec) {
if (--attempts) {
Reset(mg::globals.ActiveSlot(), attempts);
} else {
GoToErrDisengagingIdler(ec);
}
}
void logic::ToolChange::GoToFeedingToBondtech() {
ml::leds.SetPairButOffOthers(mg::globals.ActiveSlot(), ml::blink0, ml::off);
james.Reset(3);
@ -83,7 +100,7 @@ bool ToolChange::StepInner() {
case ProgressCode::FeedingToFinda:
if (feed.Step()) {
if (feed.State() == FeedToFinda::Failed) {
GoToErrDisengagingIdler(ErrorCode::FINDA_DIDNT_SWITCH_ON); // signal loading error
GoToRetryIfPossible(ErrorCode::FINDA_DIDNT_SWITCH_ON); // signal loading error
} else {
GoToFeedingToBondtech();
}
@ -93,10 +110,10 @@ bool ToolChange::StepInner() {
if (james.Step()) {
switch (james.State()) {
case FeedToBondtech::Failed:
GoToErrDisengagingIdler(ErrorCode::FSENSOR_DIDNT_SWITCH_ON); // signal loading error
GoToRetryIfPossible(ErrorCode::FSENSOR_DIDNT_SWITCH_ON); // signal loading error
break;
case FeedToBondtech::FSensorTooEarly:
GoToErrDisengagingIdler(ErrorCode::FSENSOR_TOO_EARLY); // signal loading error
GoToRetryIfPossible(ErrorCode::FSENSOR_TOO_EARLY); // signal loading error
break;
default:
ToolChangeFinishedCorrectly();

View File

@ -11,8 +11,7 @@ namespace logic {
/// @brief A high-level command state machine - handles the complex logic of tool change - which is basically a chain of an Unload and a Load operation.
class ToolChange : public CommandBase {
public:
inline ToolChange()
: CommandBase() {}
ToolChange();
/// Restart the automaton
/// @param param index of filament slot to change to - i.e. to load
@ -27,9 +26,13 @@ public:
#ifndef UNITTEST
private:
#else
inline void SetAttempts(uint8_t att) { attempts = att; }
#endif
void GoToFeedingToBondtech();
void GoToFeedingToFinda();
bool Reset(uint8_t param, uint8_t att);
void GoToRetryIfPossible(ErrorCode ec);
/// Common code for a correct completion of UnloadFilament
void ToolChangeFinishedCorrectly();
@ -38,6 +41,7 @@ private:
FeedToFinda feed;
FeedToBondtech james; // bond ;)
uint8_t plannedSlot;
uint8_t attempts; ///< how many attempts shall the state machine try before throwing out an error - obviously this has to be >= 1
};
/// The one and only instance of ToolChange state machine in the FW

View File

@ -72,6 +72,7 @@ void ToolChange(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) {
// restart the automaton
tc.Reset(toSlot);
tc.SetAttempts(1);
REQUIRE(WhileCondition(
tc,
@ -106,6 +107,7 @@ void NoToolChange(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSlot) {
// restart the automaton
tc.Reset(toSlot);
tc.SetAttempts(1);
// should not do anything
REQUIRE(tc.TopLevelState() == ProgressCode::OK);
@ -122,6 +124,7 @@ void JustLoadFilament(logic::ToolChange &tc, uint8_t slot) {
// restart the automaton
tc.Reset(slot);
tc.SetAttempts(1);
FeedingToFinda(tc, slot);
@ -182,6 +185,7 @@ void ToolChangeFailLoadToFinda(logic::ToolChange &tc, uint8_t fromSlot, uint8_t
// restart the automaton
tc.Reset(toSlot);
tc.SetAttempts(1);
REQUIRE(WhileCondition(tc, std::bind(SimulateUnloadToFINDA, _1, 100, 2'000), 200'000));
REQUIRE(WhileTopState(tc, ProgressCode::UnloadingFilament, 5000));
@ -346,6 +350,7 @@ void ToolChangeFailFSensor(logic::ToolChange &tc, uint8_t fromSlot, uint8_t toSl
// restart the automaton
tc.Reset(toSlot);
tc.SetAttempts(1);
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