70 const std::lock_guard<std::recursive_mutex> lock(
mtx_mps);
78 std::map<std::string, bool> flagMPToStop;
79 for (
auto& pair :
limb)
81 flagMPToStop[pair.first] = not
limb.at(pair.first)->controller.ftsensor.ftSafe.load();
82 if (flagMPToStop[pair.first])
86 pair.second->nonRTDeltaT =
87 pair.second->rtStatusInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
88 pair.second->nonRTAccumulateTime = pair.second->rtStatusInNonRT.accumulateTime;
92 for (
auto& pair :
hands->hands)
94 pair.second->nonRTDeltaT =
95 pair.second->rtsInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
96 pair.second->nonRTAccumulateTime = pair.second->rtsInNonRT.accumulateTime;
100 std::map<std::string, bool> mpRunning;
103 const auto mpNodeSet =
mp.second.mp->getNodeSetName();
104 mpRunning[
mp.second.mp->getMPName()] =
mp.second.mp->isRunning();
107 auto search = flagMPToStop.find(mpNodeSet);
108 if (
mp.second.mp->isStopRequested())
110 mp.second.mp->stop();
111 ARMARX_INFO <<
"user requested to stop mp execution at canonical value: "
112 <<
mp.second.mp->getCanonicalValue();
114 if (search != flagMPToStop.end() and flagMPToStop.at(mpNodeSet) and
115 mp.second.mp->isRunning() and
116 (
limb.at(mpNodeSet)->controller.ftsensor.isForceGuardEnabled() or
117 limb.at(mpNodeSet)->controller.ftsensor.isTorqueGuardEnabled()))
119 mp.second.mp->stop();
120 auto& force =
limb.at(mpNodeSet)->rtStatusInNonRT.currentForceTorque;
121 ARMARX_INFO <<
"Due to force/torque safe guard, MP " <<
mp.second.mp->getMPName()
122 <<
" is stopped at " <<
mp.second.mp->getCanonicalValue()
123 <<
" with current ft: " << force;
126 if (
mp.second.mp->isFinished())
130 if (
mp.second.mp->getRole() ==
"taskspace")
132 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
133 if (
mp.second.mp->isFirstRun())
138 const std::vector<double> mpStart =
mp.second.mp->getStartVec();
140 if (
mp.second.mp->getStartFromPrevTarget() or
142 arm->rtStatusInNonRT.currentPose,
145 "TSMP initial start pose",
146 arm->nonRtConfig.safeDistanceMMToGoal,
147 arm->nonRtConfig.safeRotAngleDegreeToGoal,
148 mp.second.mp->getMPName() +
"mp_set_target"))
150 if (
mp.second.mp->getStartFromPrevTarget())
152 ARMARX_INFO <<
"User requested to start the current TS MP from the "
153 "previous target pose";
158 <<
"deviation from current pose too large, reset MP start pose";
160 mp.second.mp->validateInitialState(
166 in->pose = arm->rtStatusInNonRT.currentPose;
167 in->vel = arm->rtStatusInNonRT.currentTwist;
169 in->deltaT = arm->nonRTDeltaT;
171 else if (
mp.second.mp->getRole() ==
"nullspace")
173 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
176 arm->rtStatusInNonRT.jointPosition.size());
177 in->angleRadian = arm->rtStatusInNonRT.jointPosition;
178 in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
179 in->deltaT = arm->nonRTDeltaT;
181 else if (
mp.second.mp->getRole() ==
"hand")
183 auto&
hand =
hands->hands.at(
mp.second.mp->getNodeSetName());
186 in->deltaT =
hand->nonRTDeltaT;
188 else if (
mp.second.mp->getRole() ==
"object")
192 ARMARX_WARNING <<
"when using the object for MP, the coordinator must be first "
202 const std::scoped_lock lock_vo_non_rt(
coordinator->mtx_data_non_rt);
209 if (not rtTargetSafe)
224 if (not mpRunning.at(
mp.second.mp->getMPName()))
228 for (
auto& ftGuard :
mpConfig.ftGuard)
230 if (ftGuard.mpName ==
mp.second.mp->getMPName())
232 bool const forceGuard =
233 (ftGuard.force.has_value() and
234 ftGuard.force.value() >=
mp.second.mp->getCanonicalValue());
235 bool const torqueGuard =
236 (ftGuard.torque.has_value() and
237 ftGuard.torque.value() >=
mp.second.mp->getCanonicalValue());
239 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
240 bool const resetForce =
241 not arm->controller.ftsensor.isForceGuardEnabled() and forceGuard;
242 bool const resetTorque =
243 not arm->controller.ftsensor.isTorqueGuardEnabled() and torqueGuard;
244 if (resetForce or resetTorque)
246 ARMARX_INFO <<
"Triggering force torque safety guard for "
247 << arm->kinematicChainName <<
" at can value "
248 <<
mp.second.mp->getCanonicalValue();
251 arm->nonRtConfig.ftConfig.enableSafeGuardForce = forceGuard;
252 arm->nonRtConfig.ftConfig.enableSafeGuardTorque = torqueGuard;
253 arm->controller.ftsensor.enableSafeGuard(resetForce, resetTorque);
257 if (
mp.second.mp->getRole() ==
"taskspace")
259 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
265 arm->rtStatusInNonRT.currentPose,
269 arm->nonRtConfig.safeDistanceMMToGoal,
270 arm->nonRtConfig.safeRotAngleDegreeToGoal,
271 mp.second.mp->getMPName() +
"mp_set_target");
272 arm->nonRtConfig.desiredPose = out->pose;
273 arm->nonRtConfig.desiredTwist = out->vel;
275 else if (
mp.second.mp->getRole() ==
"object")
279 ARMARX_WARNING <<
"when using the object for MP, the coordinator must be first "
286 else if (
mp.second.mp->getRole() ==
"nullspace")
288 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
291 arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
293 else if (
mp.second.mp->getRole() ==
"hand")
296 auto&
hand =
hands->hands.at(
mp.second.mp->getNodeSetName());
299 out->angleRadian.size());
300 hand->targetNonRT.jointPosition.value() = out->angleRadian;
302 if (mpRunning.at(
mp.second.mp->getMPName()) and
mp.second.mp->isFinished())
304 ARMARX_INFO <<
"reset buffer for nonRtConfig of " <<
mp.second.mp->getMPName();
305 for (
auto& pair :
limb)
307 auto& arm = pair.second;
308 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
309 arm->controller.ftsensor.enableSafeGuard(
true,
true);
311 for (
auto& pair :
limb)
313 userConfig.limbs.at(pair.first) = pair.second->nonRtConfig;