12 : hardware_(hardware),
16 last_guardian_tick_(0) {}
29 last_guardian_tick_.store(tick, std::memory_order_relaxed);
34 std::uint32_t max_allowed_delay)
noexcept {
35 const std::uint32_t last =
36 last_guardian_tick_.load(std::memory_order_relaxed);
38 if ((now - last) > max_allowed_delay) {
45 operator_ack_.store(
true, std::memory_order_relaxed);
54 return freeze_reason_.load(std::memory_order_relaxed);
58 return state_.load(std::memory_order_relaxed);
61void RobotInterlock::freeze(
FreezeReason reason)
noexcept {
63 if (!state_.compare_exchange_strong(
66 std::memory_order_acq_rel)) {
70 freeze_reason_.store(reason, std::memory_order_relaxed);
71 operator_ack_.store(
false, std::memory_order_relaxed);
73 if (!hardware_.freezeMotion()) {
74 std::cerr <<
"[INTERLOCK] Hardware freeze failed; entering FAULT state"
80void RobotInterlock::attemptResume() noexcept {
85 if (!operator_ack_.load(std::memory_order_relaxed)) {
90 std::cerr <<
"[INTERLOCK] Hardware enable failed; entering FAULT state"
100void RobotInterlock::enterFault(
FreezeReason reason)
noexcept {
101 freeze_reason_.store(reason, std::memory_order_relaxed);
102 operator_ack_.store(
false, std::memory_order_relaxed);
108 GPIO_WritePin(ARM_ENABLE_PIN,
false);
109 GPIO_WritePin(CUTTER_ENABLE_PIN,
false);
115 GPIO_WritePin(ARM_ENABLE_PIN,
true);
116 GPIO_WritePin(CUTTER_ENABLE_PIN,
true);
120void PhysicalRobotHardware::GPIO_WritePin(
int pin,
bool value)
noexcept {
Safety interlock gate between guardian decisions and robot motion.
FreezeReason
Latched freeze/fault reason.
@ UNKNOWN_FAULT
Unspecified fault reason.
@ NONE
No freeze reason currently latched.
@ WATCHDOG_TIMEOUT
Guardian heartbeat timeout.
InterlockState
Interlock state machine output states.
@ FROZEN
Motion blocked due to safety freeze.
@ FAULT
Motion blocked due to hardware/path fault.
ControlEvent
Control commands issued to the interlock.
@ FREEZE_NOW
Immediately freeze/deny motion.
bool freezeMotion() noexcept override
Apply immediate freeze to physical hardware lines.
bool enableMotion() noexcept override
Re-enable motion on physical hardware lines.
Abstract hardware contract used by RobotInterlock.
virtual bool enableMotion() noexcept=0
Re-enable motion output after safe/ack conditions.
bool motionAllowed() const noexcept
Query whether motion is currently allowed.
FreezeReason freezeReason() const noexcept
Get currently latched freeze reason.
void operatorAcknowledge() noexcept
Register operator acknowledge for motion resume attempts.
void guardianHeartbeat(std::uint32_t tick) noexcept
Update guardian heartbeat tick observed by interlock.
void watchdogCheck(std::uint32_t now, std::uint32_t max_allowed_delay) noexcept
Evaluate watchdog timeout against last guardian heartbeat.
void onControlEvent(ControlEvent event, FreezeReason reason=FreezeReason::UNKNOWN_FAULT) noexcept
Submit a control event to the interlock state machine.
InterlockState state() const noexcept
Get current interlock state.
RobotInterlock(RobotHardware &hardware) noexcept
Construct interlock bound to a hardware implementation.