24 #include <VirtualRobot/MathTools.h>
36 const RobotUnitPtr& robotUnit,
37 const NJointControllerConfigPtr& config,
42 mpConfig = MPListConfig();
58 auto configData = MPListConfig::FromAron(dto);
60 while (additionalTaskRunning.load())
64 for (
const auto& _mp : configData.mpList)
66 if (
limb.find(_mp.nodeSetName) ==
limb.end())
68 ARMARX_WARNING <<
"You have to make sure the RobotNodeSet " << _mp.nodeSetName
69 <<
" in your MP config "
70 <<
"corresponds to one of the RobotNodeSet in the controllers";
79 ARMARX_INFO <<
"-- successfully updated MP config.";
84 "If you want to force reset, please call \n\n"
85 " ctrl->stop('all') \n\n"
86 "before you continue";
99 ARMARX_IMPORTANT <<
"---------------------------------- Updating BiKAC Config -------------------------------------------";
102 auto configData = ::armarx::fromAronDict<arondto::BiKACConfig, BiKACConfig>(dto);
103 isConstraintReady.store(
false);
104 for (
const auto& _c : configData.cList)
106 ARMARX_INFO <<
"reinit mp in/output data, and checking " << _c.idx <<
"-th constraint with type " << _c.type;
107 if(
limb.find(_c.rnsKpt) ==
limb.end())
110 << _c.rnsFrame <<
" in your " << _c.idx <<
"-th constraint config for a keypoint "
111 <<
"corresponds to one of the RobotNodeSet in the controllers";
115 auto& _mp =
mps.at(_c.mpName);
116 if (_c.type ==
"pose")
120 if (_mp.mp->getClassName() !=
"TSMP")
125 std::dynamic_pointer_cast<mp::TSMPInput>(_mp.input)->pose = _c.currentKptPoseLocal;
126 std::dynamic_pointer_cast<mp::TSMPOutput>(_mp.output)->pose = _c.currentKptPoseLocal;
133 std::dynamic_pointer_cast<mp::JSMPInput>(_mp.input)->angleRadian = _c.currentKptPoseLocal.block<3, 1>(0, 3);
134 std::dynamic_pointer_cast<mp::JSMPInput>(_mp.input)->angularVel = Eigen::Vector3f::Zero();
135 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.output)->angleRadian = _c.currentKptPoseLocal.block<3, 1>(0, 3);
136 std::dynamic_pointer_cast<mp::JSMPOutput>(_mp.output)->angularVel = Eigen::Vector3f::Zero();
139 if(_c.rnsFrame !=
"static" and
limb.find(_c.rnsFrame) ==
limb.end())
142 << _c.rnsFrame <<
" in your " << _c.idx <<
"-th constraint config for a frame "
143 <<
"corresponds to one of the RobotNodeSet in the controllers";
149 for (
const auto&
c: configData.cList)
151 ARMARX_IMPORTANT <<
"----------------------- c -----------------------------";
157 ARMARX_IMPORTANT <<
"-------------------------------------------------------";
162 isConstraintReady.store(
true);
167 ARMARX_WARNING <<
"MP is not finished yet, cannot reset constraints \n"
168 "If you want to force reset, please call \n\n"
169 " ctrl->stop('all') \n\n"
170 "before you continue";
172 ARMARX_IMPORTANT <<
"---------------------------------- BiKAC Config Updated -------------------------------------------";
179 return ::armarx::toAronDict<arondto::BiKACConfig, BiKACConfig>(
biKacConfig);
188 auto& _mp =
mps.at(
c.mpName);
189 auto& slaveArm =
limb.at(
c.rnsKpt);
190 slaveArm->rtStatusInNonRT = slaveArm->bufferRtToNonRt.getUpToDateReadBuffer();
191 const auto currentSlaveTCPPose = slaveArm->controller.tcp->getPoseInRootFrame();
192 c.currentKptPoseRoot = currentSlaveTCPPose *
c.poseDiffKptLocal;
193 deltaT = slaveArm->rtStatusInNonRT.deltaT;
195 if (
c.type ==
"pose")
198 const auto masterFrameInv =
c.currentFrameRoot.inverse();
199 c.currentKptPoseLocal = masterFrameInv *
c.currentKptPoseRoot;
200 c.currentKptVelocityRoot = (1 -
c.keypointVelocityFilter) *
c.currentKptVelocityRoot +
201 c.keypointVelocityFilter * slaveArm->rtStatusInNonRT.currentTwist.head(3);
204 c.currentKptVelocityLocal.head(3) =
c.currentFrameRoot.block<3, 3>(0, 0).
transpose() *
c.currentKptVelocityRoot.head(3);
205 c.currentKptVelocityLocal.tail(3) =
c.currentFrameRoot.block<3, 3>(0, 0).
transpose() *
c.currentKptVelocityRoot.tail(3);
208 in->pose =
c.currentKptPoseLocal;
209 in->vel =
c.currentKptVelocityLocal;
212 _mp.mp->run(_mp.input, _mp.output);
215 c.targetKptPoseLocal = out->pose;
216 c.targetKptPoseRoot =
c.currentFrameRoot * out->pose;
219 vel.head(3) =
c.currentFrameRoot.block<3, 3>(0, 0) * out->vel.head(3);
220 vel.tail(3) =
c.currentFrameRoot.block<3, 3>(0, 0) * out->vel.tail(3);
222 slaveArm->nonRtData.c.desiredPose =
c.targetKptPoseRoot *
c.poseDiffKptLocal.inverse();
223 slaveArm->nonRtData.c.desiredTwist = vel;
230 if (
c.rnsFrame !=
"static")
232 auto& masterArm =
limb.at(
c.rnsFrame);
233 const auto currentMasterTCPPose = masterArm->controller.tcp->getPoseInRootFrame();
234 c.currentFrameRoot = currentMasterTCPPose *
c.poseDiffFrameLocal;
236 const auto masterFrameInv =
c.currentFrameRoot.inverse();
237 c.currentKptPoseLocal = masterFrameInv *
c.currentKptPoseRoot;
239 Eigen::Vector3f angular_vel = slaveArm->rtStatusInNonRT.currentTwist.tail(3);
240 Eigen::Vector3f vecRoot = currentSlaveTCPPose.block<3, 3>(0, 0) *
c.poseDiffKptLocal.block<3, 1>(0, 3);
241 c.currentKptVelocityRoot.head(3) =
242 (1 -
c.keypointVelocityFilter) *
c.currentKptVelocityRoot.head(3) +
243 c.keypointVelocityFilter * (angular_vel.cross(vecRoot) +
244 slaveArm->rtStatusInNonRT.currentTwist.head(3));
246 c.currentKptVelocityLocal.head(3) =
c.currentFrameRoot.block<3, 3>(0, 0).
transpose() *
c.currentKptVelocityRoot.head(3);
252 in->angleRadian =
c.currentKptPoseLocal.block<3, 1>(0, 3);
253 in->angularVel =
c.currentKptVelocityLocal.head(3);
256 _mp.mp->run(_mp.input, _mp.output);
259 c.targetKptPoseLocal.block<3, 1>(0, 3) = out->angleRadian;
263 Eigen::Vector3f modified_target =
c.targetKptPoseLocal.block<3, 1>(0, 3);
264 if (
c.p2pIdx >= 0 and
c.type !=
"p2p")
267 Eigen::Vector3f p2p_local = (masterFrameInv * p2p.currentKptPoseRoot).block<3, 1>(0, 3);
268 const auto x_ =
c.targetKptPoseLocal.block<3, 1>(0, 3);
269 float radius = (
c.currentKptPoseLocal.block<3, 1>(0, 3) - p2p_local).norm();
273 Eigen::Vector3f line_vec =
c.pcaComponentsLocal.row(0);
275 auto vec_mean_to_p2p = p2p_local -
c.pcaMeanLocal;
276 float proj_p2p = vec_mean_to_p2p.dot(line_vec);
277 auto proj_point_p2p =
c.pcaMeanLocal + line_vec * proj_p2p;
279 Eigen::Vector3f line_norm_to_p2p = (p2p_local - proj_point_p2p).normalized();
280 float proj_x_ = (x_ - p2p_local).
dot(line_norm_to_p2p);
281 Eigen::Vector3f proj_point = p2p_local + proj_x_ * line_norm_to_p2p;
283 Eigen::Vector3f radial_vec = (x_ - proj_point).normalized();
285 proj_point = p2p_local + proj_x_ * line_norm_to_p2p;
286 modified_target =
sqrt(radius * radius - proj_x_ * proj_x_) * radial_vec + proj_point;
288 else if (
c.type ==
"p2P")
290 Eigen::Vector3f plane_norm_vec =
c.pcaComponentsLocal.row(2);
291 float proj_x_ = (x_ - p2p_local).
dot(plane_norm_vec);
292 Eigen::Vector3f proj_point = p2p_local + proj_x_ * plane_norm_vec;
294 Eigen::Vector3f radial_vec = (x_ - proj_point).normalized();
296 proj_point = p2p_local + proj_x_ * plane_norm_vec;
297 modified_target =
sqrt(radius * radius - proj_x_ * proj_x_) * radial_vec + proj_point;
300 c.targetKptPoseLocal.block<3, 1>(0, 3) = modified_target;
301 c.targetKptPoseRoot =
c.currentFrameRoot *
c.targetKptPoseLocal;
303 Eigen::Vector3f kpt_error = modified_target -
c.currentKptPoseLocal.block<3, 1>(0, 3);
305 c.trackingForceLocal =
306 (1-
c.keypointForceFilter) *
c.trackingForceLocal +
307 c.keypointForceFilter * (
308 c.kptKp.cwiseProduct(kpt_error) -
c.kptKd.cwiseProduct(
c.currentKptVelocityLocal.head(3)));
309 c.trackingForceRoot =
c.currentFrameRoot.block<3, 3>(0, 0) *
c.trackingForceLocal;
316 auto& force_torque = pair.second.forceTorque;
318 force_torque_current.setZero();
319 Eigen::Vector3f meanKeypointPositionRoot = Eigen::Vector3f::Zero();
320 for (
auto i: pair.second.constraintIdxList)
322 meanKeypointPositionRoot = meanKeypointPositionRoot +
biKacConfig.
cList.at(i).currentKptPoseRoot.block<3, 1>(0, 3);
324 meanKeypointPositionRoot = meanKeypointPositionRoot / pair.second.constraintIdxList.size();
326 for (
auto i: pair.second.constraintIdxList)
328 Eigen::Vector3f devi =
biKacConfig.
cList.at(i).currentKptPoseRoot.block<3, 1>(0, 3) - meanKeypointPositionRoot;
331 if (force.norm() > 100.0)
336 force_torque_current.head(3) += force;
337 force_torque_current.tail(3) += devi.cross(force);
339 force_torque = 0.1 * force_torque + 0.9 * force_torque_current;
346 Eigen::Vector6f vel = pair.second.desiredVel + 0.5 *
static_cast<float>(deltaT) * (acc + pair.second.desiredAcc);
347 Eigen::VectorXf deltaPose = 0.5 *
static_cast<float>(deltaT) * (vel + pair.second.desiredVel);
348 pair.second.desiredAcc = acc;
349 pair.second.desiredVel = vel;
351 Eigen::Matrix3f deltaPoseMat = VirtualRobot::MathTools::rpy2eigen3f(deltaPose(3), deltaPose(4), deltaPose(5));
352 pair.second.desiredPose.block<3, 1>(0, 3) += deltaPose.head(3);
353 pair.second.desiredPose.block<3, 3>(0, 0) = deltaPoseMat * pair.second.desiredPose.block<3, 3>(0, 0);
356 auto& slaveArm =
limb.at(pair.first);
357 slaveArm->nonRtData.c.desiredPose = pair.second.desiredPose;
358 slaveArm->nonRtData.c.desiredTwist = pair.second.desiredVel;
368 for (
auto& pair:
limb)
370 rtSafe = rtSafe and pair.second->bufferRtToNonRt.getUpToDateReadBuffer().rtSafe;
374 if (isConstraintReady.load() and
isMPReady.load())
378 for (
auto& pair :
limb)
387 arm->bufferConfigNonRtToRt.getWriteBuffer() = arm->nonRtConfig;
388 arm->bufferConfigNonRtToRt.commitWrite();
424 for (
auto& pair :
limb)
457 debugObs->setDebugChannel(
"BiKAC", datafields);