YARP CiA-402 EtherCAT Device 0.6.0
YARP device plugin for EtherCAT CiA-402 drives
Loading...
Searching...
No Matches
CiA402StateMachine.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT)
2// SPDX-License-Identifier: BSD-3-Clause
3//
4//
5// CiA402StateMachine │
6//
7// A *header‑only* helper that drives the CiA‑402 power‑state machine and the
8// “dynamic Op‑Mode switching” logic for a single EtherCAT drive.
9//
10// Usage (pseudo‑code inside your cyclic task)
11//
12// CiA402StateMachine sm;
13// ...
14// sm.setRequestedOpMode(ciaOpValue); // whenever the user changes mode
15// auto cmd = sm.update(tx.Statusword, tx.OpModeDisplay);
16// rx.Controlword = cmd.controlword;
17// if (cmd.writeOpMode) rx.OpMode = cmd.opMode;
18//
19// The class keeps the power stage enabled whenever the drive is already in
20// *Operation‑enabled* and the only thing that changes is the mode (object 0x6060).
21// Otherwise it gracefully walks through Shutdown → Switched‑on → Operation
22// following the CiA‑402 specification, waiting for each state to be *reached*
23// before sending the next control‑word.
24//
25
26#ifndef YARP_DEV_CIA402_STATE_MACHINE_H
27#define YARP_DEV_CIA402_STATE_MACHINE_H
28
29#include <memory>
30#include <string_view>
31
32namespace CiA402
33{
34
35enum class State : uint8_t
36{
37 NotReadyToSwitchOn = 0, // 0x0000
38 SwitchOnDisabled = 1, // 0x0040
39 ReadyToSwitchOn = 2, // 0x0021
40 SwitchedOn = 3, // 0x0023
41 OperationEnabled = 4, // 0x0027
42 QuickStopActive = 5, // 0x0007
43 FaultReaction = 6, // 0x000F
44 Fault = 7, // 0x0008
46};
47
48/** Convert a raw status-word to the canonical CiA-402 state.
49 *
50 * Only the relevant bits (0,1,2,3,4,5,6) are masked, exactly as the spec does.
51 * Patterns are taken from IEC 61800-7-204, table 13.
52 */
53static inline constexpr State sw_to_state(uint16_t sw)
54{
55 const uint16_t x = sw & 0x006F; // keep bits 0,1,2,4,5,6
56 const uint16_t y = sw & 0x004F; // same, but without bit 5 (QS)
57
58 if (x == 0x0000)
59 return State::NotReadyToSwitchOn; // 0000 0000 0000 0000
60 if (y == 0x0040)
61 return State::SwitchOnDisabled; // 0100 0000
62 if (x == 0x0021)
63 return State::ReadyToSwitchOn; // 0010 0001
64 if (x == 0x0023)
65 return State::SwitchedOn; // 0010 0011
66 if (x == 0x0027)
67 return State::OperationEnabled; // 0010 0111
68 if (x == 0x0007)
69 return State::QuickStopActive; // 0000 0111
70 if (y == 0x000F)
71 return State::FaultReaction; // 0000 1111 (ignore QS)
72 if (y == 0x0008)
73 return State::Fault; // 0000 1000
74 return State::Unknown;
75}
76
77// Only for debugging
78static inline constexpr std::string_view state_to_string(State s)
79{
80 switch (s)
81 {
83 return "SwitchOnDisabled";
85 return "ReadyToSwitchOn";
87 return "SwitchedOn";
89 return "OperationEnabled";
91 return "QuickStopActive";
93 return "FaultReaction";
94 case State::Fault:
95 return "Fault";
96 default:
97 return "Unknown";
98 }
99}
100
101// ────────────────────────────────────────────────────────────────────────────
102// The state‑machine class
103// ────────────────────────────────────────────────────────────────────────────
105{
106public:
107 /**
108 * @brief Command structure.
109 *
110 * This structure contains the control word, operation mode, and a flag indicating
111 * if the operation mode should be written.
112 */
113 struct Command
114 {
115 uint16_t controlword; ///< Control word to send to the drive.
116 int8_t opMode; ///< Operation mode to send to the drive.
117 bool writeOpMode; ///< Flag indicating if the operation mode should be written.
118 };
119
120 /**
121 * @brief Constructor.
122 *
123 * Initializes the CiA-402 state machine for a single EtherCAT drive.
124 */
125 StateMachine();
126 /**
127 * @brief Destructor.
128 *
129 * Cleans up the resources used by the state machine.
130 */
132
133 /**
134 * @brief Resets the internal state machine.
135 *
136 * Call this after power-on or after a drive fault to reinitialize the state machine.
137 */
138 void reset();
139
140 /**
141 * @brief Computes the next control word and operation mode to send to the drive.
142 *
143 * This function should be called cyclically. It determines the correct control word and
144 * (optionally) the operation mode to send, based on the current statusword and opModeDisplay.
145 *
146 * @param statusword Value read from TxPDO.Statusword.
147 * @param opModeDisplay Value read from TxPDO.OpModeDisplay (object 0x6061).
148 * @param opReq Requested operation mode (object 0x6060).
149 * @param hwInhibit Hardware inhibit state (true if inhibited, false otherwise).
150 * @return Command structure containing the control word, operation mode, and a flag indicating
151 * if the opMode should be written.
152 */
153 Command update(uint16_t statusword, int8_t opModeDisplay, int8_t opReq, bool hwInhibit);
154
155 int8_t getActiveOpMode() const noexcept;
156
157 /**
158 * @brief Generates a fault reset command.
159 *
160 * This function generates a command to reset the fault state of the drive.
161 *
162 * @return Command structure containing the control word and operation mode for fault reset.
163 */
164 Command faultReset() noexcept;
165
166 /**
167 * Check if the operation is enabled.
168 * @param sw Status word.
169 * @return true if the operation is enabled, false otherwise.
170 */
171 static inline bool isOpEnabled(uint16_t sw)
172 {
173 return (sw & 0x0004) != 0;
174 }
175
176 /**
177 * Check if the drive is in a fault state.
178 * @param sw Status word.
179 * @return true if the drive is in a fault state, false otherwise.
180 */
181 static inline bool isFault(uint16_t sw)
182 {
183 return sw_to_state(sw) == State::Fault;
184 }
185
186 /**
187 * Check if the fault reaction is active.
188 * @param sw Status word.
189 * @return true if the fault reaction is active, false otherwise.
190 */
191 static inline bool isFaultReactionActive(uint16_t sw)
192 {
193 return sw_to_state(sw) == State::FaultReaction;
194 }
195
196 /**
197 * Check if the drive is not ready to switch on.
198 * @param sw Status word.
199 * @return true if the drive is not ready to switch on, false otherwise.
200 */
201 static inline bool isQuickStopActive(uint16_t sw)
202 {
204 }
205
206 /**
207 * Check if the drive is switched on.
208 * @param sw Status word.
209 * @return true if the drive is switched on, false otherwise.
210 */
211 static inline bool isOperationEnabled(uint16_t sw)
212 {
214 }
215
216 /**
217 * Check if the drive is switched on.
218 * @param sw Status word.
219 * @return true if the drive is switched on, false otherwise.
220 */
221 static inline bool isSwitchedOn(uint16_t sw)
222 {
223 return sw_to_state(sw) == State::SwitchedOn;
224 }
225
226private:
227 struct Impl;
229};
230
231} // namespace CiA402
232
233#endif // YARP_DEV_CIA402_STATE_MACHINE_H
static bool isOperationEnabled(uint16_t sw)
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.
static bool isQuickStopActive(uint16_t sw)
static bool isOpEnabled(uint16_t sw)
~StateMachine()
Destructor.
static bool isFault(uint16_t sw)
void reset()
Resets the internal state machine.
Command faultReset() noexcept
Generates a fault reset command.
static bool isSwitchedOn(uint16_t sw)
static bool isFaultReactionActive(uint16_t sw)
int8_t getActiveOpMode() const noexcept
static constexpr State sw_to_state(uint16_t sw)
static constexpr std::string_view state_to_string(State s)
bool writeOpMode
Flag indicating if the operation mode should be written.
int8_t opMode
Operation mode to send to the drive.
uint16_t controlword
Control word to send to the drive.