Introduce UnloadingFromFSensor
To allow tighter cooperation with the printer - after the printer thinks it unloaded the filament from the drive gear, we'll still rotate the drive gear as long as the MMU reports progress state UnloadingFromFSensor. After those 40mm of slow unload distance, the MMU checks the fsensor (like is has been doing before). If FSensor is off at this moment, everything is fine a the unload will continue at full speed.pull/271/head
parent
113f71330e
commit
33edba66ee
|
|
@ -50,5 +50,7 @@ enum class ProgressCode : uint_fast8_t {
|
|||
HWTestDisplay, // P35
|
||||
ErrHwTestFailed, // P36
|
||||
|
||||
UnloadingFilamentSlowly, // P37
|
||||
|
||||
Empty = 0xff // dummy empty state
|
||||
};
|
||||
|
|
|
|||
|
|
@ -133,4 +133,20 @@ bool UnloadFilament::StepInner() {
|
|||
return false;
|
||||
}
|
||||
|
||||
ProgressCode UnloadFilament::State() const {
|
||||
switch (state) {
|
||||
case ProgressCode::UnloadingToFinda:
|
||||
switch (unl.State()) {
|
||||
case UnloadToFinda::EngagingIdler:
|
||||
return ProgressCode::EngagingIdler;
|
||||
case UnloadToFinda::UnloadingFromFSensor:
|
||||
return ProgressCode::UnloadingFilamentSlowly;
|
||||
// the rest should be reported as UnloadingFilament
|
||||
}
|
||||
[[fallthrough]];
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace logic
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ public:
|
|||
/// @returns true if the state machine finished its job, false otherwise
|
||||
bool StepInner() override;
|
||||
|
||||
ProgressCode State() const override;
|
||||
|
||||
private:
|
||||
constexpr static const uint8_t maxRetries = 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,37 +20,46 @@ void UnloadToFinda::Reset(uint8_t maxTries) {
|
|||
// FINDA is sensing the filament, plan moves to unload it
|
||||
state = EngagingIdler;
|
||||
mi::idler.Engage(mg::globals.ActiveSlot());
|
||||
if (mg::globals.FilamentLoaded() >= mg::FilamentLoadState::InSelector) {
|
||||
state = UnloadingFromFSensor;
|
||||
mpu::pulley.InitAxis();
|
||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::blink0);
|
||||
} else {
|
||||
state = FailedFINDA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool UnloadToFinda::Step() {
|
||||
switch (state) {
|
||||
case EngagingIdler:
|
||||
if (mg::globals.FilamentLoaded() >= mg::FilamentLoadState::InSelector) {
|
||||
state = UnloadingToFinda;
|
||||
mpu::pulley.InitAxis();
|
||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::blink0);
|
||||
} else {
|
||||
state = FailedFINDA;
|
||||
}
|
||||
return false;
|
||||
case UnloadingToFinda:
|
||||
if (mi::idler.Engaged()) {
|
||||
state = WaitingForFINDA;
|
||||
state = UnloadingFromFSensor;
|
||||
mg::globals.SetFilamentLoaded(mg::globals.ActiveSlot(), mg::FilamentLoadState::InSelector);
|
||||
unloadStart_mm = mpu::pulley.CurrentPosition_mm();
|
||||
// plan both moves to keep the unload smooth
|
||||
mpu::pulley.PlanMove(-mg::globals.FSensorUnloadCheck_mm(), mg::globals.PulleySlowFeedrate_mm_s());
|
||||
mpu::pulley.PlanMove(-config::defaultBowdenLength - config::feedToFinda - config::filamentMinLoadedToMMU, mg::globals.PulleyUnloadFeedrate_mm_s());
|
||||
}
|
||||
return false;
|
||||
case WaitingForFINDA: {
|
||||
int32_t currentPulley_mm = mpu::pulley.CurrentPosition_mm();
|
||||
if ((abs(unloadStart_mm - currentPulley_mm) > mm::truncatedUnit(mg::globals.FSensorUnloadCheck_mm())) && mfs::fsensor.Pressed()) {
|
||||
case UnloadingFromFSensor:
|
||||
if ((abs(unloadStart_mm - mpu::pulley.CurrentPosition_mm()) > mm::truncatedUnit(mg::globals.FSensorUnloadCheck_mm()))) {
|
||||
// passed the slow unload distance, check fsensor
|
||||
if (mfs::fsensor.Pressed()) {
|
||||
// fsensor didn't trigger within the first fsensorUnloadCheckDistance mm -> stop pulling, something failed, report an error
|
||||
// This scenario should not be tried again - repeating it may cause more damage to filament + potentially more collateral damage
|
||||
state = FailedFSensor;
|
||||
mm::motion.AbortPlannedMoves(); // stop rotating the pulley
|
||||
ml::leds.SetMode(mg::globals.ActiveSlot(), ml::green, ml::off);
|
||||
} else if (!mf::finda.Pressed()) {
|
||||
} else {
|
||||
// fsensor turned correctly off, seamlessly transfer to fast unloading -> waiting for FINDA
|
||||
// the move has already been planned when idler engaged
|
||||
state = WaitingForFINDA;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case WaitingForFINDA: {
|
||||
if (!mf::finda.Pressed()) {
|
||||
// detected end of filament
|
||||
state = OK;
|
||||
mm::motion.AbortPlannedMoves(); // stop rotating the pulley
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ struct UnloadToFinda {
|
|||
/// internal states of the state machine
|
||||
enum {
|
||||
EngagingIdler,
|
||||
UnloadingToFinda,
|
||||
UnloadingFromFSensor,
|
||||
WaitingForFINDA,
|
||||
OK,
|
||||
FailedFINDA,
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ TEST_CASE("unload_to_finda::regular_unload", "[unload_to_finda]") {
|
|||
CHECK(mm::axes[mm::Pulley].enabled == true);
|
||||
|
||||
// now pulling the filament until finda triggers
|
||||
REQUIRE(ff.State() == logic::UnloadToFinda::WaitingForFINDA);
|
||||
REQUIRE(ff.State() == logic::UnloadToFinda::UnloadingFromFSensor);
|
||||
REQUIRE(WhileCondition(ff, std::bind(SimulateUnloadToFINDA, _1, 10, 1000), 1100));
|
||||
|
||||
REQUIRE(ff.State() == logic::UnloadToFinda::OK);
|
||||
|
|
@ -209,7 +209,7 @@ TEST_CASE("unload_to_finda::unload_repeated", "[unload_to_finda]") {
|
|||
main_loop();
|
||||
ff.Step();
|
||||
|
||||
REQUIRE(ff.State() == logic::UnloadToFinda::UnloadingToFinda);
|
||||
REQUIRE(ff.State() == logic::UnloadToFinda::UnloadingFromFSensor);
|
||||
REQUIRE(mg::globals.FilamentLoaded() == mg::FilamentLoadState::InSelector);
|
||||
|
||||
// make arbitrary amount of steps
|
||||
|
|
|
|||
Loading…
Reference in New Issue