31 NJointControllerRegistration<NJointTSImpedanceMPController>
36 const NJointControllerConfigPtr& config,
46 return "NJointTSImpedanceMPController";
51 const Ice::Current& iceCurrent)
55 for (
auto& pair :
limb)
57 pair.second->rtFirstRun.store(
true);
65 std::lock_guard<std::recursive_mutex> lock(
mtx_mps);
69 std::map<std::string, bool> flagMPToStop;
70 for (
auto& pair :
limb)
72 flagMPToStop[pair.first] = not
limb.at(pair.first)->controller.ftsensor.ftSafe.load();
73 pair.second->nonRTDeltaT =
74 pair.second->rtStatusInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
75 pair.second->nonRTAccumulateTime = pair.second->rtStatusInNonRT.accumulateTime;
79 for (
auto& pair :
hands->hands)
81 pair.second->nonRTDeltaT =
82 pair.second->rtsInNonRT.accumulateTime - pair.second->nonRTAccumulateTime;
83 pair.second->nonRTAccumulateTime = pair.second->rtsInNonRT.accumulateTime;
87 std::map<std::string, bool> mpRunning;
90 const auto mpNodeSet = _mp.second.mp->getNodeSetName();
91 mpRunning[_mp.second.mp->getMPName()] = _mp.second.mp->isRunning();
93 auto search = flagMPToStop.find(mpNodeSet);
94 if (search != flagMPToStop.end() and flagMPToStop.at(mpNodeSet) and
95 _mp.second.mp->isRunning() and
96 (
limb.at(mpNodeSet)->controller.ftsensor.isForceGuardEnabled() or
97 limb.at(mpNodeSet)->controller.ftsensor.isTorqueGuardEnabled()))
99 _mp.second.mp->stop();
100 ARMARX_INFO <<
"Due to force/torque safe guard, MP " << _mp.second.mp->getMPName()
101 <<
" is stopped at " << _mp.second.mp->getCanonicalValue();
104 if (_mp.second.mp->isFinished())
108 if (_mp.second.mp->getRole() ==
"taskspace")
110 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
111 if (_mp.second.mp->isFirstRun())
116 const std::vector<double> mpStart = _mp.second.mp->getStartVec();
118 if (_mp.second.mp->getStartFromPrevTarget() or
120 arm->rtStatusInNonRT.currentPose,
123 "TSMP initial start pose",
124 arm->nonRtConfig.safeDistanceMMToGoal,
125 arm->nonRtConfig.safeRotAngleDegreeToGoal,
126 _mp.second.mp->getMPName() +
"mp_set_target"))
128 if (_mp.second.mp->getStartFromPrevTarget())
130 ARMARX_INFO <<
"User requested to start the current TS MP from the "
131 "previous target pose";
136 <<
"deviation from current pose too large, reset MP start pose";
138 _mp.second.mp->validateInitialState(
143 mp::TSMPInputPtr in = std::dynamic_pointer_cast<mp::TSMPInput>(_mp.second.input);
144 in->pose = arm->rtStatusInNonRT.currentPose;
145 in->vel = arm->rtStatusInNonRT.currentTwist;
147 in->deltaT = arm->nonRTDeltaT;
149 else if (_mp.second.mp->getRole() ==
"nullspace")
151 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
152 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
154 arm->rtStatusInNonRT.jointPos.size());
155 in->angleRadian = arm->rtStatusInNonRT.jointPos;
156 in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
157 in->deltaT = arm->nonRTDeltaT;
159 else if (_mp.second.mp->getRole() ==
"hand")
161 auto&
hand =
hands->hands.at(_mp.second.mp->getNodeSetName());
162 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
163 in->angleRadian =
hand->rtsInNonRT.jointPosition.value();
164 in->deltaT =
hand->nonRTDeltaT;
180 for (
auto& _mp :
mps)
182 if (not mpRunning.at(_mp.second.mp->getMPName()))
186 for (
auto& ftGuard :
mpConfig.ftGuard)
188 if (ftGuard.mpName == _mp.second.mp->getMPName())
190 bool const forceGuard =
191 (ftGuard.force.has_value() and
192 ftGuard.force.value() >= _mp.second.mp->getCanonicalValue());
193 bool const torqueGuard =
194 (ftGuard.torque.has_value() and
195 ftGuard.torque.value() >= _mp.second.mp->getCanonicalValue());
197 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
198 bool const resetForce =
199 not arm->controller.ftsensor.isForceGuardEnabled() and forceGuard;
200 bool const resetTorque =
201 not arm->controller.ftsensor.isTorqueGuardEnabled() and torqueGuard;
202 if (resetForce or resetTorque)
204 ARMARX_INFO <<
"Triggering force torque safety guard for "
205 << arm->kinematicChainName <<
" at can value "
206 << _mp.second.mp->getCanonicalValue();
209 arm->nonRtConfig.ftConfig.enableSafeGuardForce = forceGuard;
210 arm->nonRtConfig.ftConfig.enableSafeGuardTorque = torqueGuard;
211 arm->controller.ftsensor.enableSafeGuard(resetForce, resetTorque);
215 if (_mp.second.mp->getRole() ==
"taskspace")
217 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
219 std::dynamic_pointer_cast<mp::TSMPOutput>(_mp.second.output);
224 arm->rtStatusInNonRT.currentPose,
228 arm->nonRtConfig.safeDistanceMMToGoal,
229 arm->nonRtConfig.safeRotAngleDegreeToGoal,
230 _mp.second.mp->getMPName() +
"mp_set_target");
231 arm->nonRtConfig.desiredPose = out->pose;
232 arm->nonRtConfig.desiredTwist = out->vel;
234 else if (_mp.second.mp->getRole() ==
"nullspace")
236 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
238 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
240 arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
242 else if (_mp.second.mp->getRole() ==
"hand")
245 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
246 auto&
hand =
hands->hands.at(_mp.second.mp->getNodeSetName());
247 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
249 out->angleRadian.size());
250 hand->targetNonRT.jointPosition.value() = out->angleRadian;
252 if (mpRunning.at(_mp.second.mp->getMPName()) and _mp.second.mp->isFinished())
254 ARMARX_INFO <<
"reset buffer for nonRtConfig of " << _mp.second.mp->getMPName();
255 for (
auto& pair :
limb)
257 auto& arm = pair.second;
258 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
260 for (
auto& pair :
limb)
262 userConfig.limbs.at(pair.first) = pair.second->nonRtConfig;