YARP CiA-402 EtherCAT Device 0.6.0
YARP device plugin for EtherCAT CiA-402 drives
Loading...
Searching...
No Matches
CiA402StateMachine.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
7{
8 Impl() = default;
9 ~Impl() = default;
10
11 /// Control‑word constants (CiA‑402 table 46)
12 static constexpr uint16_t CW_DISABLE_VOLTAGE = 0x0000;
13 static constexpr uint16_t CW_SHUTDOWN = 0x0006;
14 static constexpr uint16_t CW_SWITCH_ON = 0x0007;
15 static constexpr uint16_t CW_ENABLE_OP = 0x000F;
16 static constexpr uint16_t CW_FAULT_RST = 0x0080;
17 static constexpr uint16_t CW_QUICKSTOP = 0x0002;
18
19 int8_t activeOpEcho{0}; //!< latest OpModeDisplay from the drive
20};
21
23 : m_impl(std::make_unique<Impl>())
24{
25}
26
28
30{
31 // Reset the state machine to its initial state.
32 m_impl->activeOpEcho = 0;
33}
34
36{
37 return m_impl->activeOpEcho;
38}
39
41 int8_t opModeDisplay,
42 int8_t opReq,
43 bool hwInhibit)
44{
45 // Decode the current power state from statusword bits
46 const State state = sw_to_state(statusword);
47
48 // Track the active operation mode only when drive is fully enabled
49 if (state == State::OperationEnabled)
50 {
51 m_impl->activeOpEcho = opModeDisplay; // Store what the drive is actually doing
52 } else
53 {
54 m_impl->activeOpEcho = 0; // Clear when not operational
55 }
56
57 // =============================================================================
58 // SAFETY OVERRIDE: Hardware inhibit forces immediate voltage disable
59 // =============================================================================
60 if (hwInhibit)
61 {
62 // Safety systems (STO/SBC) are active - immediately disable power stage
63 return {Impl::CW_DISABLE_VOLTAGE, 0, true}; // Force opmode=0 (no mode)
64 }
65
66 // =============================================================================
67 // FAULT HANDLING: Disable voltage but don't write opmode (preserves fault info)
68 // =============================================================================
69 if (state == State::Fault)
70 {
71 // Drive is in fault state - disable voltage but let user call faultReset()
72 return {Impl::CW_DISABLE_VOLTAGE, 0, false}; // Don't overwrite opmode
73 }
74
75 // =============================================================================
76 // IDLE REQUEST: User wants to stop all motion
77 // =============================================================================
78 if (opReq == 0)
79 {
80 // Disable power stage and set "no mode" explicitly
81 return {Impl::CW_DISABLE_VOLTAGE, 0, true}; // Write opmode=0 once
82 }
83
84 // =============================================================================
85 // DYNAMIC OPERATION MODE SWITCHING (drive already enabled)
86 // =============================================================================
87 if (state == State::OperationEnabled)
88 {
89 // Drive is fully operational - can switch modes on-the-fly
90 if (opReq != m_impl->activeOpEcho)
91 {
92 // Mode change requested: write new opmode while maintaining power
93 return {Impl::CW_ENABLE_OP, opReq, true}; // Update opmode
94 } else
95 {
96 // Already in requested mode: maintain current state
97 return {Impl::CW_ENABLE_OP, opReq, false}; // Keep current opmode
98 }
99 }
100
101 // =============================================================================
102 // POWER-UP SEQUENCE: Classic CiA-402 state transitions
103 // =============================================================================
104 // Drive needs to go through the standard power-on sequence:
105 // NotReadyToSwitchOn → SwitchOnDisabled → ReadyToSwitchOn →
106 // SwitchedOn → OperationEnabled
107
108 switch (state)
109 {
111 // First step: enable the control electronics (but not power stage)
112 return {Impl::CW_SHUTDOWN, opReq, true}; // Go to ReadyToSwitchOn
113
115 // Second step: prepare for switching on the power stage
116 return {Impl::CW_SWITCH_ON, opReq, false}; // Go to SwitchedOn
117
119 // Final step: enable the power stage and operation mode
120 return {Impl::CW_ENABLE_OP, opReq, false}; // Go to OperationEnabled
121
123 // Drive performed emergency stop - clear the condition
124 return {Impl::CW_QUICKSTOP, opReq, false}; // Clear quickstop
125
126 default:
127 // NotReadyToSwitchOn, Unknown, or other: ensure safe state
128 return {Impl::CW_DISABLE_VOLTAGE, 0, true}; // Force voltage off
129 }
130}
131
132/** Immediate Fault reset (equivalent to requesting VOCAB_CM_FORCE_IDLE). */
Command update(uint16_t statusword, int8_t opModeDisplay, int8_t opReq, bool hwInhibit)
Computes the next control word and operation mode to send to the drive.
~StateMachine()
Destructor.
void reset()
Resets the internal state machine.
Command faultReset() noexcept
Generates a fault reset command.
int8_t getActiveOpMode() const noexcept
static constexpr State sw_to_state(uint16_t sw)
STL namespace.
static constexpr uint16_t CW_ENABLE_OP
static constexpr uint16_t CW_QUICKSTOP
static constexpr uint16_t CW_SHUTDOWN
static constexpr uint16_t CW_SWITCH_ON
static constexpr uint16_t CW_DISABLE_VOLTAGE
Control‑word constants (CiA‑402 table 46)
int8_t activeOpEcho
latest OpModeDisplay from the drive
static constexpr uint16_t CW_FAULT_RST