1 #include <SimoxUtility/math/pose/pose.h>
2 #include <SimoxUtility/math/pose/is_homogeneous_transform.h>
3 #include <SimoxUtility/math/isfinite.h>
17 auto cfgPtr = NJointBimanualCartesianAdmittanceControllerConfigPtr::dynamicCast(config);
21 auto initRtData = [&](
auto &
data,
const auto & rnsName,
const auto & ftName,
const auto & ftRefFrame)
27 data.frameFTSensor =
rtGetRobot()->getSensor(ftName)->getRobotNode();
30 for (
size_t i = 0; i <
data.rns->getSize(); ++i)
32 std::string jointName =
data.rns->getNode(i)->getName();
33 data.jointNames.push_back(jointName);
38 data.targets.push_back(ct->
asA<ControlTarget1DoFActuatorTorque>());
39 const SensorValue1DoFActuatorVelocity* velocitySensor = sv->
asA<SensorValue1DoFActuatorVelocity>();
40 const SensorValue1DoFActuatorPosition* positionSensor = sv->
asA<SensorValue1DoFActuatorPosition>();
43 data.velocitySensors.push_back(velocitySensor);
44 data.positionSensors.push_back(positionSensor);
46 const auto ftDev = robUnit->getSensorDevice(ftName);
52 data.IK.reset(
new VirtualRobot::DifferentialIK(
54 data.rns->getRobot()->getRootNode(),
55 VirtualRobot::JacobiProvider::eSVDDamped));
58 initRtData(rt.left, cfgPtr->kinematicChainLeft, cfgPtr->ftSensorLeft, cfgPtr->ftSensorLeftFrame);
59 initRtData(rt.right, cfgPtr->kinematicChainRight, cfgPtr->ftSensorRight, cfgPtr->ftSensorRightFrame);
112 rt.left.sensorFrame2TcpFrame.setZero();
113 rt.right.sensorFrame2TcpFrame.setZero();
139 rt.virtualAcc.setZero();
140 rt.virtualVel.setZero();
141 rt.virtualPose.setZero();
142 rt.filteredOldValue.setZero();
145 rt.ftcalibrationTimer = 0;
149 const Eigen::Matrix4f leftPose = simox::math::scaled_position(rt.left.tcp->getPoseInRootFrame(), 0.001);
150 const Eigen::Matrix4f rightPose = simox::math::scaled_position(rt.right.tcp->getPoseInRootFrame(), 0.001);
152 rt.virtualPose.block<3, 1>(0, 3) = 0.5 * (leftPose.block<3, 1>(0, 3) + rightPose.block<3, 1>(0, 3));
153 rt.virtualPose.block<3, 3>(0, 0) = leftPose.block<3, 3>(0, 0);
156 rt.left.frameFTSensor->getPoseInRootFrame(), 0.001);
158 rt.right.frameFTSensor->getPoseInRootFrame(), 0.001);
160 rt.left.sensorFrame2TcpFrame.block<3, 3>(0, 0) = leftPose.block<3, 3>(0, 0).transpose() * leftSensorFrame.block<3, 3>(0, 0);
161 rt.right.sensorFrame2TcpFrame.block<3, 3>(0, 0) = rightPose.block<3, 3>(0, 0).transpose() * rightSensorFrame.block<3, 3>(0, 0);
169 return "NJointBimanualCartesianAdmittanceController";
204 const Eigen::Matrix4f currentLeftPose = simox::math::scaled_position(rt.left.tcp->getPoseInRootFrame(), 0.001);
205 const Eigen::Matrix4f currentRightPose = simox::math::scaled_position(rt.right.tcp->getPoseInRootFrame(), 0.001);
209 pose.block<3, 1>(0, 3) = 0.5 * (currentLeftPose.block<3, 1>(0, 3) + currentRightPose.block<3, 1>(0, 3));
210 pose.block<3, 3>(0, 0) = currentLeftPose.block<3, 3>(0, 0);
218 const double deltaT = timeSinceLastIteration.toSecondsDouble();
222 rt.ftcalibrationTimer += deltaT;
229 const Eigen::Vector3f tmpL = rt.left.sensorFrame2TcpFrame.block<3, 3>(0, 0) * cfg.CoMVecLeft;
230 const Eigen::Vector3f tmpR = rt.right.sensorFrame2TcpFrame.block<3, 3>(0, 0) * cfg.CoMVecRight;
231 cfg.CoMVecLeft = tmpL;
232 cfg.CoMVecRight = tmpR;
237 trg.pose = currentBoxPose;
244 if (rt.ftcalibrationTimer < cfg.ftCalibrationTime)
254 (rt.ftcalibrationTimer < cfg.ftCalibrationTime) ?
255 Eigen::Vector6f::Zero() :
259 const Eigen::Vector12f deltaPoseForWrenchControl = cfg.targetWrench.array() / cfg.KpImpedance.array();
265 const auto skew = [](
auto & vec)
276 const Eigen::Vector3f objCom2TCPLeft{-cfg.boxWidth * 0.5f, 0.f, 0.f};
277 const Eigen::Vector3f objCom2TCPRight{+cfg.boxWidth * 0.5f, 0.f, 0.f};
279 Eigen::Matrix_6_12_f graspMatrix;
280 graspMatrix.setZero();
284 const Eigen::Vector3f rLeft = rt.virtualPose.block<3, 3>(0, 0) * objCom2TCPLeft;
285 const Eigen::Vector3f rRight = rt.virtualPose.block<3, 3>(0, 0) * objCom2TCPRight;
287 graspMatrix.block<3, 3>(3, 0) = skew(rLeft);
288 graspMatrix.block<3, 3>(3, 6) = skew(rRight);
295 const Eigen::MatrixXf pinvGraspMatrixT = rt.left.IK->computePseudoInverseJacobianMatrix(graspMatrix.transpose(), lambda);
299 boxCurrentPose.block<3, 1>(0, 3) = 0.5 * (currentLeftPose.block<3, 1>(0, 3) + currentRightPose.block<3, 1>(0, 3));
305 Eigen::MatrixXf jacobiL = rt.left.IK->getJacobianMatrix(rt.left.tcp, VirtualRobot::IKSolver::CartesianSelection::All);
306 Eigen::MatrixXf jacobiR = rt.right.IK->getJacobianMatrix(rt.right.tcp, VirtualRobot::IKSolver::CartesianSelection::All);
307 jacobiL.block<3, 8>(0, 0) = 0.001 * jacobiL.block<3, 8>(0, 0);
308 jacobiR.block<3, 8>(0, 0) = 0.001 * jacobiR.block<3, 8>(0, 0);
311 Eigen::VectorXf leftqpos(rt.left.positionSensors.size());
312 Eigen::VectorXf leftqvel(rt.left.velocitySensors.size());
313 for (
size_t i = 0; i < rt.left.velocitySensors.size(); ++i)
315 leftqpos(i) = rt.left.positionSensors[i]->position;
316 leftqvel(i) = rt.left.velocitySensors[i]->velocity;
319 Eigen::VectorXf rightqpos(rt.right.positionSensors.size());
320 Eigen::VectorXf rightqvel(rt.right.velocitySensors.size());
321 for (
size_t i = 0; i < rt.right.velocitySensors.size(); ++i)
323 rightqpos(i) = rt.right.positionSensors[i]->position;
324 rightqvel(i) = rt.right.velocitySensors[i]->velocity;
331 Eigen::Vector12f currentTwist;
332 currentTwist << currentLeftTwist, currentRightTwist;
333 boxCurrentTwist = pinvGraspMatrixT * currentTwist;
343 const Eigen::Vector3f gravity{0.0, 0.0, -9.8};
344 const Eigen::Vector3f localGravityLeft = currentLeftPose.block<3, 3>(0, 0).
transpose() * gravity;
345 const Eigen::Vector3f localForceVecLeft = cfg.massLeft * localGravityLeft;
346 const Eigen::Vector3f localTorqueVecLeft = cfg.CoMVecLeft.cross(localForceVecLeft);
348 const Eigen::Vector3f localGravityRight = currentRightPose.block<3, 3>(0, 0).
transpose() * gravity;
349 const Eigen::Vector3f localForceVecRight = cfg.massRight * localGravityRight;
350 const Eigen::Vector3f localTorqueVecRight = cfg.CoMVecRight.cross(localForceVecRight);
353 Eigen::Vector12f wrenchesMeasured;
354 wrenchesMeasured << rt.right.forceTorque->force - cfg.forceOffsetLeft,
355 rt.right.forceTorque->torque - cfg.torqueOffsetLeft,
356 rt.left.forceTorque->force - cfg.forceOffsetRight,
357 rt.left.forceTorque->torque - cfg.torqueOffsetRight;
358 for (
size_t i = 0; i < 12; i++)
360 wrenchesMeasured(i) = (1 - cfg.filterCoeff) * wrenchesMeasured(i) + cfg.filterCoeff * rt.filteredOldValue(i);
362 rt.filteredOldValue = wrenchesMeasured;
363 wrenchesMeasured.block<3, 1>(0, 0) = rt.left.sensorFrame2TcpFrame.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(0, 0) - localForceVecLeft;
364 wrenchesMeasured.block<3, 1>(3, 0) = rt.left.sensorFrame2TcpFrame.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(3, 0) - localTorqueVecLeft;
365 wrenchesMeasured.block<3, 1>(6, 0) = rt.right.sensorFrame2TcpFrame.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(6, 0) - localForceVecRight;
366 wrenchesMeasured.block<3, 1>(9, 0) = rt.right.sensorFrame2TcpFrame.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(9, 0) - localTorqueVecRight;
372 Eigen::Vector12f wrenchesMeasuredInRoot;
373 wrenchesMeasuredInRoot.block<3, 1>(0, 0) = currentLeftPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(0, 0);
374 wrenchesMeasuredInRoot.block<3, 1>(3, 0) = currentLeftPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(3, 0);
375 wrenchesMeasuredInRoot.block<3, 1>(6, 0) = currentRightPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(6, 0);
376 wrenchesMeasuredInRoot.block<3, 1>(9, 0) = currentRightPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(9, 0);
380 for (
size_t i = 0; i < 6; i++)
382 if (fabs(objFTValue(i)) < cfg.forceThreshold(i))
388 objFTValue(i) -= cfg.forceThreshold(i) * objFTValue(i) / fabs(objFTValue(i));
398 objPoseError.head(3) = rt.virtualPose.block<3, 1>(0, 3) - boxPose.block<3, 1>(0, 3);
399 const Eigen::Matrix3f objDiffMat = rt.virtualPose.block<3, 3>(0, 0) * boxPose.block<3, 3>(0, 0).transpose();
400 objPoseError.tail(3) = VirtualRobot::MathTools::eigen3f2rpy(objDiffMat);
405 for (
size_t i = 0; i < 6; i++)
407 objAcc(i) = KmAdmittance(i) * objFTValue(i)
408 - cfg.KpAdmittance(i) * objPoseError(i)
409 - cfg.KdAdmittance(i) * rt.virtualVel(i);
411 objVel = rt.virtualVel + 0.5 * deltaT * (objAcc + rt.virtualAcc);
412 const Eigen::Vector6f deltaObjPose = 0.5 * deltaT * (objVel + rt.virtualVel);
413 rt.virtualAcc = objAcc;
414 rt.virtualVel = objVel;
415 rt.virtualPose.block<3, 1>(0, 3) += deltaObjPose.head(3);
416 rt.virtualPose.block<3, 3>(0, 0) = VirtualRobot::MathTools::rpy2eigen3f(
419 deltaObjPose(5)) * rt.virtualPose.block<3, 3>(0, 0);
424 tcpTargetPoseLeft.block<3, 1>(0, 3) += rt.virtualPose.block<3, 3>(0, 0) * (objCom2TCPLeft - deltaPoseForWrenchControl.block<3, 1>(0, 0));
425 tcpTargetPoseRight.block<3, 1>(0, 3) += rt.virtualPose.block<3, 3>(0, 0) * (objCom2TCPRight - deltaPoseForWrenchControl.block<3, 1>(6, 0));
428 Eigen::Vector12f poseError;
429 Eigen::Matrix3f diffMat = tcpTargetPoseLeft.block<3, 3>(0, 0) * currentLeftPose.block<3, 3>(0, 0).transpose();
430 poseError.block<3, 1>(0, 0) = tcpTargetPoseLeft.block<3, 1>(0, 3) - currentLeftPose.block<3, 1>(0, 3);
431 poseError.block<3, 1>(3, 0) = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
433 diffMat = tcpTargetPoseRight.block<3, 3>(0, 0) * currentRightPose.block<3, 3>(0, 0).transpose();
434 poseError.block<3, 1>(6, 0) = tcpTargetPoseRight.block<3, 1>(0, 3) - currentRightPose.block<3, 1>(0, 3);
435 poseError.block<3, 1>(9, 0) = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
437 Eigen::Vector12f forceImpedance;
438 for (
size_t i = 0; i < 12; i++)
440 forceImpedance(i) = cfg.KpImpedance(i) * poseError(i) - cfg.KdImpedance(i) * currentTwist(i);
445 const Eigen::VectorXf leftNullspaceTorque = cfg.knull * (cfg.desiredJointValuesLeft - leftqpos) - cfg.dnull * leftqvel;
446 const Eigen::VectorXf rightNullspaceTorque = cfg.knull * (cfg.desiredJointValuesRight - rightqpos) - cfg.dnull * rightqvel;
452 const auto setTargets = [&](
auto & rtarm,
const auto & jacobi,
const auto & nullspaceTorque,
int forceImpOffset)
454 const Eigen::MatrixXf jtpinv = rtarm.IK->computePseudoInverseJacobianMatrix(jacobi.transpose(), lambda);
455 const Eigen::VectorXf desiredJointTorques = jacobi.transpose() * forceImpedance.block<6, 1>(forceImpOffset, 0) +
456 (I - jacobi.transpose() * jtpinv) * nullspaceTorque;
457 for (
size_t i = 0; i < rtarm.targets.size(); ++i)
459 float desiredTorque = desiredJointTorques(i);
460 if (isnan(desiredTorque))
464 desiredTorque = (desiredTorque > cfg.torqueLimit) ? cfg.torqueLimit : desiredTorque;
465 desiredTorque = (desiredTorque < -cfg.torqueLimit) ? -cfg.torqueLimit : desiredTorque;
466 dbgOut.desired_torques[rtarm.jointNames[i]] = desiredJointTorques(i);
467 rtarm.targets.at(i)->torque = desiredTorque;
470 setTargets(rt.left, jacobiL, leftNullspaceTorque, 0);
471 setTargets(rt.right, jacobiR, rightNullspaceTorque, 6);
473 const Eigen::MatrixXf jtpinvL = rt.left.IK->computePseudoInverseJacobianMatrix(jacobiL.transpose(), lambda);
474 const Eigen::VectorXf leftJointDesiredTorques = jacobiL.transpose() * forceImpedance.head(6) + (I - jacobiL.transpose() * jtpinvL) * leftNullspaceTorque;
475 for (
size_t i = 0; i < rt.left.targets.size(); ++i)
477 float desiredTorque = leftJointDesiredTorques(i);
478 if (isnan(desiredTorque))
482 desiredTorque = (desiredTorque > cfg.torqueLimit) ? cfg.torqueLimit : desiredTorque;
483 desiredTorque = (desiredTorque < -cfg.torqueLimit) ? -cfg.torqueLimit : desiredTorque;
484 dbgOut.desired_torques[rt.left.jointNames[i]] = leftJointDesiredTorques(i);
485 rt.left.targets.at(i)->torque = desiredTorque;
490 const Eigen::MatrixXf jtpinvR = rt.right.IK->computePseudoInverseJacobianMatrix(jacobiR.transpose(), lambda);
491 const Eigen::VectorXf rightJointDesiredTorques = jacobiR.transpose() * forceImpedance.tail(6) + (I - jacobiR.transpose() * jtpinvR) * rightNullspaceTorque;
492 for (
size_t i = 0; i < rt.right.targets.size(); ++i)
494 float desiredTorque = rightJointDesiredTorques(i);
495 if (isnan(desiredTorque))
499 desiredTorque = (desiredTorque > cfg.torqueLimit) ? cfg.torqueLimit : desiredTorque;
500 desiredTorque = (desiredTorque < - cfg.torqueLimit) ? - cfg.torqueLimit : desiredTorque;
501 dbgOut.desired_torques[rt.right.jointNames[i]] = rightJointDesiredTorques(i);
502 rt.right.targets.at(i)->torque = desiredTorque;
507 dbgOut.currentBoxPose = currentBoxPose;
508 dbgOut.forceImpedance = forceImpedance;
509 dbgOut.poseError = poseError;
511 dbgOut.wrenchesMeasuredInRoot = wrenchesMeasuredInRoot;
515 dbgOut.virtualPose_x = rt.virtualPose(0, 3);
516 dbgOut.virtualPose_y = rt.virtualPose(1, 3);
517 dbgOut.virtualPose_z = rt.virtualPose(2, 3);
519 dbgOut.objPose_x = boxCurrentPose(0, 3);
520 dbgOut.objPose_y = boxCurrentPose(1, 3);
521 dbgOut.objPose_z = boxCurrentPose(2, 3);
523 dbgOut.objForce_x = objFTValue(0);
524 dbgOut.objForce_y = objFTValue(1);
525 dbgOut.objForce_z = objFTValue(2);
526 dbgOut.objTorque_x = objFTValue(3);
527 dbgOut.objTorque_y = objFTValue(4);
528 dbgOut.objTorque_z = objFTValue(5);
530 dbgOut.objVel_x = objVel(0);
531 dbgOut.objVel_y = objVel(1);
532 dbgOut.objVel_z = objVel(2);
533 dbgOut.objVel_rx = objVel(3);
534 dbgOut.objVel_ry = objVel(4);
535 dbgOut.objVel_rz = objVel(5);
537 dbgOut.deltaPose_x = deltaObjPose(0);
538 dbgOut.deltaPose_y = deltaObjPose(1);
539 dbgOut.deltaPose_z = deltaObjPose(2);
540 dbgOut.deltaPose_rx = deltaObjPose(3);
541 dbgOut.deltaPose_ry = deltaObjPose(4);
542 dbgOut.deltaPose_rz = deltaObjPose(5);
544 dbgOut.modifiedPoseRight_x = tcpTargetPoseRight(0, 3);
545 dbgOut.modifiedPoseRight_y = tcpTargetPoseRight(1, 3);
546 dbgOut.modifiedPoseRight_z = tcpTargetPoseRight(2, 3);
548 dbgOut.currentPoseLeft_x = currentLeftPose(0, 3);
549 dbgOut.currentPoseLeft_y = currentLeftPose(1, 3);
550 dbgOut.currentPoseLeft_z = currentLeftPose(2, 3);
554 dbgOut.modifiedPoseLeft_x = tcpTargetPoseLeft(0, 3);
555 dbgOut.modifiedPoseLeft_y = tcpTargetPoseLeft(1, 3);
556 dbgOut.modifiedPoseLeft_z = tcpTargetPoseLeft(2, 3);
558 dbgOut.currentPoseRight_x = currentRightPose(0, 3);
559 dbgOut.currentPoseRight_y = currentRightPose(1, 3);
560 dbgOut.currentPoseRight_z = currentRightPose(2, 3);
563 dbgOut.dmpBoxPose_x = boxPose(0, 3);
564 dbgOut.dmpBoxPose_y = boxPose(1, 3);
565 dbgOut.dmpBoxPose_z = boxPose(2, 3);
567 dbgOut.dmpTwist_x = boxTwist(0);
568 dbgOut.dmpTwist_y = boxTwist(1);
569 dbgOut.dmpTwist_z = boxTwist(2);
570 dbgOut.rx = rRight(0);
571 dbgOut.ry = rRight(1);
572 dbgOut.rz = rRight(2);
589 std::lock_guard guard{debugOutputDataReadMutex};
593 for (
const auto& [name, val] : buf.desired_torques)
595 datafields[name] =
new Variant(val);
598 const auto& reportElements = [&](
const auto & vec,
const std::string & pre)
600 for (
int i = 0; i < vec.rows(); ++i)
605 reportElements(buf.forceImpedance,
"forceImpedance_");
606 reportElements(buf.forcePID,
"forcePID_");
607 reportElements(buf.poseError,
"poseError_");
608 reportElements(buf.wrenchesConstrained,
"wrenchesConstrained_");
609 reportElements(buf.wrenchesMeasuredInRoot,
"wrenchesMeasuredInRoot_");
610 reportElements(buf.wrenchesConstrained,
"wrenchesConstrained_");
611 reportElements(buf.wrenchesConstrained,
"wrenchesConstrained_");
613 datafields[
"virtualPose_x"] =
new Variant(buf.virtualPose_x);
614 datafields[
"virtualPose_y"] =
new Variant(buf.virtualPose_y);
615 datafields[
"virtualPose_z"] =
new Variant(buf.virtualPose_z);
617 datafields[
"objPose_x"] =
new Variant(buf.objPose_x);
618 datafields[
"objPose_y"] =
new Variant(buf.objPose_y);
619 datafields[
"objPose_z"] =
new Variant(buf.objPose_z);
621 datafields[
"objForce_x"] =
new Variant(buf.objForce_x);
622 datafields[
"objForce_y"] =
new Variant(buf.objForce_y);
623 datafields[
"objForce_z"] =
new Variant(buf.objForce_z);
624 datafields[
"objTorque_x"] =
new Variant(buf.objTorque_x);
625 datafields[
"objTorque_y"] =
new Variant(buf.objTorque_y);
626 datafields[
"objTorque_z"] =
new Variant(buf.objTorque_z);
628 datafields[
"objVel_x"] =
new Variant(buf.objVel_x);
629 datafields[
"objVel_y"] =
new Variant(buf.objVel_y);
630 datafields[
"objVel_z"] =
new Variant(buf.objVel_z);
631 datafields[
"objVel_rx"] =
new Variant(buf.objVel_rx);
632 datafields[
"objVel_ry"] =
new Variant(buf.objVel_ry);
633 datafields[
"objVel_rz"] =
new Variant(buf.objVel_rz);
635 datafields[
"deltaPose_x"] =
new Variant(buf.deltaPose_x);
636 datafields[
"deltaPose_y"] =
new Variant(buf.deltaPose_y);
637 datafields[
"deltaPose_z"] =
new Variant(buf.deltaPose_z);
638 datafields[
"deltaPose_rx"] =
new Variant(buf.deltaPose_rx);
639 datafields[
"deltaPose_ry"] =
new Variant(buf.deltaPose_ry);
640 datafields[
"deltaPose_rz"] =
new Variant(buf.deltaPose_rz);
642 datafields[
"modifiedPoseRight_x"] =
new Variant(buf.modifiedPoseRight_x);
643 datafields[
"modifiedPoseRight_y"] =
new Variant(buf.modifiedPoseRight_y);
644 datafields[
"modifiedPoseRight_z"] =
new Variant(buf.modifiedPoseRight_z);
645 datafields[
"currentPoseLeft_x"] =
new Variant(buf.currentPoseLeft_x);
646 datafields[
"currentPoseLeft_y"] =
new Variant(buf.currentPoseLeft_y);
647 datafields[
"currentPoseLeft_z"] =
new Variant(buf.currentPoseLeft_z);
650 datafields[
"modifiedPoseLeft_x"] =
new Variant(buf.modifiedPoseLeft_x);
651 datafields[
"modifiedPoseLeft_y"] =
new Variant(buf.modifiedPoseLeft_y);
652 datafields[
"modifiedPoseLeft_z"] =
new Variant(buf.modifiedPoseLeft_z);
654 datafields[
"currentPoseRight_x"] =
new Variant(buf.currentPoseRight_x);
655 datafields[
"currentPoseRight_y"] =
new Variant(buf.currentPoseRight_y);
656 datafields[
"currentPoseRight_z"] =
new Variant(buf.currentPoseRight_z);
657 datafields[
"dmpBoxPose_x"] =
new Variant(buf.dmpBoxPose_x);
658 datafields[
"dmpBoxPose_y"] =
new Variant(buf.dmpBoxPose_y);
659 datafields[
"dmpBoxPose_z"] =
new Variant(buf.dmpBoxPose_z);
660 datafields[
"dmpTwist_x"] =
new Variant(buf.dmpTwist_x);
661 datafields[
"dmpTwist_y"] =
new Variant(buf.dmpTwist_y);
662 datafields[
"dmpTwist_z"] =
new Variant(buf.dmpTwist_z);
664 datafields[
"modifiedTwist_lx"] =
new Variant(buf.modifiedTwist_lx);
665 datafields[
"modifiedTwist_ly"] =
new Variant(buf.modifiedTwist_ly);
666 datafields[
"modifiedTwist_lz"] =
new Variant(buf.modifiedTwist_lz);
667 datafields[
"modifiedTwist_rx"] =
new Variant(buf.modifiedTwist_rx);
668 datafields[
"modifiedTwist_ry"] =
new Variant(buf.modifiedTwist_ry);
669 datafields[
"modifiedTwist_rz"] =
new Variant(buf.modifiedTwist_rz);
671 datafields[
"rx"] =
new Variant(buf.rx);
672 datafields[
"ry"] =
new Variant(buf.ry);
673 datafields[
"rz"] =
new Variant(buf.rz);
676 debugObs->setDebugChannel(
"BimanualForceController", datafields);
681 std::lock_guard guard{debugOutputDataReadMutex};
688 std::lock_guard guard{targBufWriteMutex};
696 std::lock_guard{cfgBufWriteMutex};
701 const Eigen::Vector3f& velXYZ,
702 const Eigen::Vector3f& velRPY,
707 std::lock_guard guard{targBufWriteMutex};
715 const Eigen::Vector3f& velXYZ,
716 const Eigen::Vector3f& velRPY,
const Ice::Current&)
721 std::lock_guard guard{targBufWriteMutex};
730 std::lock_guard guard{targBufWriteMutex};
738 std::lock_guard guard{targBufWriteMutex};
746 ARMARX_CHECK_EQUAL(ptr->nullspace.desiredJointValuesLeft.size(), rt.left.targets.size());
747 ARMARX_CHECK_EQUAL(ptr->nullspace.desiredJointValuesRight.size(), rt.right.targets.size());
748 std::lock_guard{cfgBufWriteMutex};
754 std::lock_guard{cfgBufWriteMutex};
760 std::lock_guard{cfgBufWriteMutex};
766 std::lock_guard{cfgBufWriteMutex};
772 std::lock_guard{cfgBufWriteMutex};
778 std::lock_guard{cfgBufWriteMutex};
784 std::lock_guard{cfgBufWriteMutex};
791 std::lock_guard{cfgBufWriteMutex};
804 std::lock_guard{cfgBufWriteMutex};
807 buf.desiredJointValuesLeft = Eigen::Map<const Eigen::VectorXf>(
808 vals.data(), vals.size());
812 std::lock_guard{cfgBufWriteMutex};
815 buf.desiredJointValuesRight = Eigen::Map<const Eigen::VectorXf>(
816 vals.data(), vals.size());
820 std::lock_guard{cfgBufWriteMutex};
824 cfg.knull = nullspace.
k;
825 cfg.dnull = nullspace.
d;
829 std::lock_guard{cfgBufWriteMutex};
831 cfg.KmAdmittance.block<3, 1>(0, 0) = admittanceObject.
KmXYZ;
832 cfg.KmAdmittance.block<3, 1>(3, 0) = admittanceObject.
KmRPY;
834 cfg.KpAdmittance.block<3, 1>(0, 0) = admittanceObject.
KpXYZ;
835 cfg.KpAdmittance.block<3, 1>(3, 0) = admittanceObject.
KpRPY;
837 cfg.KdAdmittance.block<3, 1>(0, 0) = admittanceObject.
KdXYZ;
838 cfg.KdAdmittance.block<3, 1>(3, 0) = admittanceObject.
KdRPY;
842 std::lock_guard{cfgBufWriteMutex};
845 cfg.massLeft = forceLeft.
mass;
846 cfg.CoMVecLeft = forceLeft.
com;
849 cfg.targetWrench.block<3, 1>(0, 0) = forceLeft.
wrenchXYZ;
850 cfg.targetWrench.block<3, 1>(3, 0) = forceLeft.
wrenchRPY;
853 cfg.massRight = forceRight.
mass;
854 cfg.CoMVecRight = forceRight.
com;
857 cfg.targetWrench.block<3, 1>(6, 0) = forceRight.
wrenchXYZ;
858 cfg.targetWrench.block<3, 1>(9, 0) = forceRight.
wrenchRPY;
864 std::lock_guard{cfgBufWriteMutex};
866 cfg.KpImpedance.block<3, 1>(0, 0) = impedanceLeft.
KpXYZ;
867 cfg.KpImpedance.block<3, 1>(3, 0) = impedanceLeft.
KpRPY;
868 cfg.KpImpedance.block<3, 1>(6, 0) = impedanceRight.
KpXYZ;
869 cfg.KpImpedance.block<3, 1>(9, 0) = impedanceRight.
KpRPY;
871 cfg.KdImpedance.block<3, 1>(0, 0) = impedanceLeft.
KdXYZ;
872 cfg.KdImpedance.block<3, 1>(3, 0) = impedanceLeft.
KdRPY;
873 cfg.KdImpedance.block<3, 1>(6, 0) = impedanceRight.
KdXYZ;
874 cfg.KdImpedance.block<3, 1>(9, 0) = impedanceRight.
KdRPY;