31 NJointControllerRegistration<NJointTSCollisionAvoidanceImpedanceMPController>
33 "NJointTSCollisionAvoidanceImpedanceMPController");
37 const NJointControllerConfigPtr& config,
48 return "NJointTSCollisionAvoidanceImpedanceMPController";
54 const Ice::Current& iceCurrent)
58 for (
auto& pair :
limb)
60 pair.second->rtFirstRun.store(
true);
68 std::lock_guard<std::recursive_mutex> lock(
mtx_mps);
72 std::map<std::string, bool> flagMPToStop;
73 for (
auto& pair :
limb)
75 flagMPToStop[pair.first] = not
limb.at(pair.first)->controller.ftsensor.ftSafe.load();
76 pair.second->nonRTDeltaT =
77 pair.second->rtStatusInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
78 pair.second->nonRTAccumulateTime = pair.second->rtStatusInNonRT.accumulateTime;
82 for (
auto& pair :
hands->hands)
84 pair.second->nonRTDeltaT =
85 pair.second->rtsInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
86 pair.second->nonRTAccumulateTime = pair.second->rtsInNonRT.accumulateTime;
90 std::map<std::string, bool> mpRunning;
93 const auto mpNodeSet = _mp.second.mp->getNodeSetName();
94 mpRunning[_mp.second.mp->getMPName()] = _mp.second.mp->isRunning();
96 auto search = flagMPToStop.find(mpNodeSet);
97 if (search != flagMPToStop.end() and flagMPToStop.at(mpNodeSet) and
98 _mp.second.mp->isRunning() and
99 (
limb.at(mpNodeSet)->controller.ftsensor.isForceGuardEnabled() or
100 limb.at(mpNodeSet)->controller.ftsensor.isTorqueGuardEnabled()))
102 _mp.second.mp->stop();
103 ARMARX_INFO <<
"Due to force/torque safe guard, MP " << _mp.second.mp->getMPName()
104 <<
" is stopped at " << _mp.second.mp->getCanonicalValue();
107 if (_mp.second.mp->isFinished())
111 if (_mp.second.mp->getRole() ==
"taskspace")
113 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
114 if (_mp.second.mp->isFirstRun())
119 const std::vector<double> mpStart = _mp.second.mp->getStartVec();
121 if (_mp.second.mp->getStartFromPrevTarget() or
123 arm->rtStatusInNonRT.currentPose,
126 "TSMP initial start pose",
127 arm->nonRtConfig.safeDistanceMMToGoal,
128 arm->nonRtConfig.safeRotAngleDegreeToGoal,
129 _mp.second.mp->getMPName() +
"mp_set_target"))
131 if (_mp.second.mp->getStartFromPrevTarget())
133 ARMARX_INFO <<
"User requested to start the current TS MP from the "
134 "previous target pose";
139 <<
"deviation from current pose too large, reset MP start pose";
141 _mp.second.mp->validateInitialState(
146 mp::TSMPInputPtr in = std::dynamic_pointer_cast<mp::TSMPInput>(_mp.second.input);
147 in->pose = arm->rtStatusInNonRT.currentPose;
148 in->vel = arm->rtStatusInNonRT.currentTwist;
150 in->deltaT = arm->nonRTDeltaT;
152 else if (_mp.second.mp->getRole() ==
"nullspace")
154 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
155 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
157 arm->rtStatusInNonRT.jointPos.size());
158 in->angleRadian = arm->rtStatusInNonRT.jointPos;
159 in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
160 in->deltaT = arm->nonRTDeltaT;
162 else if (_mp.second.mp->getRole() ==
"hand")
164 auto&
hand =
hands->hands.at(_mp.second.mp->getNodeSetName());
165 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
166 in->angleRadian =
hand->rtsInNonRT.jointPosition.value();
167 in->deltaT =
hand->nonRTDeltaT;
183 for (
auto& _mp :
mps)
185 if (not mpRunning.at(_mp.second.mp->getMPName()))
189 for (
auto& ftGuard :
mpConfig.ftGuard)
191 if (ftGuard.mpName == _mp.second.mp->getMPName())
193 bool const forceGuard =
194 (ftGuard.force.has_value() and
195 ftGuard.force.value() >= _mp.second.mp->getCanonicalValue());
196 bool const torqueGuard =
197 (ftGuard.torque.has_value() and
198 ftGuard.torque.value() >= _mp.second.mp->getCanonicalValue());
200 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
201 bool const resetForce =
202 not arm->controller.ftsensor.isForceGuardEnabled() and forceGuard;
203 bool const resetTorque =
204 not arm->controller.ftsensor.isTorqueGuardEnabled() and torqueGuard;
205 if (resetForce or resetTorque)
207 ARMARX_INFO <<
"Triggering force torque safety guard for "
208 << arm->kinematicChainName <<
" at can value "
209 << _mp.second.mp->getCanonicalValue();
212 arm->nonRtConfig.ftConfig.enableSafeGuardForce = forceGuard;
213 arm->nonRtConfig.ftConfig.enableSafeGuardTorque = torqueGuard;
214 arm->controller.ftsensor.enableSafeGuard(resetForce, resetTorque);
218 if (_mp.second.mp->getRole() ==
"taskspace")
220 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
222 std::dynamic_pointer_cast<mp::TSMPOutput>(_mp.second.output);
227 arm->rtStatusInNonRT.currentPose,
231 arm->nonRtConfig.safeDistanceMMToGoal,
232 arm->nonRtConfig.safeRotAngleDegreeToGoal,
233 _mp.second.mp->getMPName() +
"mp_set_target");
234 arm->nonRtConfig.desiredPose = out->pose;
235 arm->nonRtConfig.desiredTwist = out->vel;
237 else if (_mp.second.mp->getRole() ==
"nullspace")
239 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
241 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
243 arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
245 else if (_mp.second.mp->getRole() ==
"hand")
248 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
249 auto&
hand =
hands->hands.at(_mp.second.mp->getNodeSetName());
250 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
252 out->angleRadian.size());
253 hand->targetNonRT.jointPosition.value() = out->angleRadian;
255 if (mpRunning.at(_mp.second.mp->getMPName()) and _mp.second.mp->isFinished())
257 ARMARX_INFO <<
"reset buffer for nonRtConfig of " << _mp.second.mp->getMPName();
258 for (
auto& pair :
limb)
260 auto& arm = pair.second;
261 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
263 for (
auto& pair :
limb)
265 userConfig.limbs.at(pair.first) = pair.second->nonRtConfig;