24 #include <VirtualRobot/MathTools.h>
25 #include <VirtualRobot/Nodes/RobotNode.h>
26 #include <VirtualRobot/RobotNodeSet.h>
35 NJointControllerRegistration<NJointTSMixedImpedanceVelocityMPController>
37 "NJointTSMixedImpedanceVelocityMPController");
41 const NJointControllerConfigPtr& config,
51 return "NJointTSMixedImpedanceVelocityMPController";
57 const Ice::Current& iceCurrent)
61 for (
auto& pair :
limb)
63 pair.second->rtFirstRun.store(
true);
71 std::lock_guard<std::recursive_mutex> lock(
mtx_mps);
75 std::map<std::string, bool> mpRunning;
78 mpRunning[_mp.second.mp->getMPName()] = _mp.second.mp->isRunning();
79 if (_mp.second.mp->isFinished())
83 if (_mp.second.mp->getRole() ==
"taskspace")
85 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
86 if (_mp.second.mp->isFirstRun())
91 const std::vector<double> mpStart = _mp.second.mp->getStartVec();
94 arm->rtStatusInNonRT.currentPose,
97 "TSMP initial start pose",
98 arm->nonRtConfig.safeDistanceMMToGoal,
99 arm->nonRtConfig.safeRotAngleDegreeToGoal,
100 _mp.second.mp->getMPName() +
"mp_set_target"))
102 ARMARX_INFO <<
"deviation from current pose too large, reset MP start pose";
103 _mp.second.mp->validateInitialState(
108 mp::TSMPInputPtr in = std::dynamic_pointer_cast<mp::TSMPInput>(_mp.second.input);
109 in->pose = arm->rtStatusInNonRT.currentPose;
110 in->vel = arm->rtStatusInNonRT.currentTwist;
111 in->deltaT = arm->rtStatusInNonRT.deltaT;
113 else if (_mp.second.mp->getRole() ==
"nullspace")
115 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
116 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
118 arm->rtStatusInNonRT.jointPos.size());
119 in->angleRadian = arm->rtStatusInNonRT.jointPos;
120 in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
121 in->deltaT = arm->rtStatusInNonRT.deltaT;
123 else if (_mp.second.mp->getRole() ==
"hand")
125 auto&
hand =
hands->hands.at(_mp.second.mp->getNodeSetName());
126 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
128 hand->bufferRTToNonRT.getUpToDateReadBuffer().jointPosition.value();
129 in->deltaT =
hand->bufferRTToNonRT.getReadBuffer().deltaT;
132 if (not rtTargetSafe)
145 for (
auto& _mp :
mps)
147 if (not mpRunning.at(_mp.second.mp->getMPName()))
151 for (
auto& ftGuard :
mpConfig.ftGuard)
153 if (ftGuard.mpName == _mp.second.mp->getMPName())
155 bool const forceGuard =
156 (ftGuard.force.has_value() and
157 ftGuard.force.value() >= _mp.second.mp->getCanonicalValue());
158 bool const torqueGuard =
159 (ftGuard.torque.has_value() and
160 ftGuard.torque.value() >= _mp.second.mp->getCanonicalValue());
162 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
163 bool const resetForce =
164 not arm->controller.ftsensor.isForceGuardEnabled() and forceGuard;
165 bool const resetTorque =
166 not arm->controller.ftsensor.isTorqueGuardEnabled() and torqueGuard;
167 if (resetForce or resetTorque)
169 ARMARX_INFO <<
"Triggering force torque safety guard for "
170 << arm->kinematicChainName <<
" at can value "
171 << _mp.second.mp->getCanonicalValue();
174 arm->nonRtConfig.ftConfig.enableSafeGuardForce = forceGuard;
175 arm->nonRtConfig.ftConfig.enableSafeGuardTorque = torqueGuard;
176 arm->controller.ftsensor.enableSafeGuard(resetForce, resetTorque);
180 if (_mp.second.mp->getRole() ==
"taskspace")
182 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
184 std::dynamic_pointer_cast<mp::TSMPOutput>(_mp.second.output);
189 arm->rtStatusInNonRT.currentPose,
193 arm->nonRtConfig.safeDistanceMMToGoal,
194 arm->nonRtConfig.safeRotAngleDegreeToGoal,
195 _mp.second.mp->getMPName() +
"mp_set_target");
196 arm->nonRtConfig.desiredPose = out->pose;
197 arm->nonRtConfig.desiredTwist = out->vel;
199 else if (_mp.second.mp->getRole() ==
"nullspace")
201 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
203 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
205 arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
207 else if (_mp.second.mp->getRole() ==
"hand")
210 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
211 auto&
hand =
hands->hands.at(_mp.second.mp->getNodeSetName());
212 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
214 out->angleRadian.size());
215 hand->targetNonRT.jointPosition.value() = out->angleRadian;
217 if (mpRunning.at(_mp.second.mp->getMPName()) and _mp.second.mp->isFinished())
219 ARMARX_INFO <<
"reset buffer for nonRtConfig of " << _mp.second.mp->getMPName();
220 for (
auto& pair :
limb)
222 auto& arm = pair.second;
223 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
225 for (
auto& pair :
limb)
227 userConfig.limbs.at(pair.first) = pair.second->nonRtConfig;