Skip to content

tests: improvements around idler homing #344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions tests/unit/logic/load_filament/test_load_filament.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ void LoadFilamentSuccessful(uint8_t slot, logic::LoadFilament &lf) {
void LoadFilamentSuccessfulWithRehomeSelector(uint8_t slot, logic::LoadFilament &lf) {
// Stage 2 - feeding to finda
// make FINDA switch on
// engaging idler

REQUIRE(WhileCondition(
lf,
[&](uint32_t) { return !mi::idler.Engaged(); },
5000));

REQUIRE(WhileCondition(lf, std::bind(SimulateFeedToFINDA, _1, 100), 5000));
REQUIRE(VerifyState(lf, mg::FilamentLoadState::InSelector, slot, slot, true, true, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::RetractingFromFinda));

Expand Down Expand Up @@ -176,8 +183,6 @@ void FailedLoadToFindaResolveTryAgain(uint8_t slot, logic::LoadFilament &lf) {
REQUIRE(VerifyState(lf, mg::FilamentLoadState::InSelector, config::toolCount, slot, false, false, ml::blink0, ml::off, ErrorCode::RUNNING, ProgressCode::FeedingToFinda));
ClearButtons(lf);

SimulateIdlerHoming(lf);

LoadFilamentSuccessfulWithRehomeSelector(slot, lf);
}

Expand Down
62 changes: 38 additions & 24 deletions tests/unit/logic/stubs/homing.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "catch2/catch_test_macros.hpp"
#include "homing.h"
#include "main_loop_stub.h"

Expand Down Expand Up @@ -58,6 +59,18 @@ void SimulateIdlerAndSelectorHoming(logic::CommandBase &cb) {

void SimulateIdlerHoming(logic::CommandBase &cb) {
uint32_t idlerStepsFwd = mm::unitToSteps<mm::I_pos_t>(config::idlerLimits.lenght - 5.0_deg);

// Sometimes the initial idler state is Ready. Let's wait for the firmware to start
// homing.
REQUIRE(WhileCondition(
cb,
[&](uint32_t) { return mi::idler.State() == mm::MovableBase::Ready; },
5000));

// At this point the idler should always be homing forward.
REQUIRE((int)mi::idler.State() == (int)mm::MovableBase::HomeForward);

// Simulate the idler steps in one direction (forward)
for (uint32_t i = 0; i < idlerStepsFwd; ++i) {
main_loop();
cb.Step();
Expand All @@ -68,6 +81,8 @@ void SimulateIdlerHoming(logic::CommandBase &cb) {
cb.Step();
mm::motion.StallGuardReset(mm::Idler);

REQUIRE((int)mi::idler.State() == (int)mm::MovableBase::HomeBack);

// now do a correct amount of steps of each axis towards the other end
uint32_t idlerSteps = mm::unitToSteps<mm::I_pos_t>(config::idlerLimits.lenght);
uint32_t maxSteps = idlerSteps + 1;
Expand All @@ -82,6 +97,9 @@ void SimulateIdlerHoming(logic::CommandBase &cb) {
mm::motion.StallGuardReset(mm::Idler);
}
}

// If the homing has failed, the axis length was too short.
REQUIRE(!((mi::idler.State() & mm::MovableBase::HomingFailed) == mm::MovableBase::HomingFailed));
}

void SimulateIdlerWaitForHomingValid(logic::CommandBase &cb) {
Expand Down Expand Up @@ -185,33 +203,40 @@ bool SimulateFailedHomeSelectorPostfix(logic::CommandBase &cb) {
}

bool SimulateFailedHomeFirstTime(logic::CommandBase &cb) {
if (mi::idler.HomingValid())
return false;
if (ms::selector.HomingValid())
return false;
REQUIRE(!mi::idler.HomingValid());
REQUIRE(!ms::selector.HomingValid());

// Idler homing is successful
SimulateIdlerHoming(cb);
SimulateIdlerWaitForHomingValid(cb);

// Selector homes once the idler homing is valid.
REQUIRE(mi::idler.HomingValid());
REQUIRE(!ms::selector.HomingValid());

// The selector will only rehome once the idler homing is valid. At that moment
// the state will change to HomeForward.
REQUIRE(WhileCondition(
cb,
[&](uint32_t) { return ms::selector.State() != mm::MovableBase::HomeForward; },
5000));

constexpr uint32_t selectorSteps = mm::unitToSteps<mm::S_pos_t>(config::selectorLimits.lenght) + 1;
{
// do 5 steps until we trigger the simulated StallGuard
constexpr uint32_t idlerStepsFwd = mm::unitToSteps<mm::I_pos_t>(config::idlerLimits.lenght - 5.0_deg);
static_assert(idlerStepsFwd < selectorSteps); // beware, we expect that the Idler homes faster than Selector (less steps)
for (uint32_t i = 0; i < idlerStepsFwd; ++i) {
for (uint32_t i = 0; i < selectorSteps; ++i) {
main_loop();
cb.Step();
}

mm::TriggerStallGuard(mm::Selector);
mm::TriggerStallGuard(mm::Idler);
main_loop();
cb.Step();
mm::motion.StallGuardReset(mm::Selector);
mm::motion.StallGuardReset(mm::Idler);
}
// now do a correct amount of steps of each axis towards the other end
constexpr uint32_t idlerSteps = mm::unitToSteps<mm::I_pos_t>(config::idlerLimits.lenght);
// now do LESS steps than expected to simulate something is blocking the selector

constexpr uint32_t selectorTriggerShort = std::min(idlerSteps, selectorSteps) / 2;
// now do LESS steps than expected to simulate something is blocking the selector
constexpr uint32_t selectorTriggerShort = selectorSteps / 2;
constexpr uint32_t maxSteps = selectorTriggerShort + 1;
{
for (uint32_t i = 0; i < maxSteps; ++i) {
Expand All @@ -225,17 +250,6 @@ bool SimulateFailedHomeFirstTime(logic::CommandBase &cb) {
}
}

// make sure the Idler finishes its homing procedure (makes further checks much easier)
for (uint32_t i = maxSteps; i < idlerSteps + 1; ++i) {
main_loop();
cb.Step();
if (i == idlerSteps) {
mm::TriggerStallGuard(mm::Idler);
} else {
mm::motion.StallGuardReset(mm::Idler);
}
}

while (!(ms::selector.State() & mm::MovableBase::OnHold)) {
main_loop();
cb.Step();
Expand Down
Loading