Add Idler module

pull/21/head
D.R.racer 2021-06-09 09:30:37 +02:00 committed by DRracer
parent 05ff998c01
commit b4e8c3fa5d
2 changed files with 121 additions and 0 deletions

59
src/modules/idler.cpp Normal file
View File

@ -0,0 +1,59 @@
#include "idler.h"
#include "buttons.h"
#include "leds.h"
#include "motion.h"
#include "permanent_storage.h"
namespace modules {
namespace idler {
namespace mm = modules::motion;
bool Idler::Disengage() {
if (state == Moving)
return false;
plannedEngage = false;
// plan move to idle position
// mm::motion.PlanMove(0, idle_position, 0, 1000, 0, 0); // @@TODO
state = Moving;
return true;
}
bool Idler::Engage(uint8_t slot) {
if (state == Moving)
return false;
plannedSlot = slot;
plannedEngage = true;
// mm::motion.PlanMove(0, slotPositions[slot], 0, 1000, 0, 0); // @@TODO
state = Moving;
return true;
}
bool Idler::Home() {
if (state == Moving)
return false;
plannedEngage = false;
mm::motion.Home(mm::Idler, false);
return true;
}
bool Idler::Step() {
switch (state) {
case Moving:
if (mm::motion.QueueEmpty()) {
// move finished
state = Ready;
}
return false;
case Ready:
currentlyEngaged = plannedEngage;
currentSlot = plannedSlot;
return true;
case Failed:
default:
return true;
}
}
} // namespace idler
} // namespace modules

62
src/modules/idler.h Normal file
View File

@ -0,0 +1,62 @@
#pragma once
#include <stdint.h>
/// Idler model
/// Handles asynchronnous Engaging / Disengaging operations
/// Keeps track of idler's current state
namespace modules {
namespace idler {
class Idler {
public:
enum {
Ready = 0,
Moving,
Failed
};
// public operations on the idler
/// @retuns false in case an operation is already underway
bool Engage(uint8_t slot);
/// @retuns false in case an operation is already underway
bool Disengage();
/// @retuns false in case an operation is already underway
bool Home();
/// @returns true if the idler is ready to accept new commands (i.e. it has finished the last operation)
bool Step();
/// @returns the current state of idler - engaged / disengaged
/// this state is updated only when a planned move is successfully finished, so it is safe for higher-level
/// state machines to use this call as a waiting condition for the desired state of the idler
inline bool Engaged() const { return currentlyEngaged; }
inline uint8_t Slot() const { return currentSlot; }
private:
constexpr static const uint16_t slotPositions[5] = { 1, 2, 3, 4, 5 }; // @@TODO
/// internal state of the automaton
uint8_t state;
/// direction of travel - engage/disengage
bool plannedEngage;
uint8_t plannedSlot;
/// current state
uint8_t currentSlot;
bool currentlyEngaged;
inline Idler()
: plannedEngage(false)
, plannedSlot(0)
, state(Ready)
, currentSlot(0)
, currentlyEngaged(false) {}
};
extern Idler idler;
} // namespace idler
} // namespace modules