101 if (not adaptionReady.load())
105 const std::lock_guard<std::recursive_mutex> lock(
mtx_mps);
109 std::map<std::string, bool> flagMPToStop;
111 for (
auto& pair :
limb)
113 flagMPToStop[pair.first] = not
limb.at(pair.first)->controller.ftsensor.ftSafe.load();
114 pair.second->nonRTDeltaT =
115 pair.second->rtStatusInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
117 pair.second->nonRTAccumulateTime = pair.second->rtStatusInNonRT.accumulateTime;
121 for (
auto& pair :
hands->hands)
123 pair.second->nonRTDeltaT =
124 pair.second->rtsInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
125 pair.second->nonRTAccumulateTime = pair.second->rtsInNonRT.accumulateTime;
129 std::map<std::string, bool> mpRunning;
132 const auto mpNodeSet =
mp.second.mp->getNodeSetName();
133 mpRunning[
mp.second.mp->getMPName()] =
mp.second.mp->isRunning();
135 auto search = flagMPToStop.find(mpNodeSet);
136 if (search != flagMPToStop.end() and flagMPToStop.at(mpNodeSet) and
137 mp.second.mp->isRunning() and
138 (
limb.at(mpNodeSet)->controller.ftsensor.isForceGuardEnabled() or
139 limb.at(mpNodeSet)->controller.ftsensor.isTorqueGuardEnabled()))
141 mp.second.mp->stop();
142 ARMARX_INFO <<
"Due to force/torque safe guard, MP " <<
mp.second.mp->getMPName()
143 <<
" is stopped at " <<
mp.second.mp->getCanonicalValue();
146 if (
mp.second.mp->isFinished())
150 if (
mp.second.mp->getRole() ==
"taskspace")
152 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
153 if (
mp.second.mp->isFirstRun())
158 const std::vector<double> mpStart =
mp.second.mp->getStartVec();
160 if (
mp.second.mp->getStartFromPrevTarget() or
162 arm->rtStatusInNonRT.currentPose,
165 "TSMP initial start pose",
166 arm->nonRtConfig.safeDistanceMMToGoal,
167 arm->nonRtConfig.safeRotAngleDegreeToGoal,
168 mp.second.mp->getMPName() +
"mp_set_target"))
170 if (
mp.second.mp->getStartFromPrevTarget())
172 ARMARX_INFO <<
"User requested to start the current TS MP from the "
173 "previous target pose";
178 <<
"deviation from current pose too large, reset MP start pose";
180 mp.second.mp->validateInitialState(
186 in->pose = arm->rtStatusInNonRT.currentPose;
187 in->vel = arm->rtStatusInNonRT.currentTwist;
189 in->deltaT = arm->nonRTDeltaT;
191 else if (
mp.second.mp->getRole() ==
"nullspace")
193 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
196 arm->rtStatusInNonRT.jointPosition.size());
197 in->angleRadian = arm->rtStatusInNonRT.jointPosition;
198 in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
200 in->deltaT = arm->nonRTDeltaT;
202 else if (
mp.second.mp->getRole() ==
"hand")
204 auto&
hand =
hands->hands.at(
mp.second.mp->getNodeSetName());
207 <<
"Fix the following line, see new controller implement in template.h";
209 hand->nonRTDeltaT =
hand->bufferRTToNonRT.getReadBuffer().accumulateTime -
210 hand->nonRTAccumulateTime;
211 hand->nonRTAccumulateTime =
hand->bufferRTToNonRT.getReadBuffer().accumulateTime;
213 in->deltaT =
hand->nonRTDeltaT;
216 if (not rtTargetSafe)
229 std::lock_guard<std::recursive_mutex> adaptLock(adaptionMtx);
233 if (not mpRunning.at(
mp.second.mp->getMPName()))
237 for (
auto& ftGuard :
mpConfig.ftGuard)
239 if (ftGuard.mpName ==
mp.second.mp->getMPName())
241 bool const forceGuard =
242 (ftGuard.force.has_value() and
243 ftGuard.force.value() >=
mp.second.mp->getCanonicalValue());
244 bool const torqueGuard =
245 (ftGuard.torque.has_value() and
246 ftGuard.torque.value() >=
mp.second.mp->getCanonicalValue());
248 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
249 bool const resetForce =
250 not arm->controller.ftsensor.isForceGuardEnabled() and forceGuard;
251 bool const resetTorque =
252 not arm->controller.ftsensor.isTorqueGuardEnabled() and torqueGuard;
253 if (resetForce or resetTorque)
255 ARMARX_INFO <<
"Triggering force torque safety guard for "
256 << arm->kinematicChainName <<
" at can value "
257 <<
mp.second.mp->getCanonicalValue();
260 arm->nonRtConfig.ftConfig.enableSafeGuardForce = forceGuard;
261 arm->nonRtConfig.ftConfig.enableSafeGuardTorque = torqueGuard;
262 arm->controller.ftsensor.enableSafeGuard(resetForce, resetTorque);
266 if (
mp.second.mp->getRole() ==
"taskspace")
268 auto& nodeSetName =
mp.second.mp->getNodeSetName();
269 auto& cfg = adaptionCfg.cfg.at(nodeSetName);
270 auto& s = adaptionStatus.at(nodeSetName);
271 auto& arm =
limb.at(nodeSetName);
277 arm->rtStatusInNonRT.currentPose,
278 arm->nonRtConfig.desiredPose,
280 "desiredPose for RT",
281 arm->nonRtConfig.safeDistanceMMToGoal,
282 arm->nonRtConfig.safeRotAngleDegreeToGoal,
283 mp.second.mp->getMPName() +
"mp_set_target");
284 arm->nonRtConfig.desiredPose = out->pose;
285 arm->nonRtConfig.desiredTwist = out->vel;
289 cfg.kpf * (cfg.targetForce - arm->rtStatusInNonRT.currentForceTorque(2));
290 arm->nonRtConfig.desiredTwist(2) -= desiredVelZ;
291 arm->nonRtConfig.desiredTwist.tail<3>().setZero();
294 float dT =
static_cast<float>(arm->nonRTDeltaT);
297 auto& adaptKImp = arm->nonRtConfig.kpImpedance;
298 if (not cfg.originalKpImp.has_value())
300 cfg.originalKpImp = adaptKImp;
305 Eigen::Vector2f currentForceXY =
306 arm->rtStatusInNonRT.currentForceTorque.head<2>();
307 Eigen::Vector2f dragForce =
308 currentForceXY - cfg.deadZoneForce * currentForceXY / currentForceXY.norm();
309 adaptKImp.head<2>() =
310 (adaptKImp.head<2>().array() - dT * cfg.adaptForceCoeff * dragForce.norm())
316 adaptKImp.head<2>() = (adaptKImp.head<2>().array() + dT * cfg.adaptCoeff)
317 .min(originalKpImp.head<2>().array());
319 adaptKImp(2) = originalKpImp(2);
322 arm->nonRtConfig.desiredPose.block<3, 1>(0, 3) +=
323 dT * arm->nonRtConfig.desiredTwist.head<3>();
328 Eigen::Vector2f currentXY = arm->rtStatusInNonRT.currentPose.block<2, 1>(0, 3);
329 if ((s.lastPosition - currentXY).norm() < cfg.changePositionTolerance)
335 s.lastPosition = currentXY;
339 if (s.changeTimer > cfg.changeTimerThreshold)
341 arm->nonRtConfig.desiredPose.block<2, 1>(0, 3) = currentXY;
351 else if (
mp.second.mp->getRole() ==
"nullspace")
353 auto& arm =
limb.at(
mp.second.mp->getNodeSetName());
356 arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
358 else if (
mp.second.mp->getRole() ==
"hand")
361 auto&
hand =
hands->hands.at(
mp.second.mp->getNodeSetName());
364 out->angleRadian.size());
365 hand->targetNonRT.jointPosition.value() = out->angleRadian;
367 if (mpRunning.at(
mp.second.mp->getMPName()) and
mp.second.mp->isFinished())
369 ARMARX_INFO <<
"reset buffer for nonRtConfig of " <<
mp.second.mp->getMPName();
370 for (
auto& pair :
limb)
372 auto& arm = pair.second;
373 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
375 for (
auto& pair :
limb)
377 userConfig.limbs.at(pair.first) = pair.second->nonRtConfig;