32 const RobotUnitPtr& robotUnit,
33 const NJointControllerConfigPtr& config,
43 return "NJointTSAdmittanceMPController";
48 const Ice::Current& iceCurrent)
52 for (
auto& pair :
limb)
54 pair.second->rtFirstRun.store(
true);
62 std::lock_guard<std::recursive_mutex> lock(
mtx_mps);
65 std::map<std::string, bool> mpRunning;
68 mpRunning[_mp.second.mp->getMPName()] = _mp.second.mp->isRunning();
69 if (_mp.second.mp->isFinished())
73 if (_mp.second.mp->getRole() ==
"taskspace")
75 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
76 if (_mp.second.mp->isFirstRun())
78 _mp.second.mp->validateInitialState(
common::mat4ToDVec(arm->rtStatusInNonRT.currentPose));
80 mp::TSMPInputPtr in = std::dynamic_pointer_cast<mp::TSMPInput>(_mp.second.input);
81 in->pose = arm->rtStatusInNonRT.currentPose;
82 in->vel = arm->rtStatusInNonRT.currentTwist;
83 in->deltaT = arm->rtStatusInNonRT.deltaT;
85 else if (_mp.second.mp->getRole() ==
"nullspace")
87 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
88 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
90 arm->rtStatusInNonRT.jointPos.size());
91 in->angleRadian = arm->rtStatusInNonRT.jointPos;
92 in->angularVel = arm->rtStatusInNonRT.qvelFiltered;
93 in->deltaT = arm->rtStatusInNonRT.deltaT;
95 else if (_mp.second.mp->getRole() ==
"hand")
97 auto&
hand =
hands->hands.at(_mp.second.mp->getNodeSetName());
98 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
100 hand->bufferRTToNonRT.getUpToDateReadBuffer().jointPosition.value();
101 in->deltaT =
hand->bufferRTToNonRT.getReadBuffer().deltaT;
117 for (
auto& _mp :
mps)
119 if (not mpRunning.at(_mp.second.mp->getMPName()))
123 for (
auto& ftGuard :
mpConfig.ftGuard)
125 if (ftGuard.mpName == _mp.second.mp->getMPName())
127 bool const forceGuard =
128 (ftGuard.force.has_value() and
129 ftGuard.force.value() >= _mp.second.mp->getCanonicalValue());
130 bool const torqueGuard =
131 (ftGuard.torque.has_value() and
132 ftGuard.torque.value() >= _mp.second.mp->getCanonicalValue());
134 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
135 bool const resetForce =
136 not arm->nonRtConfig.ftConfig.enableSafeGuardForce and forceGuard;
137 bool const resetTorque =
138 not arm->nonRtConfig.ftConfig.enableSafeGuardTorque and torqueGuard;
139 if (resetForce or resetTorque)
141 ARMARX_INFO <<
"Triggering force torque safety guard for "
142 << arm->kinematicChainName <<
" at can value "
143 << _mp.second.mp->getCanonicalValue();
146 arm->nonRtConfig.ftConfig.enableSafeGuardForce = forceGuard;
147 arm->nonRtConfig.ftConfig.enableSafeGuardTorque = torqueGuard;
148 arm->controller.ftsensor.enableSafeGuard(resetForce, resetTorque);
152 if (_mp.second.mp->getRole() ==
"taskspace")
154 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
156 std::dynamic_pointer_cast<mp::TSMPOutput>(_mp.second.output);
162 "current pose",
"TSMP pose",
163 arm->nonRtConfig.safeDistanceMMToGoal,
164 arm->nonRtConfig.safeRotAngleDegreeToGoal,
165 _mp.second.mp->getMPName() +
"mp_set_target");
166 arm->nonRtConfig.desiredPose = out->pose;
167 arm->nonRtConfig.desiredTwist = out->vel;
169 else if (_mp.second.mp->getRole() ==
"nullspace")
171 auto& arm =
limb.at(_mp.second.mp->getNodeSetName());
173 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
175 arm->nonRtConfig.desiredNullspaceJointAngles.value() = out->angleRadian;
177 else if (_mp.second.mp->getRole() ==
"hand")
180 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.second.output);
181 auto&
hand =
hands->hands.at(_mp.second.mp->getNodeSetName());
182 mp::JSMPInputPtr in = std::dynamic_pointer_cast<mp::JSMPInput>(_mp.second.input);
184 out->angleRadian.size());
185 hand->targetNonRT.jointPosition.value() = out->angleRadian;
187 if (mpRunning.at(_mp.second.mp->getMPName()) and _mp.second.mp->isFinished())
189 ARMARX_INFO <<
"reset buffer for nonRtConfig of " << _mp.second.mp->getMPName();
190 for (
auto& pair :
limb)
192 auto& arm = pair.second;
193 arm->bufferConfigUserToNonRt.reinitAllBuffers(arm->nonRtConfig);
195 for (
auto& pair :
limb)
197 userConfig.limbs.at(pair.first) = pair.second->nonRtConfig;