|
24 | 24 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
25 | 25 | */ |
26 | 26 |
|
| 27 | +/** |
| 28 | + * @file trigger.h |
| 29 | + * @brief Trigger mechanism for periodic and event-based callbacks. |
| 30 | + * |
| 31 | + * The `trigger` class allows registration of callback objects |
| 32 | + * that are invoked at a specified rate. It also includes a |
| 33 | + * helper waiter (`trigger_waiter`) that can block until the |
| 34 | + * next trigger event occurs. |
| 35 | + * |
| 36 | + * This mechanism is widely used for scheduling periodic tasks |
| 37 | + * in device drivers, bridges, services, or other runtime modules. |
| 38 | + * |
| 39 | + * @note |
| 40 | + * - A trigger manages a set of callbacks that inherit from |
| 41 | + * `trigger_base`. |
| 42 | + * - Callbacks may be handled directly or via worker threads |
| 43 | + * depending on configuration. |
| 44 | + * - The `wait()` call may throw on timeout. |
| 45 | + * |
| 46 | + * See also `trigger_worker.h` for worker-based callback dispatch. |
| 47 | + */ |
| 48 | + |
27 | 49 | #ifndef ROBOTKERNEL__TRIGGER_H |
28 | 50 | #define ROBOTKERNEL__TRIGGER_H |
29 | 51 |
|
|
39 | 61 |
|
40 | 62 | namespace robotkernel { |
41 | 63 |
|
42 | | -//! trigger waiter class |
43 | | -class trigger_waiter : |
44 | | - public trigger_base |
| 64 | +/** |
| 65 | + * @class trigger_waiter |
| 66 | + * @brief Helper class that waits on a condition variable until a trigger occurs. |
| 67 | + * |
| 68 | + * This class can be used when a component needs to block until the |
| 69 | + * next trigger. The `tick()` method wakes all waiting threads, |
| 70 | + * and `wait()` sleeps until either a wake occurs or a timeout expires. |
| 71 | + */ |
| 72 | +class trigger_waiter : public trigger_base |
45 | 73 | { |
46 | 74 | public: |
| 75 | + /// Condition variable used to wake waiting threads. |
47 | 76 | std::condition_variable cond; |
48 | | - std::mutex mtx; |
49 | | - |
50 | | - trigger_waiter() { } |
51 | | - |
52 | | - ~trigger_waiter() { } |
53 | | - |
54 | | - void tick() { |
| 77 | + |
| 78 | + /// Mutex protecting the condition variable. |
| 79 | + std::mutex mtx; |
| 80 | + |
| 81 | + /// Construct a trigger waiter. |
| 82 | + trigger_waiter() {} |
| 83 | + |
| 84 | + /// Default destructor. |
| 85 | + ~trigger_waiter() {} |
| 86 | + |
| 87 | + /** |
| 88 | + * @brief Notify all waiting threads. |
| 89 | + * |
| 90 | + * Called by the triggering mechanism on each tick to wake |
| 91 | + * up any waiters. |
| 92 | + */ |
| 93 | + void tick() |
| 94 | + { |
55 | 95 | std::unique_lock<std::mutex> lock(mtx); |
56 | 96 | cond.notify_all(); |
57 | 97 | } |
58 | | - |
59 | | - void wait(double timeout) { |
| 98 | + |
| 99 | + /** |
| 100 | + * @brief Block until the next trigger tick or timeout. |
| 101 | + * |
| 102 | + * @param timeout Maximum time to wait, in seconds. |
| 103 | + * @throws std::runtime_error If the wait times out. |
| 104 | + */ |
| 105 | + void wait(double timeout) |
| 106 | + { |
60 | 107 | std::unique_lock<std::mutex> lock(mtx); |
61 | 108 | wait(timeout, lock); |
62 | 109 | } |
63 | | - |
64 | | - void wait(double timeout, std::unique_lock<std::mutex>& lock) { |
65 | | - if (cond.wait_for(lock, std::chrono::nanoseconds( |
66 | | - (uint64_t)(timeout * 1000000000))) == std::cv_status::timeout) |
| 110 | + |
| 111 | + /** |
| 112 | + * @brief Block on the condition with an existing lock. |
| 113 | + * |
| 114 | + * @param timeout Maximum time to wait, in seconds. |
| 115 | + * @param lock Held mutex lock during wait. |
| 116 | + * @throws std::runtime_error If the wait times out. |
| 117 | + */ |
| 118 | + void wait(double timeout, std::unique_lock<std::mutex>& lock) |
| 119 | + { |
| 120 | + using namespace std::chrono; |
| 121 | + if (cond.wait_for(lock, nanoseconds((uint64_t)(timeout * 1e9))) |
| 122 | + == std::cv_status::timeout) { |
67 | 123 | throw std::runtime_error("timeout waiting for trigger"); |
| 124 | + } |
68 | 125 | } |
69 | 126 | }; |
70 | 127 |
|
| 128 | +/// Shared pointer type for trigger_waiter. |
71 | 129 | typedef std::shared_ptr<trigger_waiter> sp_trigger_waiter_t; |
72 | 130 |
|
73 | | -class trigger : |
74 | | - public device |
| 131 | + |
| 132 | +/** |
| 133 | + * @class trigger |
| 134 | + * @brief Central trigger object that schedules callback execution. |
| 135 | + * |
| 136 | + * A trigger object manages one or more callback handlers derived |
| 137 | + * from `trigger_base`. Each callback is scheduled at the trigger's |
| 138 | + * configured rate and may be executed either directly or via |
| 139 | + * worker threads depending on the callback configuration. |
| 140 | + * |
| 141 | + * Derived classes or users can adjust the trigger rate at runtime. |
| 142 | + */ |
| 143 | +class trigger : public device |
75 | 144 | { |
76 | 145 | private: |
77 | | - trigger(const trigger&); // prevent copy-construction |
78 | | - trigger& operator=(const trigger&); // prevent assignment |
79 | | - |
80 | | - std::mutex list_mtx; //!< protection for trigger list |
81 | | - trigger_list_t triggers; //!< trigger callback list |
82 | | - trigger_workers_t workers; //!< workers |
83 | | - |
| 146 | + /// Disable copy construction. |
| 147 | + trigger(const trigger&); |
| 148 | + |
| 149 | + /// Disable assignment. |
| 150 | + trigger& operator=(const trigger&); |
| 151 | + |
| 152 | + /// Mutex protecting access to the trigger list. |
| 153 | + std::mutex list_mtx; |
| 154 | + |
| 155 | + /// Map of registered trigger callbacks. |
| 156 | + trigger_list_t triggers; |
| 157 | + |
| 158 | + /// Worker threads for handling callbacks. |
| 159 | + trigger_workers_t workers; |
| 160 | + |
84 | 161 | protected: |
85 | | - double rate; //!< trigger rate in [Hz] |
86 | | - |
| 162 | + /// Trigger rate in Hz (events per second). |
| 163 | + double rate; |
| 164 | + |
87 | 165 | public: |
88 | | - //! trigger construction |
89 | | - /*! |
90 | | - * \param[in] owner Name of owning module/bridge/service_provider... |
91 | | - * \param[in] name Name of trigger. |
92 | | - * \param[in] rate Rate of trigger in seconds [s]. |
| 166 | + /** |
| 167 | + * @brief Construct a trigger with a given rate. |
| 168 | + * |
| 169 | + * @param owner Logical owner name (e.g. bridge/module). |
| 170 | + * @param name Name of the trigger. |
| 171 | + * @param rate Frequency of trigger in Hertz (Hz). 0 means manual. |
93 | 172 | */ |
94 | | - trigger( |
95 | | - const std::string& owner, |
96 | | - const std::string& name, |
| 173 | + trigger(const std::string& owner, |
| 174 | + const std::string& name, |
97 | 175 | double rate = 0.); |
98 | | - |
99 | | - //! destruction |
100 | | - ~trigger(); |
101 | | - |
102 | | - //! add a trigger callback function |
103 | | - /*! |
104 | | - * \param cb trigger callback |
105 | | - * \param divisor rate divisor |
106 | | - * \return trigger object to newly inserted callback |
| 176 | + |
| 177 | + /// Virtual destructor. |
| 178 | + virtual ~trigger(); |
| 179 | + |
| 180 | + /** |
| 181 | + * @brief Add a trigger callback. |
| 182 | + * |
| 183 | + * Registers a callback object with this trigger. The callback |
| 184 | + * will be invoked on each tick at the configured rate. |
| 185 | + * |
| 186 | + * @param trigger Shared pointer to callback object. |
107 | 187 | */ |
108 | | - void add_trigger(sp_trigger_base_t trigger) { |
109 | | - add_trigger( |
110 | | - trigger, |
111 | | - trigger->direct_mode, |
112 | | - trigger->worker_prio, |
113 | | - trigger->worker_affinity); |
| 188 | + void add_trigger(sp_trigger_base_t trigger) |
| 189 | + { |
| 190 | + add_trigger(trigger, |
| 191 | + trigger->direct_mode, |
| 192 | + trigger->worker_prio, |
| 193 | + trigger->worker_affinity); |
114 | 194 | } |
115 | | - |
116 | | - //! add a trigger callback function |
117 | | - /*! |
118 | | - * \param cb trigger callback |
119 | | - * \param divisor rate divisor |
120 | | - * \return trigger object to newly inserted callback |
| 195 | + |
| 196 | + /** |
| 197 | + * @brief Add a trigger callback with custom execution parameters. |
| 198 | + * |
| 199 | + * @param trigger Callback object to register. |
| 200 | + * @param direct_mode Whether to run the callback in the trigger thread. |
| 201 | + * @param worker_prio Thread priority for worker execution. |
| 202 | + * @param worker_affinity CPU affinity for worker thread. |
121 | 203 | */ |
122 | | - void add_trigger(sp_trigger_base_t trigger, bool direct_mode, |
123 | | - int worker_prio, int worker_affinity); |
124 | | - |
125 | | - //! remove a trigger callback function |
126 | | - /*! |
127 | | - * \param obj trigger object to trigger callback |
| 204 | + void add_trigger(sp_trigger_base_t trigger, |
| 205 | + bool direct_mode, |
| 206 | + int worker_prio, |
| 207 | + int worker_affinity); |
| 208 | + |
| 209 | + /** |
| 210 | + * @brief Remove a previously registered trigger callback. |
| 211 | + * |
| 212 | + * @param trigger Callback object to unregister. |
128 | 213 | */ |
129 | 214 | void remove_trigger(sp_trigger_base_t trigger); |
130 | | - |
131 | | - //! get rate of trigger |
132 | | - /*! |
133 | | - * return the current rate of the trigger |
| 215 | + |
| 216 | + /** |
| 217 | + * @brief Get the configured trigger rate. |
| 218 | + * |
| 219 | + * @return The rate in Hertz. |
134 | 220 | */ |
135 | 221 | double get_rate() const { return rate; } |
136 | | - |
137 | | - //! set rate of trigger |
138 | | - /*! |
139 | | - * set the rate of the current trigger |
140 | | - * overload in derived trigger class |
| 222 | + |
| 223 | + /** |
| 224 | + * @brief Set a new trigger rate. |
| 225 | + * |
| 226 | + * Derived classes may override this to implement |
| 227 | + * specific rate constraints or scheduling behavior. |
141 | 228 | * |
142 | | - * \param new_rate new trigger rate to set |
| 229 | + * @param new_rate New trigger frequency in Hertz. |
143 | 230 | */ |
144 | 231 | virtual void set_rate(double new_rate); |
145 | | - |
146 | | - //! trigger all modules in list |
| 232 | + |
| 233 | + /** |
| 234 | + * @brief Invoke all registered callbacks. |
| 235 | + * |
| 236 | + * Called internally by the trigger scheduler (timer or loop). |
| 237 | + * Executes all callbacks at this tick. |
| 238 | + */ |
147 | 239 | void do_trigger(); |
148 | | - |
149 | | - //! wait blocking for next trigger |
150 | | - /*! |
151 | | - * \param[in] timeout Wait timeout in seconds. |
| 240 | + |
| 241 | + /** |
| 242 | + * @brief Block until the next trigger event or timeout. |
| 243 | + * |
| 244 | + * @param timeout Maximum wait time in seconds. |
152 | 245 | */ |
153 | 246 | void wait(double timeout); |
154 | 247 | }; |
155 | 248 |
|
| 249 | +/// Shared pointer type for trigger. |
156 | 250 | typedef std::shared_ptr<trigger> sp_trigger_t; |
| 251 | + |
| 252 | +/// Map from trigger names to shared trigger pointers. |
157 | 253 | typedef std::map<std::string, sp_trigger_t> trigger_map_t; |
158 | 254 |
|
159 | 255 | } // namespace robotkernel |
|
0 commit comments