99 lines
2.4 KiB
C++
Executable File
99 lines
2.4 KiB
C++
Executable File
#include "StateMachine.hpp"
|
|
#include "UartHandler.hpp"
|
|
|
|
constexpr uint8_t ERROR_INDICATOR_LED_PIN = 3;
|
|
|
|
StateMachine::StateMachine() noexcept
|
|
{
|
|
pinMode(ERROR_INDICATOR_LED_PIN, OUTPUT);
|
|
digitalWrite(ERROR_INDICATOR_LED_PIN, LOW);
|
|
}
|
|
|
|
StateMachine& StateMachine::getInstance() noexcept
|
|
{
|
|
static StateMachine instance;
|
|
return instance;
|
|
}
|
|
|
|
bool StateMachine::setState(const STATE newState) noexcept
|
|
{
|
|
if (canSwitchToState(newState)) {
|
|
state = newState;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool StateMachine::canSwitchToState(const STATE newState) const noexcept
|
|
{
|
|
// Error state is final
|
|
if (state == STATE::ERROR) {
|
|
return false;
|
|
}
|
|
|
|
// Error state only settable via raiseError()
|
|
if (newState == STATE::ERROR) {
|
|
return false;
|
|
}
|
|
|
|
// Allow same-to-same transition
|
|
if (state == newState) {
|
|
return true;
|
|
}
|
|
|
|
switch (state) {
|
|
case StateMachine::STATE::INITIALIZING:
|
|
switch (newState) {
|
|
// Can go to idle
|
|
case STATE::IDLING:
|
|
return true;
|
|
// Can't go straight to moving
|
|
case STATE::MOVING:
|
|
return false;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
break;
|
|
case StateMachine::STATE::IDLING:
|
|
switch (newState) {
|
|
// Can't initialize again
|
|
case STATE::INITIALIZING:
|
|
return false;
|
|
// Can enter move state
|
|
case STATE::MOVING:
|
|
return true;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
break;
|
|
case StateMachine::STATE::MOVING:
|
|
switch (newState) {
|
|
// Can't initialize again
|
|
case STATE::INITIALIZING:
|
|
return false;
|
|
// Can go into idling
|
|
case STATE::IDLING:
|
|
return true;
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool StateMachine::raiseError(const String &reason) noexcept
|
|
{
|
|
state = STATE::ERROR;
|
|
lastError = reason;
|
|
digitalWrite(ERROR_INDICATOR_LED_PIN, HIGH);
|
|
UartHandler& uart = UartHandler::getInstance();
|
|
if (uart.isOpen()) {
|
|
uart.send(String("Error!: ") + reason);
|
|
}
|
|
}
|