Change the semantics of load filament
Load filament performs feed to FINDA and retract: - engage idler - feed normal to FINDA with config::feedToFinda distance until FINDA triggers - retract normal and as soon FINDA un-triggers move back to PTFE config::cuttingEdgeToFindaMidpoint - disengage the idler That implied introducing another substate machine - RetractFromFinda, which does the opposite of FeedToFinda while also checking for the FINDA switching off while retracting filament. Still, ToolChange and CutFilament need fixing with this changepull/126/head
parent
01b2280ea6
commit
6426295e32
|
|
@ -7,6 +7,7 @@ target_sources(
|
|||
feed_to_finda.cpp
|
||||
load_filament.cpp
|
||||
no_command.cpp
|
||||
retract_from_finda.cpp
|
||||
set_mode.cpp
|
||||
tool_change.cpp
|
||||
unload_filament.cpp
|
||||
|
|
|
|||
|
|
@ -32,29 +32,14 @@ bool FeedToFinda::Step() {
|
|||
if (mf::finda.Pressed() || (feedPhaseLimited && mui::userInput.AnyEvent())) { // @@TODO probably also a command from the printer
|
||||
mm::motion.AbortPlannedMoves(); // stop pushing filament
|
||||
// FINDA triggered - that means it works and detected the filament tip
|
||||
state = UnloadBackToPTFE;
|
||||
mm::motion.PlanMove<mm::Pulley>(-config::cuttingEdgeToFindaMidpoint, config::pulleyFeedrate);
|
||||
state = OK;
|
||||
} else if (mm::motion.QueueEmpty()) { // all moves have been finished and FINDA didn't switch on
|
||||
state = Failed;
|
||||
// @@TODO - shall we disengage the idler?
|
||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off);
|
||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::blink0);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case UnloadBackToPTFE:
|
||||
if (mm::motion.QueueEmpty()) { // all moves have been finished
|
||||
state = DisengagingIdler;
|
||||
mi::idler.Disengage();
|
||||
}
|
||||
return false;
|
||||
case DisengagingIdler:
|
||||
if (!mi::idler.Engaged()) {
|
||||
state = OK;
|
||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off);
|
||||
}
|
||||
// @@TODO FINDA must be reported as OFF again as we are pulling the filament from it - is this correct?
|
||||
return false;
|
||||
case OK:
|
||||
case Failed:
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -51,20 +51,22 @@ bool LoadFilament::StepInner() {
|
|||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off);
|
||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::blink0); // signal loading error
|
||||
} else {
|
||||
state = ProgressCode::FeedingToBondtech;
|
||||
james.Reset(config::feedToBondtechMaxRetries);
|
||||
state = ProgressCode::RetractingFromFinda;
|
||||
retract.Reset();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ProgressCode::FeedingToBondtech:
|
||||
if (james.Step()) { // No, Mr. Bond, I expect you to FEED
|
||||
switch (james.State()) {
|
||||
case FeedToBondtech::Failed:
|
||||
|
||||
case FeedToBondtech::OK:
|
||||
mm::motion.Disable(mm::Pulley);
|
||||
case ProgressCode::RetractingFromFinda:
|
||||
if (retract.Step()) {
|
||||
if (retract.State() == RetractFromFinda::Failed) {
|
||||
state = ProgressCode::ERRDisengagingIdler;
|
||||
error = ErrorCode::FINDA_DIDNT_SWITCH_OFF;
|
||||
mi::idler.Disengage();
|
||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off);
|
||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::blink0); // signal loading error
|
||||
} else {
|
||||
state = ProgressCode::DisengagingIdler;
|
||||
mi::idler.Disengage();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include <stdint.h>
|
||||
#include "command_base.h"
|
||||
#include "feed_to_finda.h"
|
||||
#include "feed_to_bondtech.h"
|
||||
#include "retract_from_finda.h"
|
||||
|
||||
namespace logic {
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ public:
|
|||
|
||||
private:
|
||||
FeedToFinda feed;
|
||||
FeedToBondtech james; // bond ;)
|
||||
RetractFromFinda retract;
|
||||
};
|
||||
|
||||
/// The one and only instance of LoadFilament state machine in the FW
|
||||
|
|
|
|||
|
|
@ -33,4 +33,5 @@ enum class ProgressCode : uint_fast8_t {
|
|||
ReturningSelector, // P21
|
||||
ParkingSelector, // P22
|
||||
EjectingFilament, // P23
|
||||
RetractingFromFinda, // P24
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
#include "retract_from_finda.h"
|
||||
#include "../modules/finda.h"
|
||||
#include "../modules/globals.h"
|
||||
#include "../modules/idler.h"
|
||||
#include "../modules/leds.h"
|
||||
#include "../modules/motion.h"
|
||||
|
||||
namespace logic {
|
||||
|
||||
void RetractFromFinda::Reset() {
|
||||
state = EngagingIdler;
|
||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::blink0);
|
||||
mi::idler.Engage(mg::globals.ActiveSlot());
|
||||
}
|
||||
|
||||
bool RetractFromFinda::Step() {
|
||||
switch (state) {
|
||||
case EngagingIdler:
|
||||
if (mi::idler.Engaged()) {
|
||||
state = UnloadBackToPTFE;
|
||||
mm::motion.PlanMove<mm::Pulley>(-config::cuttingEdgeToFindaMidpoint, config::pulleyFeedrate);
|
||||
}
|
||||
return false;
|
||||
case UnloadBackToPTFE:
|
||||
if (mm::motion.QueueEmpty()) { // all moves have been finished
|
||||
if (!mf::finda.Pressed()) { // FINDA switched off correctly
|
||||
state = OK;
|
||||
} else { // FINDA didn't switch off
|
||||
state = Failed;
|
||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off);
|
||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::red, ml::blink0);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case OK:
|
||||
case Failed:
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace logic
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
namespace logic {
|
||||
|
||||
/// @brief Retract filament from FINDA to PTFE
|
||||
///
|
||||
/// Continuously pull filament by a fixed length (originally 600 steps) + verify FINDA is switched OFF
|
||||
struct RetractFromFinda {
|
||||
/// internal states of the state machine
|
||||
enum {
|
||||
EngagingIdler,
|
||||
UnloadBackToPTFE,
|
||||
OK,
|
||||
Failed
|
||||
};
|
||||
|
||||
inline RetractFromFinda()
|
||||
: state(OK) {}
|
||||
|
||||
/// Restart the automaton
|
||||
void Reset();
|
||||
|
||||
/// @returns true if the state machine finished its job, false otherwise
|
||||
bool Step();
|
||||
|
||||
/// This method may be used to check the result of the automaton
|
||||
/// @returns OK if everything went OK and FINDA triggered
|
||||
/// @returns Failed if the FINDA didn't trigger
|
||||
inline uint8_t State() const { return state; }
|
||||
|
||||
private:
|
||||
uint8_t state;
|
||||
};
|
||||
|
||||
} // namespace logic
|
||||
|
|
@ -63,26 +63,26 @@ TEST_CASE("feed_to_finda::feed_phase_unlimited", "[feed_to_finda]") {
|
|||
1500));
|
||||
// From now on the FINDA is reported as ON
|
||||
|
||||
// unloading back to PTFE
|
||||
REQUIRE(ff.State() == FeedToFinda::UnloadBackToPTFE);
|
||||
REQUIRE(WhileCondition(
|
||||
ff,
|
||||
[&](int) { return ff.State() == FeedToFinda::UnloadBackToPTFE; },
|
||||
5000));
|
||||
// // unloading back to PTFE
|
||||
// REQUIRE(ff.State() == FeedToFinda::UnloadBackToPTFE);
|
||||
// REQUIRE(WhileCondition(
|
||||
// ff,
|
||||
// [&](int) { return ff.State() == FeedToFinda::UnloadBackToPTFE; },
|
||||
// 5000));
|
||||
|
||||
// disengaging idler
|
||||
REQUIRE(ff.State() == FeedToFinda::DisengagingIdler);
|
||||
REQUIRE(WhileCondition(
|
||||
ff,
|
||||
[&](int) { return mi::idler.Engaged(); },
|
||||
5000));
|
||||
// // disengaging idler
|
||||
// REQUIRE(ff.State() == FeedToFinda::DisengagingIdler);
|
||||
// REQUIRE(WhileCondition(
|
||||
// ff,
|
||||
// [&](int) { return mi::idler.Engaged(); },
|
||||
// 5000));
|
||||
|
||||
CHECK(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(5).v); // @@TODO constants
|
||||
// CHECK(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(5).v); // @@TODO constants
|
||||
CHECK(mm::axes[mm::Selector].pos == ms::Selector::SlotPosition(0).v);
|
||||
|
||||
// state machine finished ok, the green LED should be on
|
||||
// state machine finished ok, the green LED should be blinking
|
||||
REQUIRE(ff.State() == FeedToFinda::OK);
|
||||
REQUIRE(ml::leds.Mode(mg::globals.ActiveSlot(), ml::green) == ml::off);
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ add_executable(
|
|||
${CMAKE_SOURCE_DIR}/src/logic/feed_to_bondtech.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/logic/feed_to_finda.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/logic/load_filament.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/logic/retract_from_finda.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/modules/buttons.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/modules/debouncer.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/modules/finda.cpp
|
||||
|
|
|
|||
|
|
@ -57,23 +57,23 @@ void LoadFilamentSuccessful(uint8_t slot, logic::LoadFilament &lf) {
|
|||
}
|
||||
return lf.TopLevelState() == ProgressCode::FeedingToFinda; },
|
||||
5000));
|
||||
REQUIRE(VerifyState(lf, false, slot, slot, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::FeedingToBondtech));
|
||||
REQUIRE(VerifyState(lf, false, slot, slot, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::RetractingFromFinda));
|
||||
|
||||
// Stage 3 - feeding to bondtech
|
||||
// we'll make a fsensor switch during the process
|
||||
// Stage 3 - retracting from finda
|
||||
// we'll assume the finda is working correctly here
|
||||
REQUIRE(WhileCondition(
|
||||
lf,
|
||||
[&](int step) -> bool {
|
||||
if(step == 100){ // on 100th step make fsensor trigger
|
||||
mfs::fsensor.ProcessMessage(true);
|
||||
if(step == 50){ // on 50th step make FINDA trigger
|
||||
hal::gpio::WritePin(FINDA_PIN, hal::gpio::Level::low);
|
||||
}
|
||||
return lf.TopLevelState() == ProgressCode::FeedingToBondtech; },
|
||||
return lf.TopLevelState() == ProgressCode::RetractingFromFinda; },
|
||||
5000));
|
||||
REQUIRE(VerifyState(lf, false, slot, slot, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::DisengagingIdler));
|
||||
REQUIRE(VerifyState(lf, false, slot, slot, false, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::DisengagingIdler));
|
||||
|
||||
// Stage 4 - disengaging idler
|
||||
REQUIRE(WhileTopState(lf, ProgressCode::DisengagingIdler, idlerEngageDisengageMaxSteps));
|
||||
REQUIRE(VerifyState(lf, true, mi::Idler::IdleSlotIndex(), slot, true, ml::off, ml::off, ErrorCode::OK, ProgressCode::OK));
|
||||
REQUIRE(VerifyState(lf, true, mi::Idler::IdleSlotIndex(), slot, false, ml::on, ml::off, ErrorCode::OK, ProgressCode::OK));
|
||||
}
|
||||
|
||||
TEST_CASE("load_filament::regular_load_to_slot_0-4", "[load_filament]") {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ add_executable(
|
|||
${CMAKE_SOURCE_DIR}/src/logic/feed_to_bondtech.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/logic/feed_to_finda.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/logic/load_filament.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/logic/retract_from_finda.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/logic/tool_change.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/logic/unload_filament.cpp
|
||||
${CMAKE_SOURCE_DIR}/src/logic/unload_to_finda.cpp
|
||||
|
|
|
|||
Loading…
Reference in New Issue