RobotUnitModuleControlThreadDataBuffer.h
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package RobotAPI::ArmarXObjects::RobotUnit
17 * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
18 * @date 2018
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
23#pragma once
24
25#include <VirtualRobot/VirtualRobot.h>
26
28
29#include <RobotAPI/interface/units/RobotUnit/RobotUnitInterface.h>
30
34#include "RobotUnitModuleBase.h"
35
36namespace armarx
37{
38 class SensorValue1DoFActuatorPosition;
39}
40
42{
43 /**
44 * @ingroup Library-RobotUnit-Modules
45 * @brief This \ref ModuleBase "Module" manages all communication into and out of the \ref ControlThread.
46 *
47 * \section buffers Data Buffers
48 * This class holds three data buffers
49 *
50 * \subsection bufferreq Buffer for requested controllers
51 * \note This buffer's direction is ArmarX -> \ref ControlThread
52 *
53 * This buffer contains all \ref NJointControllerBase "NJointControllers"
54 * requested by the user (e.g.: via \ref NJointControllerBase::activate) and
55 * the set of \ref JointController "JointControllers" implicitly defined by this.
56 * These controllers will be activated by \ref ControlThread::rtSwitchControllerSetup.
57 *
58 *
59 * \subsection bufferact Buffer for activated controllers
60 * \note This buffer's direction is \ref ControlThread -> ArmarX
61 *
62 * This buffer contains all \ref JointController "Joint-" and
63 * \ref NJointControllerBase "NJointControllers" executed by the \ref ControlThread.
64 *
65 *
66 * \subsection bufferout Buffer for iteration data
67 * \note This buffer's direction is \ref ControlThread -> ArmarX
68 *
69 * This buffer contains all \ref SensorValueBase "SensorValues" and \ref ControlTargetBase "ControlTargets"
70 * for each iteration.
71 * It also contains messages logged via \ref ARMARX_RT_LOGF.
72 *
73 * This data is used to update \ref Units and is reported to topics (see \ref Publish).
74 *
75 * This buffer is organized as a ringbuffer and holds several old iterations.
76 *
77 * @see ModuleBase
78 */
79 class ControlThreadDataBuffer : virtual public ModuleBase
80 {
81 friend class ModuleBase;
82
83 public:
84 /**
85 * @brief Returns the singleton instance of this class
86 * @return The singleton instance of this class
87 */
93
94 // //////////////////////////////////////////////////////////////////////////////////////// //
95 // ///////////////////////////////// RobotUnitModule hooks //////////////////////////////// //
96 // //////////////////////////////////////////////////////////////////////////////////////// //
97 private:
98 /// @see ModuleBase::_postFinishDeviceInitialization
99 void _postFinishDeviceInitialization();
100 // //////////////////////////////////////////////////////////////////////////////////////// //
101 // /////////////////////////////////// Module interface /////////////////////////////////// //
102 // //////////////////////////////////////////////////////////////////////////////////////// //
103 public:
104 /**
105 * @brief Updates the given VirtualRobot with the current joint values
106 * @param robot The robot to update
107 */
108 void updateVirtualRobot(const VirtualRobot::RobotPtr& robot) const;
109 /**
110 * @brief Updates the given VirtualRobot with the current joint values
111 * @param robot The robot to update
112 * @param nodes The robot's nodes
113 */
115 const std::vector<VirtualRobot::RobotNodePtr>& nodes) const;
116
117 /**
118 * @brief Returns whether the set of activated \ref JointController "Joint-" and
119 * \ref NJointControllerBase "NJointControllers" changed.
120 * @return Whether the set of activated \ref JointController "Joint-" and
121 * \ref NJointControllerBase "NJointControllers" changed.
122 * @see ControlThread
123 * @see ControlThread::rtSwitchControllerSetup
124 */
125 bool activatedControllersChanged() const; ///TODO private + attorney for publish
126 /**
127 * @brief Returns the set of activated \ref JointController "Joint-" and
128 * \ref NJointControllerBase "NJointControllers".
129 * @return The set of activated \ref JointController "Joint-" and
130 * \ref NJointControllerBase "NJointControllers".
131 * @see ControlThread
132 * @see ControlThread::rtSwitchControllerSetup
133 */
135 /**
136 * @brief Returns the set of activated \ref JointController "JointControllers".
137 * @return The set of activated \ref JointController "JointControllers".
138 * @see ControlThread
139 * @see ControlThread::rtSwitchControllerSetup
140 */
141 std::vector<JointController*> getActivatedJointControllers() const;
142 /**
143 * @brief Returns the set of activated \ref NJointControllerBase "NJointControllers".
144 * @return The set of activated \ref NJointControllerBase "NJointControllers".
145 * @see ControlThread
146 * @see ControlThread::rtSwitchControllerSetup
147 */
148 std::vector<NJointControllerBase*> getActivatedNJointControllers() const;
149
150 /**
151 * @brief Returns the set of requsted \ref JointController "Joint-" and
152 * \ref NJointControllerBase "NJointControllers".
153 * @return The set of requested \ref JointController "Joint-" and
154 * \ref NJointControllerBase "NJointControllers".
155 * @see ControllerManagement
156 * @see ControllerManagement::activateNJointController
157 * @see ControllerManagement::deactivateNJointController
158 * @see ControllerManagement::switchNJointControllerSetup
159 * @see NJointControllerBase::activateController
160 * @see NJointControllerBase::deactivateController
161 * @see setActivateControllersRequest
162 */
164 /**
165 * @brief Returns the set of requsted \ref JointController "JointControllers".
166 * @return The set of requested \ref JointController "JointControllers".
167 * @see ControllerManagement
168 * @see ControllerManagement::activateNJointController
169 * @see ControllerManagement::deactivateNJointController
170 * @see ControllerManagement::switchNJointControllerSetup
171 * @see NJointControllerBase::activateController
172 * @see NJointControllerBase::deactivateController
173 * @see setActivateControllersRequest
174 */
175 std::vector<JointController*> copyRequestedJointControllers() const;
176 /**
177 * @brief Returns the set of requsted \ref NJointControllerBase "NJointControllers".
178 * @return The set of requested \ref NJointControllerBase "NJointControllers".
179 * @see ControllerManagement
180 * @see ControllerManagement::activateNJointController
181 * @see ControllerManagement::deactivateNJointController
182 * @see ControllerManagement::switchNJointControllerSetup
183 * @see NJointControllerBase::activateController
184 * @see NJointControllerBase::deactivateController
185 * @see setActivateControllersRequest
186 */
187 std::vector<NJointControllerBase*> copyRequestedNJointControllers() const;
188
189 /**
190 * @brief Updates the sensor and control buffer and returns whether the buffer was updated.
191 * @return Whether the buffer was updated.
192 */
193 bool sensorAndControlBufferChanged() const; /// TODO private + attorney for publish
194 /**
195 * @brief Returns the last updated sensor and control buffer.
196 * @return The last updated sensor and control buffer.
197 */
199
200 /**
201 * @brief Returns the \ref ControlThreadOutputBuffer
202 * \warning This function is dangerous to use.
203 * @return The \ref ControlThreadOutputBuffer
204 */
206 getControlThreadOutputBuffer() ///TODO refactor logging and remove this function
207 {
208 return controlThreadOutputBuffer;
209 }
210
211 /**
212 * @brief Returns the writer buffer for sensor and control values.
213 * @return The writer buffer for sensor and control values.
214 */
216 rtGetSensorAndControlBuffer() ///TODO move to attorney
217 {
218 return controlThreadOutputBuffer.getWriteBuffer();
219 }
220
221 /**
222 * @brief Commits the writer buffer for sensor and control values.
223 */
224 void
225 rtSensorAndControlBufferCommitWrite() ///TODO move to attorney
226 {
227 return controlThreadOutputBuffer.commitWrite();
228 }
229
230 /**
231 * @brief Sets the set of requested \ref NJointControllerBase "NJointControllers" to \param ctrls.
232 * @param ctrls \ref NJointControllerBase "NJointControllers" requested.
233 * @see ControllerManagement
234 * @see ControllerManagement::activateNJointController
235 * @see ControllerManagement::deactivateNJointController
236 * @see ControllerManagement::switchNJointControllerSetup
237 * @see NJointControllerBase::activateController
238 * @see NJointControllerBase::deactivateController
239 */
241 std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>> ctrls);
242 // //////////////////////////////////////////////////////////////////////////////////////// //
243 // //////////////////////////////////// implementation //////////////////////////////////// //
244 // //////////////////////////////////////////////////////////////////////////////////////// //
245 protected:
246 /**
247 * @brief This hook is called prior to writing the set of requested controllers.
248 * A deriving class can override this function to perform some additional checks
249 * (e.g. two controll devices may always need to have the same control mode, this can be checked here)
250 * If any check fails, throw an exception with a descriptive message.
251 * @param controllers The controllers to activate
252 */
253 virtual void
255 {
256 }
257
258 private:
259 void writeRequestedControllers(JointAndNJointControllers&& setOfControllers);
260
261 // //////////////////////////////////////////////////////////////////////////////////////// //
262 // ///////////////////////////////////////// Data ///////////////////////////////////////// //
263 // //////////////////////////////////////////////////////////////////////////////////////// //
264 private:
265 /// @brief Controllers the RT thread is supposed to activate (direction nonRT -> RT) (some NJoint controllers may be null)
266 /// data may only be used after State::InitializingDevices
267 /// all NJointControllerBase have to be sorted by id (null controllers are at the end)
269 /// @brief Mutex guarding \ref controllersRequested
270 mutable std::recursive_mutex controllersRequestedMutex;
271
272 /// @brief Controllers the RT thread is currently running (direction RT -> nonRT) (some NJoint controllers may be null)
273 /// data may only be used after State::InitializingDevices
274 /// all NJointControllerBase are sorted by id (null controllers may be anywhere)
276 /// @brief Mutex guarding \ref controllersActivated
277 mutable std::recursive_mutex controllersActivatedMutex;
278
279 /// @brief Transfers Data (current sensor values and control targets) from the control thread to other threads (direction RT -> nonRT)
280 /// \warning DO NOT ACCESS EXCEPT YOU KNOW WHAT YOU ARE DOING!
281 ControlThreadOutputBuffer controlThreadOutputBuffer;
282 /// @brief Mutex guarding \ref controlThreadOutputBuffer
283 mutable std::recursive_mutex
284 controlThreadOutputBufferMutex; /// TODO use this mutex instead of the global one
285 // //////////////////////////////////////////////////////////////////////////////////////// //
286 // /////////////////////////////////////// Attorneys ////////////////////////////////////// //
287 // //////////////////////////////////////////////////////////////////////////////////////// //
288 private:
289 /**
290 * \brief This class allows minimal access to private members of \ref ControlThreadDataBuffer in a sane fashion for \ref ControlThread.
291 * \warning !! DO NOT ADD ADDITIONAL FRIENDS IF YOU DO NOT KNOW WAHT YOU ARE DOING! IF YOU DO SOMETHING WRONG YOU WILL CAUSE UNDEFINED BEHAVIOUR !!
292 */
294 };
295} // namespace armarx::RobotUnitModule
This Module manages all communication into and out of the ControlThread.
virtual void checkSetOfControllersToActivate(const JointAndNJointControllers &) const
This hook is called prior to writing the set of requested controllers.
std::vector< NJointControllerBase * > getActivatedNJointControllers() const
Returns the set of activated NJointControllers.
bool sensorAndControlBufferChanged() const
Updates the sensor and control buffer and returns whether the buffer was updated.
bool activatedControllersChanged() const
Returns whether the set of activated Joint- and NJointControllers changed.
void setActivateControllersRequest(std::set< NJointControllerBasePtr, std::greater< NJointControllerBasePtr > > ctrls)
Sets the set of requested NJointControllers to.
JointAndNJointControllers getActivatedControllers() const
TODO private + attorney for publish.
const SensorAndControl & getSensorAndControlBuffer() const
TODO private + attorney for publish.
friend class ControlThreadDataBufferAttorneyForControlThread
TODO use this mutex instead of the global one.
ControlThreadOutputBuffer & getControlThreadOutputBuffer()
Returns the ControlThreadOutputBuffer.
SensorAndControl & rtGetSensorAndControlBuffer()
Returns the writer buffer for sensor and control values.
void rtSensorAndControlBufferCommitWrite()
Commits the writer buffer for sensor and control values.
std::vector< JointController * > copyRequestedJointControllers() const
Returns the set of requsted JointControllers.
JointAndNJointControllers copyRequestedControllers() const
Returns the set of requsted Joint- and NJointControllers.
std::vector< NJointControllerBase * > copyRequestedNJointControllers() const
Returns the set of requsted NJointControllers.
static ControlThreadDataBuffer & Instance()
Returns the singleton instance of this class.
void updateVirtualRobot(const VirtualRobot::RobotPtr &robot) const
Updates the given VirtualRobot with the current joint values.
std::vector< JointController * > getActivatedJointControllers() const
Returns the set of activated JointControllers.
static ModuleBase & Instance()
Returns the singleton instance of this class.
Same as the TripleBuffer, but partial writes of the data structure are ok. The write operation may be...
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
This file offers overloads of toIce() and fromIce() functions for STL container types.
detail::ControlThreadOutputBufferEntry SensorAndControl
Structure used by the RobotUnit to swap lists of Joint and NJoint controllers.