98 if (not adaptionReady.load())
102 std::lock_guard<std::recursive_mutex> lock(
mtx_mps);
106 std::map<std::string, bool> flagMPToStop;
108 for (
auto& pair :
limb)
110 flagMPToStop[pair.first] = not
limb.at(pair.first)->controller.ftsensor.ftSafe.load();
111 pair.second->nonRTDeltaT =
112 pair.second->rtStatusInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
114 pair.second->nonRTAccumulateTime = pair.second->rtStatusInNonRT.accumulateTime;
118 for (
auto& pair :
hands->hands)
120 pair.second->nonRTDeltaT =
121 pair.second->rtsInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
122 pair.second->nonRTAccumulateTime = pair.second->rtsInNonRT.accumulateTime;
126 std::map<std::string, bool> mpRunning;
129 const auto mpNodeSet =
mp.second.mp->getNodeSetName();
130 mpRunning[
mp.second.mp->getMPName()] =
mp.second.mp->isRunning();
132 auto search = flagMPToStop.find(mpNodeSet);
133 if (search != flagMPToStop.end() and flagMPToStop.at(mpNodeSet) and
134 mp.second.mp->isRunning() and
135 (
limb.at(mpNodeSet)->controller.ftsensor.isForceGuardEnabled() or
136 limb.at(mpNodeSet)->controller.ftsensor.isTorqueGuardEnabled()))
138 mp.second.mp->stop();
139 ARMARX_INFO <<
"Due to force/torque safe guard, MP " <<
mp.second.mp->getMPName()
140 <<
" is stopped at " <<
mp.second.mp->getCanonicalValue();
143 if (
mp.second.mp->isFinished())
147 if (
mp.second.mp->getRole() ==
"taskspace")
149 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
150 if (
mp.second.mp->isFirstRun())
155 const std::vector<double> mpStart =
mp.second.mp->getStartVec();
157 if (
mp.second.mp->getStartFromPrevTarget() or
159 arm->rtStatusInNonRT.currentPose,
162 "TSMP initial start pose",
163 arm->nonRtConfig.safeDistanceMMToGoal,
164 arm->nonRtConfig.safeRotAngleDegreeToGoal,
165 mp.second.mp->getMPName() +
"mp_set_target"))
167 if (
mp.second.mp->getStartFromPrevTarget())
169 ARMARX_INFO <<
"User requested to start the current TS MP from the "
170 "previous target pose";
175 <<
"deviation from current pose too large, reset MP start pose";
177 mp.second.mp->validateInitialState(
183 in->pose = arm->rtStatusInNonRT.currentPose;
184 in->vel = arm->rtStatusInNonRT.currentTwist;
186 in->deltaT = arm->nonRTDeltaT;
188 else if (
mp.second.mp->getRole() ==
"nullspace")
190 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
193 arm->rtStatusInNonRT.jointPosition.size());
194 in->angleRadian = arm->rtStatusInNonRT.jointPosition;
195 in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
197 in->deltaT = arm->nonRTDeltaT;
199 else if (
mp.second.mp->getRole() ==
"hand")
201 auto&
hand =
hands->hands.at(
mp.second.mp->getNodeSetName());
203 ARMARX_ERROR <<
"Fix the following line, see template.h";
205 hand->nonRTDeltaT =
hand->bufferRTToNonRT.getReadBuffer().accumulateTime -
206 hand->nonRTAccumulateTime;
207 hand->nonRTAccumulateTime =
hand->bufferRTToNonRT.getReadBuffer().accumulateTime;
209 in->deltaT =
hand->nonRTDeltaT;
212 if (not rtTargetSafe)
224 std::lock_guard<std::recursive_mutex> adaptLock(adaptionMtx);
228 if (not mpRunning.at(
mp.second.mp->getMPName()))
232 for (
auto& ftGuard :
mpConfig.ftGuard)
234 if (ftGuard.mpName ==
mp.second.mp->getMPName())
236 bool const forceGuard =
237 (ftGuard.force.has_value() and
238 ftGuard.force.value() >=
mp.second.mp->getCanonicalValue());
239 bool const torqueGuard =
240 (ftGuard.torque.has_value() and
241 ftGuard.torque.value() >=
mp.second.mp->getCanonicalValue());
243 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
244 bool const resetForce =
245 not arm->controller.ftsensor.isForceGuardEnabled() and forceGuard;
246 bool const resetTorque =
247 not arm->controller.ftsensor.isTorqueGuardEnabled() and torqueGuard;
248 if (resetForce or resetTorque)
250 ARMARX_INFO <<
"Triggering force torque safety guard for "
251 << arm->kinematicChainName <<
" at can value "
252 <<
mp.second.mp->getCanonicalValue();
255 arm->nonRtConfig.ftConfig.enableSafeGuardForce = forceGuard;
256 arm->nonRtConfig.ftConfig.enableSafeGuardTorque = torqueGuard;
257 arm->controller.ftsensor.enableSafeGuard(resetForce, resetTorque);
261 if (
mp.second.mp->getRole() ==
"taskspace")
263 auto& nodeSetName =
mp.second.mp->getNodeSetName();
264 auto& cfg = adaptionCfg.cfg.at(nodeSetName);
265 auto& s = adaptionStatus.at(nodeSetName);
266 auto& arm =
limb.at(nodeSetName);
272 arm->rtStatusInNonRT.currentPose,
273 arm->nonRtConfig.desiredPose,
275 "desiredPose for RT",
276 arm->nonRtConfig.safeDistanceMMToGoal,
277 arm->nonRtConfig.safeRotAngleDegreeToGoal,
278 mp.second.mp->getMPName() +
"mp_set_target");
279 arm->nonRtConfig.desiredPose = out->pose;
280 arm->nonRtConfig.desiredTwist = out->vel;
284 cfg.kpf * (cfg.targetForce - arm->rtStatusInNonRT.currentForceTorque(2));
285 arm->nonRtConfig.desiredTwist(2) -= desiredVelZ;
286 arm->nonRtConfig.desiredTwist.tail<3>().setZero();
289 float dT =
static_cast<float>(arm->nonRTDeltaT);
292 auto& adaptKVel = arm->nonRtConfig.kpCartesianVel;
293 if (not cfg.originalKpVel.has_value())
295 cfg.originalKpVel = adaptKVel;
300 Eigen::Vector2f currentForceXY =
301 arm->rtStatusInNonRT.currentForceTorque.head<2>();
302 Eigen::Vector2f dragForce =
303 currentForceXY - cfg.deadZoneForce * currentForceXY / currentForceXY.norm();
304 adaptKVel.head<2>() =
305 (adaptKVel.head<2>().array() - dT * cfg.adaptForceCoeff * dragForce.norm())
311 adaptKVel.head<2>() = (adaptKVel.head<2>().array() + dT * cfg.adaptCoeff)
312 .min(originalKpVel.head<2>().array());
314 adaptKVel(2) = originalKpVel(2);
317 arm->nonRtConfig.desiredPose.block<3, 1>(0, 3) +=
318 dT * arm->nonRtConfig.desiredTwist.head<3>();
323 Eigen::Vector2f currentXY = arm->rtStatusInNonRT.currentPose.block<2, 1>(0, 3);
324 if ((s.lastPosition - currentXY).norm() < cfg.changePositionTolerance)
330 s.lastPosition = currentXY;
334 if (s.changeTimer > cfg.changeTimerThreshold)
336 arm->nonRtConfig.desiredPose.block<2, 1>(0, 3) = currentXY;
346 else if (
mp.second.mp->getRole() ==
"nullspace")
348 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
351 arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
353 else if (
mp.second.mp->getRole() ==
"hand")
356 auto&
hand =
hands->hands.at(
mp.second.mp->getNodeSetName());
359 out->angleRadian.size());
360 hand->targetNonRT.jointPosition.value() = out->angleRadian;
362 if (mpRunning.at(
mp.second.mp->getMPName()) and
mp.second.mp->isFinished())
364 ARMARX_INFO <<
"reset buffer for nonRtConfig of " <<
mp.second.mp->getMPName();
365 for (
auto& pair :
limb)
367 auto& arm = pair.second;
368 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
370 for (
auto& pair :
limb)
372 userConfig.limbs.at(pair.first) = pair.second->nonRtConfig;