68 const std::lock_guard<std::recursive_mutex> lock(
mtx_mps);
76 std::map<std::string, bool> flagMPToStop;
77 for (
auto& pair :
limb)
79 flagMPToStop[pair.first] = not
limb.at(pair.first)->controller.ftsensor.ftSafe.load();
80 pair.second->nonRTDeltaT =
81 pair.second->rtStatusInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
82 pair.second->nonRTAccumulateTime = pair.second->rtStatusInNonRT.accumulateTime;
86 for (
auto& pair :
hands->hands)
88 pair.second->nonRTDeltaT =
89 pair.second->rtsInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
90 pair.second->nonRTAccumulateTime = pair.second->rtsInNonRT.accumulateTime;
94 std::map<std::string, bool> mpRunning;
97 const auto mpNodeSet =
mp.second.mp->getNodeSetName();
98 mpRunning[
mp.second.mp->getMPName()] =
mp.second.mp->isRunning();
101 auto search = flagMPToStop.find(mpNodeSet);
102 if (search != flagMPToStop.end() and flagMPToStop.at(mpNodeSet) and
103 mp.second.mp->isRunning() and
104 (
limb.at(mpNodeSet)->controller.ftsensor.isForceGuardEnabled() or
105 limb.at(mpNodeSet)->controller.ftsensor.isTorqueGuardEnabled()))
107 mp.second.mp->stop();
108 ARMARX_INFO <<
"Due to force/torque safe guard, MP " <<
mp.second.mp->getMPName()
109 <<
" is stopped at " <<
mp.second.mp->getCanonicalValue();
112 if (
mp.second.mp->isFinished())
116 if (
mp.second.mp->getRole() ==
"taskspace")
118 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
119 if (
mp.second.mp->isFirstRun())
124 const std::vector<double> mpStart =
mp.second.mp->getStartVec();
126 if (
mp.second.mp->getStartFromPrevTarget() or
128 arm->rtStatusInNonRT.currentPose,
131 "TSMP initial start pose",
132 arm->nonRtConfig.safeDistanceMMToGoal,
133 arm->nonRtConfig.safeRotAngleDegreeToGoal,
134 mp.second.mp->getMPName() +
"mp_set_target"))
136 if (
mp.second.mp->getStartFromPrevTarget())
138 ARMARX_INFO <<
"User requested to start the current TS MP from the "
139 "previous target pose";
144 <<
"deviation from current pose too large, reset MP start pose";
146 mp.second.mp->validateInitialState(
152 in->pose = arm->rtStatusInNonRT.currentPose;
153 in->vel = arm->rtStatusInNonRT.currentTwist;
155 in->deltaT = arm->nonRTDeltaT;
157 else if (
mp.second.mp->getRole() ==
"nullspace")
159 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
162 arm->rtStatusInNonRT.jointPosition.size());
163 in->angleRadian = arm->rtStatusInNonRT.jointPosition;
164 in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
165 in->deltaT = arm->nonRTDeltaT;
167 else if (
mp.second.mp->getRole() ==
"hand")
169 auto&
hand =
hands->hands.at(
mp.second.mp->getNodeSetName());
172 in->deltaT =
hand->nonRTDeltaT;
174 else if (
mp.second.mp->getRole() ==
"object")
178 ARMARX_WARNING <<
"when using the object for MP, the coordinator must be first "
188 const std::scoped_lock lock_vo_non_rt(
coordinator->mtx_data_non_rt);
195 if (not rtTargetSafe)
210 if (not mpRunning.at(
mp.second.mp->getMPName()))
214 for (
auto& ftGuard :
mpConfig.ftGuard)
216 if (ftGuard.mpName ==
mp.second.mp->getMPName())
218 bool const forceGuard =
219 (ftGuard.force.has_value() and
220 ftGuard.force.value() >=
mp.second.mp->getCanonicalValue());
221 bool const torqueGuard =
222 (ftGuard.torque.has_value() and
223 ftGuard.torque.value() >=
mp.second.mp->getCanonicalValue());
225 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
226 bool const resetForce =
227 not arm->controller.ftsensor.isForceGuardEnabled() and forceGuard;
228 bool const resetTorque =
229 not arm->controller.ftsensor.isTorqueGuardEnabled() and torqueGuard;
230 if (resetForce or resetTorque)
232 ARMARX_INFO <<
"Triggering force torque safety guard for "
233 << arm->kinematicChainName <<
" at can value "
234 <<
mp.second.mp->getCanonicalValue();
237 arm->nonRtConfig.ftConfig.enableSafeGuardForce = forceGuard;
238 arm->nonRtConfig.ftConfig.enableSafeGuardTorque = torqueGuard;
239 arm->controller.ftsensor.enableSafeGuard(resetForce, resetTorque);
243 if (
mp.second.mp->getRole() ==
"taskspace")
245 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
251 arm->rtStatusInNonRT.currentPose,
255 arm->nonRtConfig.safeDistanceMMToGoal,
256 arm->nonRtConfig.safeRotAngleDegreeToGoal,
257 mp.second.mp->getMPName() +
"mp_set_target");
258 arm->nonRtConfig.desiredPose = out->pose;
259 arm->nonRtConfig.desiredTwist = out->vel;
263 else if (
mp.second.mp->getRole() ==
"object")
267 ARMARX_WARNING <<
"when using the object for MP, the coordinator must be first "
274 else if (
mp.second.mp->getRole() ==
"nullspace")
276 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
279 arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
281 else if (
mp.second.mp->getRole() ==
"hand")
284 auto&
hand =
hands->hands.at(
mp.second.mp->getNodeSetName());
287 out->angleRadian.size());
288 hand->targetNonRT.jointPosition.value() = out->angleRadian;
290 if (mpRunning.at(
mp.second.mp->getMPName()) and
mp.second.mp->isFinished())
292 ARMARX_INFO <<
"reset buffer for nonRtConfig of " <<
mp.second.mp->getMPName();
293 for (
auto& pair :
limb)
295 auto& arm = pair.second;
296 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
298 for (
auto& pair :
limb)
300 userConfig.limbs.at(pair.first) = pair.second->nonRtConfig;