31 NJointControllerRegistration<NJointTSCollisionAvoidanceMixedImpedanceVelocityMPController>
33 "NJointTSCollisionAvoidanceMixedImpedanceVelocityMPController");
38 const NJointControllerConfigPtr& config,
48 const Ice::Current&)
const
50 return "NJointTSCollisionAvoidanceMixedImpedanceVelocityMPController";
56 const Ice::Current& iceCurrent)
60 for (
auto& pair :
limb)
62 pair.second->rtFirstRun.store(
true);
70 std::lock_guard<std::recursive_mutex> lock(
mtx_mps);
74 std::map<std::string, bool> flagMPToStop;
75 for (
auto& pair :
limb)
77 flagMPToStop[pair.first] = not
limb.at(pair.first)->controller.ftsensor.ftSafe.load();
78 pair.second->nonRTDeltaT =
79 pair.second->rtStatusInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
80 pair.second->nonRTAccumulateTime = pair.second->rtStatusInNonRT.accumulateTime;
84 for (
auto& pair :
hands->hands)
86 pair.second->nonRTDeltaT =
87 pair.second->rtsInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
88 pair.second->nonRTAccumulateTime = pair.second->rtsInNonRT.accumulateTime;
92 std::map<std::string, bool> mpRunning;
95 const auto mpNodeSet = _mp.second.mp->getNodeSetName();
96 mpRunning[_mp.second.mp->getMPName()] = _mp.second.mp->isRunning();
98 auto search = flagMPToStop.find(mpNodeSet);
99 if (search != flagMPToStop.end() and flagMPToStop.at(mpNodeSet) and
100 _mp.second.mp->isRunning() and
101 (
limb.at(mpNodeSet)->controller.ftsensor.isForceGuardEnabled() or
102 limb.at(mpNodeSet)->controller.ftsensor.isTorqueGuardEnabled()))
104 _mp.second.mp->stop();
105 auto& force =
limb.at(mpNodeSet)->rtStatusInNonRT.currentForceTorque;
106 ARMARX_INFO <<
"Due to force/torque safe guard, MP " << _mp.second.mp->getMPName()
107 <<
" is stopped at " << _mp.second.mp->getCanonicalValue()
108 <<
" with current ft: " << force;
111 if (_mp.second.mp->isFinished())
115 if (_mp.second.mp->getRole() ==
"taskspace")
117 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
118 if (_mp.second.mp->isFirstRun())
123 const std::vector<double> mpStart = _mp.second.mp->getStartVec();
125 if (_mp.second.mp->getStartFromPrevTarget() or
127 arm->rtStatusInNonRT.currentPose,
130 "TSMP initial start pose",
131 arm->nonRtConfig.safeDistanceMMToGoal,
132 arm->nonRtConfig.safeRotAngleDegreeToGoal,
133 _mp.second.mp->getMPName() +
"mp_set_target"))
135 if (_mp.second.mp->getStartFromPrevTarget())
137 ARMARX_INFO <<
"User requested to start the current TS MP from the "
138 "previous target pose";
143 <<
"deviation from current pose too large, reset MP start pose";
145 _mp.second.mp->validateInitialState(
150 mp::TSMPInputPtr in = std::dynamic_pointer_cast<mp::TSMPInput>(_mp.second.input);
151 in->pose = arm->rtStatusInNonRT.currentPose;
152 in->vel = arm->rtStatusInNonRT.currentTwist;
154 in->deltaT = arm->nonRTDeltaT;
156 else if (_mp.second.mp->getRole() ==
"nullspace")
158 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
159 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
161 arm->rtStatusInNonRT.jointPos.size());
162 in->angleRadian = arm->rtStatusInNonRT.jointPos;
163 in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
164 in->deltaT = arm->nonRTDeltaT;
166 else if (_mp.second.mp->getRole() ==
"hand")
168 auto&
hand =
hands->hands.at(_mp.second.mp->getNodeSetName());
169 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
170 in->angleRadian =
hand->rtsInNonRT.jointPosition.value();
171 in->deltaT =
hand->nonRTDeltaT;
187 for (
auto& _mp :
mps)
189 if (not mpRunning.at(_mp.second.mp->getMPName()))
193 for (
auto& ftGuard :
mpConfig.ftGuard)
195 if (ftGuard.mpName == _mp.second.mp->getMPName())
197 bool const forceGuard =
198 (ftGuard.force.has_value() and
199 ftGuard.force.value() >= _mp.second.mp->getCanonicalValue());
200 bool const torqueGuard =
201 (ftGuard.torque.has_value() and
202 ftGuard.torque.value() >= _mp.second.mp->getCanonicalValue());
204 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
205 bool const resetForce =
206 not arm->controller.ftsensor.isForceGuardEnabled() and forceGuard;
207 bool const resetTorque =
208 not arm->controller.ftsensor.isTorqueGuardEnabled() and torqueGuard;
209 if (resetForce or resetTorque)
211 ARMARX_INFO <<
"Triggering force torque safety guard for "
212 << arm->kinematicChainName <<
" at can value "
213 << _mp.second.mp->getCanonicalValue();
216 arm->nonRtConfig.ftConfig.enableSafeGuardForce = forceGuard;
217 arm->nonRtConfig.ftConfig.enableSafeGuardTorque = torqueGuard;
218 arm->controller.ftsensor.enableSafeGuard(resetForce, resetTorque);
222 if (_mp.second.mp->getRole() ==
"taskspace")
224 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
226 std::dynamic_pointer_cast<mp::TSMPOutput>(_mp.second.output);
231 arm->rtStatusInNonRT.currentPose,
235 arm->nonRtConfig.safeDistanceMMToGoal,
236 arm->nonRtConfig.safeRotAngleDegreeToGoal,
237 _mp.second.mp->getMPName() +
"mp_set_target");
238 arm->nonRtConfig.desiredPose = out->pose;
239 arm->nonRtConfig.desiredTwist = out->vel;
241 else if (_mp.second.mp->getRole() ==
"nullspace")
243 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
245 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
247 arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
249 else if (_mp.second.mp->getRole() ==
"hand")
252 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
253 auto&
hand =
hands->hands.at(_mp.second.mp->getNodeSetName());
254 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
256 out->angleRadian.size());
257 hand->targetNonRT.jointPosition.value() = out->angleRadian;
259 if (mpRunning.at(_mp.second.mp->getMPName()) and _mp.second.mp->isFinished())
261 ARMARX_INFO <<
"reset buffer for nonRtConfig of " << _mp.second.mp->getMPName();
262 for (
auto& pair :
limb)
264 auto& arm = pair.second;
265 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
267 for (
auto& pair :
limb)
269 userConfig.limbs.at(pair.first) = pair.second->nonRtConfig;