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();
100 bool forceGuardEnabled =
false;
101 bool torqueGuardEnabled =
false;
102 for (
auto& ftGuard :
mpConfig.ftGuard)
104 if (ftGuard.mpName ==
mp.second.mp->getMPName())
107 (ftGuard.force.has_value() and
108 ftGuard.force.value() >=
mp.second.mp->getCanonicalValue());
110 (ftGuard.torque.has_value() and
111 ftGuard.torque.value() >=
mp.second.mp->getCanonicalValue());
116 auto search = flagMPToStop.find(mpNodeSet);
117 if (search != flagMPToStop.end() and flagMPToStop.at(mpNodeSet) and
118 mp.second.mp->isRunning() and not
mp.second.mp->isFirstRun() and
119 ((forceGuardEnabled and
120 limb.at(mpNodeSet)->controller.ftsensor.isForceGuardEnabled()) or
121 (torqueGuardEnabled and
122 limb.at(mpNodeSet)->controller.ftsensor.isTorqueGuardEnabled())))
124 mp.second.mp->stop();
125 ARMARX_INFO <<
"Due to force/torque safe guard, MP " <<
mp.second.mp->getMPName()
126 <<
" is stopped at " <<
mp.second.mp->getCanonicalValue();
129 if (
mp.second.mp->isFinished())
133 if (
mp.second.mp->getRole() ==
"taskspace")
135 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
136 if (
mp.second.mp->isFirstRun())
141 const std::vector<double> mpStart =
mp.second.mp->getStartVec();
143 if (
mp.second.mp->getStartFromPrevTarget() or
145 arm->rtStatusInNonRT.currentPose,
148 "TSMP initial start pose",
149 arm->nonRtConfig.safeDistanceMMToGoal,
150 arm->nonRtConfig.safeRotAngleDegreeToGoal,
151 mp.second.mp->getMPName() +
"mp_set_target"))
153 if (
mp.second.mp->getStartFromPrevTarget())
155 ARMARX_INFO <<
"User requested to start the current TS MP from the "
156 "previous target pose";
161 <<
"deviation from current pose too large, reset MP start pose";
163 mp.second.mp->validateInitialState(
169 in->pose = arm->rtStatusInNonRT.currentPose;
170 in->vel = arm->rtStatusInNonRT.currentTwist;
172 in->deltaT = arm->nonRTDeltaT;
174 else if (
mp.second.mp->getRole() ==
"nullspace")
176 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
179 arm->rtStatusInNonRT.jointPosition.size());
180 in->angleRadian = arm->rtStatusInNonRT.jointPosition;
181 in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
182 in->deltaT = arm->nonRTDeltaT;
184 else if (
mp.second.mp->getRole() ==
"hand")
186 auto&
hand =
hands->hands.at(
mp.second.mp->getNodeSetName());
189 in->deltaT =
hand->nonRTDeltaT;
191 else if (
mp.second.mp->getRole() ==
"object")
195 ARMARX_WARNING <<
"when using the object for MP, the coordinator must be first "
205 const std::scoped_lock lock_vo_non_rt(
coordinator->mtx_data_non_rt);
212 if (not rtTargetSafe)
227 if (not mpRunning.at(
mp.second.mp->getMPName()))
231 for (
auto& ftGuard :
mpConfig.ftGuard)
233 if (ftGuard.mpName ==
mp.second.mp->getMPName())
235 bool const forceGuard =
236 (ftGuard.force.has_value() and
237 ftGuard.force.value() >=
mp.second.mp->getCanonicalValue());
238 bool const torqueGuard =
239 (ftGuard.torque.has_value() and
240 ftGuard.torque.value() >=
mp.second.mp->getCanonicalValue());
242 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
243 bool const resetForce =
244 not arm->controller.ftsensor.isForceGuardEnabled() and forceGuard;
245 bool const resetTorque =
246 not arm->controller.ftsensor.isTorqueGuardEnabled() and torqueGuard;
247 if (resetForce or resetTorque)
249 ARMARX_INFO <<
"Triggering force torque safety guard for "
250 << arm->kinematicChainName <<
" at can value "
251 <<
mp.second.mp->getCanonicalValue();
254 arm->nonRtConfig.ftConfig.enableSafeGuardForce = forceGuard;
255 arm->nonRtConfig.ftConfig.enableSafeGuardTorque = torqueGuard;
256 arm->controller.ftsensor.enableSafeGuard(resetForce, resetTorque);
260 if (
mp.second.mp->getRole() ==
"taskspace")
262 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
268 arm->rtStatusInNonRT.currentPose,
272 arm->nonRtConfig.safeDistanceMMToGoal,
273 arm->nonRtConfig.safeRotAngleDegreeToGoal,
274 mp.second.mp->getMPName() +
"mp_set_target");
275 arm->nonRtConfig.desiredPose = out->pose;
276 arm->nonRtConfig.desiredTwist = out->vel;
278 else if (
mp.second.mp->getRole() ==
"object")
282 ARMARX_WARNING <<
"when using the object for MP, the coordinator must be first "
289 else if (
mp.second.mp->getRole() ==
"nullspace")
291 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
294 arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
296 else if (
mp.second.mp->getRole() ==
"hand")
299 auto&
hand =
hands->hands.at(
mp.second.mp->getNodeSetName());
302 out->angleRadian.size());
303 hand->targetNonRT.jointPosition.value() = out->angleRadian;
305 if (mpRunning.at(
mp.second.mp->getMPName()) and
mp.second.mp->isFinished())
307 ARMARX_INFO <<
"reset buffer for nonRtConfig of " <<
mp.second.mp->getMPName();
308 for (
auto& pair :
limb)
310 auto& arm = pair.second;
311 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
313 for (
auto& pair :
limb)
315 userConfig.limbs.at(pair.first) = pair.second->nonRtConfig;