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);
74 std::map<std::string, bool> mpRunning;
77 mpRunning[_mp.second.mp->getMPName()] = _mp.second.mp->isRunning();
78 if (_mp.second.mp->isFinished())
82 if (_mp.second.mp->getRole() ==
"taskspace")
84 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
85 if (_mp.second.mp->isFirstRun())
90 const std::vector<double> mpStart = _mp.second.mp->getStartVec();
93 arm->rtStatusInNonRT.currentPose,
96 "TSMP initial start pose",
97 arm->nonRtConfig.safeDistanceMMToGoal,
98 arm->nonRtConfig.safeRotAngleDegreeToGoal,
99 _mp.second.mp->getMPName() +
"mp_set_target"))
101 ARMARX_INFO <<
"deviation from current pose too large, reset MP start pose";
102 _mp.second.mp->validateInitialState(
107 mp::TSMPInputPtr in = std::dynamic_pointer_cast<mp::TSMPInput>(_mp.second.input);
108 in->pose = arm->rtStatusInNonRT.currentPose;
109 in->vel = arm->rtStatusInNonRT.currentTwist;
110 in->deltaT = arm->rtStatusInNonRT.deltaT;
112 else if (_mp.second.mp->getRole() ==
"nullspace")
114 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
115 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
117 arm->rtStatusInNonRT.jointPos.size());
118 in->angleRadian = arm->rtStatusInNonRT.jointPos;
119 in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
120 in->deltaT = arm->rtStatusInNonRT.deltaT;
122 else if (_mp.second.mp->getRole() ==
"hand")
124 auto&
hand =
hands->hands.at(_mp.second.mp->getNodeSetName());
125 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
127 hand->bufferRTToNonRT.getUpToDateReadBuffer().jointPosition.value();
128 in->deltaT =
hand->bufferRTToNonRT.getReadBuffer().deltaT;
144 for (
auto& _mp :
mps)
146 if (not mpRunning.at(_mp.second.mp->getMPName()))
150 for (
auto& ftGuard :
mpConfig.ftGuard)
152 if (ftGuard.mpName == _mp.second.mp->getMPName())
154 bool const forceGuard =
155 (ftGuard.force.has_value() and
156 ftGuard.force.value() >= _mp.second.mp->getCanonicalValue());
157 bool const torqueGuard =
158 (ftGuard.torque.has_value() and
159 ftGuard.torque.value() >= _mp.second.mp->getCanonicalValue());
161 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
162 bool const resetForce =
163 not arm->controller.ftsensor.isForceGuardEnabled() and forceGuard;
164 bool const resetTorque =
165 not arm->controller.ftsensor.isTorqueGuardEnabled() and torqueGuard;
166 if (resetForce or resetTorque)
168 ARMARX_INFO <<
"Triggering force torque safety guard for "
169 << arm->kinematicChainName <<
" at can value "
170 << _mp.second.mp->getCanonicalValue();
173 arm->nonRtConfig.ftConfig.enableSafeGuardForce = forceGuard;
174 arm->nonRtConfig.ftConfig.enableSafeGuardTorque = torqueGuard;
175 arm->controller.ftsensor.enableSafeGuard(resetForce, resetTorque);
179 if (_mp.second.mp->getRole() ==
"taskspace")
181 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
183 std::dynamic_pointer_cast<mp::TSMPOutput>(_mp.second.output);
188 arm->rtStatusInNonRT.currentPose,
192 arm->nonRtConfig.safeDistanceMMToGoal,
193 arm->nonRtConfig.safeRotAngleDegreeToGoal,
194 _mp.second.mp->getMPName() +
"mp_set_target");
195 arm->nonRtConfig.desiredPose = out->pose;
196 arm->nonRtConfig.desiredTwist = out->vel;
198 else if (_mp.second.mp->getRole() ==
"nullspace")
200 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
202 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
204 arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
206 else if (_mp.second.mp->getRole() ==
"hand")
209 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
210 auto&
hand =
hands->hands.at(_mp.second.mp->getNodeSetName());
211 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
213 out->angleRadian.size());
214 hand->targetNonRT.jointPosition.value() = out->angleRadian;
216 if (mpRunning.at(_mp.second.mp->getMPName()) and _mp.second.mp->isFinished())
218 ARMARX_INFO <<
"reset buffer for nonRtConfig of " << _mp.second.mp->getMPName();
219 for (
auto& pair :
limb)
221 auto& arm = pair.second;
222 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
224 for (
auto& pair :
limb)
226 userConfig.limbs.at(pair.first) = pair.second->nonRtConfig;