25#include <VirtualRobot/Robot.h>
42 static std::vector<JointController*>
59 const std::set<NJointControllerBasePtr>& request)
68 JointAndNJointControllers
73 std::lock_guard<std::recursive_mutex> guard{controllersActivatedMutex};
74 return controllersActivated.getReadBuffer();
77 std::vector<JointController*>
82 std::lock_guard<std::recursive_mutex> guard{controllersActivatedMutex};
83 return controllersActivated.getReadBuffer().jointControllers;
86 std::vector<NJointControllerBase*>
91 std::lock_guard<std::recursive_mutex> guard{controllersActivatedMutex};
92 return controllersActivated.getReadBuffer().nJointControllers;
100 std::lock_guard<std::recursive_mutex> guard{controllersActivatedMutex};
101 return controllersActivated.updateReadBuffer();
109 std::lock_guard<std::recursive_mutex> guard{controllersRequestedMutex};
110 return controllersRequested.getWriteBuffer();
113 std::vector<JointController*>
118 std::lock_guard<std::recursive_mutex> guard{controllersRequestedMutex};
119 return controllersRequested.getWriteBuffer().jointControllers;
122 std::vector<NJointControllerBase*>
127 std::lock_guard<std::recursive_mutex> guard{controllersRequestedMutex};
128 return controllersRequested.getWriteBuffer().nJointControllers;
136 return controlThreadOutputBuffer.updateReadBuffer();
144 return controlThreadOutputBuffer.getReadBuffer();
153 const auto& nJointCtrls = setOfControllers.nJointControllers;
154 std::set<NJointControllerBasePtr> nJointSet{nJointCtrls.begin(), nJointCtrls.end()};
155 nJointSet.erase(
nullptr);
157 const std::size_t nNJointCtrls =
158 std::count_if(nJointCtrls.begin(),
160 [](
const NJointControllerBasePtr& p) { return p; });
167 nJointCtrls.begin() + nNJointCtrls,
175 nJointCtrls.begin(), nJointCtrls.end(), std::greater<NJointControllerBase*>{}));
177 nJointCtrls.begin(), nJointCtrls.begin() + nNJointCtrls));
180 const auto& jointCtrls = setOfControllers.jointControllers;
184 jointCtrls.begin(), jointCtrls.end(), [](
JointController* p) { return p; }));
189 std::size_t grpIdx = 0;
194 setOfControllers.jointControllers
196 ->getHardwareControlMode();
197 ARMARX_DEBUG <<
"---- group " << grpIdx <<
" mode '" << hwMode <<
"'";
198 for (
const auto& other : group)
202 const auto otherHwMode =
203 setOfControllers.jointControllers.at(dev)->getHardwareControlMode();
204 ARMARX_DEBUG <<
"-------- '" << other <<
"'' mode '" << otherHwMode <<
"'";
213 setOfControllers.resetAssignement();
214 for (std::size_t nJointCtrlIndex = 0;
215 nJointCtrlIndex < setOfControllers.nJointControllers.size();
218 const NJointControllerBase* nJoint =
219 setOfControllers.nJointControllers.at(nJointCtrlIndex);
225 for (std::size_t jointIndex : nJoint->getControlDeviceUsedIndices())
228 << setOfControllers.jointToNJointControllerAssignement.at(
230 <<
"-> " << nJointCtrlIndex;
233 setOfControllers.jointToNJointControllerAssignement.at(jointIndex) =
244 ControllerManagementAttorneyForControlThreadDataBuffer::
245 UpdateNJointControllerRequestedState(
this, nJointSet);
248 setOfControllers.jointControllers.size());
250 setOfControllers.nJointControllers.size());
252 setOfControllers.jointToNJointControllerAssignement.size());
254 std::lock_guard<std::recursive_mutex> guard{controllersRequestedMutex};
255 controllersRequested.getWriteBuffer() = std::move(setOfControllers);
256 controllersRequested.commitWrite();
259 <<
"writeRequestedControllers(JointAndNJointControllers&& setOfControllers)...done!";
264 std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>> ctrls)
267 std::lock_guard<std::recursive_mutex> guardRequested{controllersRequestedMutex};
270 ctrls.erase(
nullptr);
273 const std::set<NJointControllerBasePtr, std::greater<NJointControllerBasePtr>>
274 setOfRequestedCtrls{controllersRequested.getWriteBuffer().nJointControllers.begin(),
275 controllersRequested.getWriteBuffer().nJointControllers.end()};
276 if (setOfRequestedCtrls == ctrls)
279 controllersRequested.commitWrite();
284 for (
const NJointControllerBasePtr& nJointCtrl : ctrls)
286 request.nJointControllers.at(idx++) = nJointCtrl.get();
288 for (
const auto& cd2cm : nJointCtrl->getControlDeviceUsedControlModeMap())
290 std::size_t jointCtrlIndex =
292 if (request.jointControllers.at(jointCtrlIndex))
294 std::stringstream ss;
295 ss <<
"RobotUnit:setActivateControllersRequest controllers to activate are in "
296 "conflict!\ncontrollers:";
297 for (
const auto& ctrl : ctrls)
299 ss <<
"\n" << ctrl->getInstanceName();
302 throw InvalidArgumentException{ss.str()};
304 request.jointControllers.at(jointCtrlIndex) =
308 ->getJointController(cd2cm.second);
313 for (std::size_t i = 0; i < jointControllersCount; ++i)
319 controllersRequested.getWriteBuffer().jointControllers.at(i);
321 _module<Devices>().getControlDevices().at(i)->getJointStopMovementController())
324 jointCtrl = jointCtrlOld;
332 ->getJointEmergencyStopController();
339 for (std::size_t i = 0; i < request.nJointControllers.size(); ++i)
341 const auto& ctrl = request.nJointControllers.at(i);
344 out << i <<
"\t'" << ctrl->getInstanceName() <<
"' \t of class '"
345 << ctrl->getClassName() <<
"'\n";
349 writeRequestedControllers(std::move(request));
355 const std::vector<VirtualRobot::RobotNodePtr>& nodes)
const
359 robot, nodes, controlThreadOutputBuffer.getReadBuffer().sensors);
367 robot, controlThreadOutputBuffer.getReadBuffer().sensors);
371 ControlThreadDataBuffer::_postFinishDeviceInitialization()
376 ARMARX_DEBUG <<
"----initializing controller buffers for "
381 ctrlinitReq.jointControllers.size());
383 ctrlinitReq.nJointControllers.size());
385 ctrlinitReq.jointToNJointControllerAssignement.size());
386 controllersActivated.reinitAllBuffers(ctrlinitReq);
388 ctrlinitReq.jointControllers =
389 DevicesAttorneyForControlThreadDataBuffer::GetStopMovementJointControllers(
this);
391 ctrlinitReq.jointControllers.size());
393 ctrlinitReq.nJointControllers.size());
395 ctrlinitReq.jointToNJointControllerAssignement.size());
396 controllersRequested.reinitAllBuffers(ctrlinitReq);
#define ARMARX_STREAM_PRINTER
use this macro to write output code that is executed when printed and thus not executed if the debug ...
The JointController class represents one joint in one control mode.
A high level controller writing its results into ControlTargets.
static std::optional< std::vector< char > > AreNotInConflict(ItT first, ItT last)
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.
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.
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.
This class allows minimal access to private members of ControllerManagement in a sane fashion for Con...
friend class ControlThreadDataBuffer
This Module manages NJointControllers.
This class allows minimal access to private members of Devices in a sane fashion for ControlThreadDat...
friend class ControlThreadDataBuffer
This Module manages sensor and control devices for a RobotUnit and only allows save and sane access.
T & _module()
Returns this as ref to the given type.
void throwIfInControlThread(const std::string &fnc) const
Throws if the current thread is the ControlThread.
static constexpr std::size_t IndexSentinel()
Returns a sentinel value for an index (std::numeric_limits<std::size_t>::max())
void throwIfDevicesNotReady(const std::string &fnc) const
Throws if the Devices are not ready.
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
#define ARMARX_INFO
The normal logging level.
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
std::shared_ptr< class Robot > RobotPtr
detail::ControlThreadOutputBufferEntry SensorAndControl
Structure used by the RobotUnit to swap lists of Joint and NJoint controllers.
std::vector< JointController * > jointControllers