3 #include <SimoxUtility/math/isfinite.h>
4 #include <SimoxUtility/math/pose/is_homogeneous_transform.h>
5 #include <SimoxUtility/math/pose/pose.h>
10 #include <VirtualRobot/IK/DifferentialIK.h>
11 #include <VirtualRobot/MathTools.h>
12 #include <VirtualRobot/Nodes/RobotNode.h>
13 #include <VirtualRobot/Nodes/Sensor.h>
14 #include <VirtualRobot/Robot.h>
15 #include <VirtualRobot/RobotNodeSet.h>
28 #include <armarx/control/deprecated_njoint_mp_controller/bimanual/CartesianAdmittanceControllerInterface.h>
34 "NJointBimanualCartesianAdmittanceController");
38 const armarx::NJointControllerConfigPtr& config,
43 auto cfgPtr = NJointBimanualCartesianAdmittanceControllerConfigPtr::dynamicCast(config);
48 [&](
auto&
data,
const auto& rnsName,
const auto& ftName,
const auto& ftRefFrame)
54 data.frameFTSensor =
rtGetRobot()->getSensor(ftName)->getRobotNode();
57 for (
size_t i = 0; i <
data.rns->getSize(); ++i)
59 std::string jointName =
data.rns->getNode(i)->getName();
60 data.jointNames.push_back(jointName);
65 data.targets.push_back(ct->
asA<ControlTarget1DoFActuatorTorque>());
66 const SensorValue1DoFActuatorVelocity* velocitySensor =
67 sv->
asA<SensorValue1DoFActuatorVelocity>();
68 const SensorValue1DoFActuatorPosition* positionSensor =
69 sv->
asA<SensorValue1DoFActuatorPosition>();
71 <<
"No velocitySensor available for " << jointName;
73 <<
"No positionSensor available for " << jointName;
74 data.velocitySensors.push_back(velocitySensor);
75 data.positionSensors.push_back(positionSensor);
77 const auto ftDev = robUnit->getSensorDevice(ftName);
83 <<
"Sensor value for " << ftName <<
" is not of type SensorValueForceTorque";
85 new VirtualRobot::DifferentialIK(
data.rns,
86 data.rns->getRobot()->getRootNode(),
87 VirtualRobot::JacobiProvider::eSVDDamped));
91 cfgPtr->kinematicChainLeft,
93 cfgPtr->ftSensorLeftFrame);
95 cfgPtr->kinematicChainRight,
96 cfgPtr->ftSensorRight,
97 cfgPtr->ftSensorRightFrame);
150 rt.left.sensorFrame2TcpFrame.setZero();
151 rt.right.sensorFrame2TcpFrame.setZero();
177 rt.virtualAcc.setZero();
178 rt.virtualVel.setZero();
179 rt.virtualPose.setZero();
180 rt.filteredOldValue.setZero();
183 rt.ftcalibrationTimer = 0;
187 simox::math::scaled_position(rt.left.tcp->getPoseInRootFrame(), 0.001);
189 simox::math::scaled_position(rt.right.tcp->getPoseInRootFrame(), 0.001);
191 rt.virtualPose.block<3, 1>(0, 3) =
192 0.5 * (leftPose.block<3, 1>(0, 3) + rightPose.block<3, 1>(0, 3));
193 rt.virtualPose.block<3, 3>(0, 0) = leftPose.block<3, 3>(0, 0);
196 simox::math::scaled_position(rt.left.frameFTSensor->getPoseInRootFrame(), 0.001);
198 simox::math::scaled_position(rt.right.frameFTSensor->getPoseInRootFrame(), 0.001);
200 rt.left.sensorFrame2TcpFrame.block<3, 3>(0, 0) =
201 leftPose.block<3, 3>(0, 0).transpose() * leftSensorFrame.block<3, 3>(0, 0);
202 rt.right.sensorFrame2TcpFrame.block<3, 3>(0, 0) =
203 rightPose.block<3, 3>(0, 0).transpose() * rightSensorFrame.block<3, 3>(0, 0);
212 return "NJointBimanualCartesianAdmittanceController";
248 simox::math::scaled_position(rt.left.tcp->getPoseInRootFrame(), 0.001);
250 simox::math::scaled_position(rt.right.tcp->getPoseInRootFrame(), 0.001);
254 pose.block<3, 1>(0, 3) =
255 0.5 * (currentLeftPose.block<3, 1>(0, 3) + currentRightPose.block<3, 1>(0, 3));
256 pose.block<3, 3>(0, 0) = currentLeftPose.block<3, 3>(0, 0);
264 const double deltaT = timeSinceLastIteration.toSecondsDouble();
268 rt.firstLoop =
false;
271 rt.ftcalibrationTimer += deltaT;
278 const Eigen::Vector3f tmpL =
279 rt.left.sensorFrame2TcpFrame.block<3, 3>(0, 0) * cfg.CoMVecLeft;
280 const Eigen::Vector3f tmpR =
281 rt.right.sensorFrame2TcpFrame.block<3, 3>(0, 0) * cfg.CoMVecRight;
282 cfg.CoMVecLeft = tmpL;
283 cfg.CoMVecRight = tmpR;
288 trg.pose = currentBoxPose;
295 if (rt.ftcalibrationTimer < cfg.ftCalibrationTime)
304 const Eigen::Vector6f KmAdmittance = (rt.ftcalibrationTimer < cfg.ftCalibrationTime)
305 ? Eigen::Vector6f::Zero()
309 const Eigen::Vector12f deltaPoseForWrenchControl =
310 cfg.targetWrench.array() / cfg.KpImpedance.array();
316 const auto skew = [](
auto& vec)
327 const Eigen::Vector3f objCom2TCPLeft{-cfg.boxWidth * 0.5f, 0.f, 0.f};
328 const Eigen::Vector3f objCom2TCPRight{+cfg.boxWidth * 0.5f, 0.f, 0.f};
330 Eigen::Matrix_6_12_f graspMatrix;
331 graspMatrix.setZero();
335 const Eigen::Vector3f rLeft = rt.virtualPose.block<3, 3>(0, 0) * objCom2TCPLeft;
336 const Eigen::Vector3f rRight = rt.virtualPose.block<3, 3>(0, 0) * objCom2TCPRight;
338 graspMatrix.block<3, 3>(3, 0) = skew(rLeft);
339 graspMatrix.block<3, 3>(3, 6) = skew(rRight);
346 const Eigen::MatrixXf pinvGraspMatrixT =
347 rt.left.IK->computePseudoInverseJacobianMatrix(graspMatrix.transpose(), lambda);
351 boxCurrentPose.block<3, 1>(0, 3) =
352 0.5 * (currentLeftPose.block<3, 1>(0, 3) + currentRightPose.block<3, 1>(0, 3));
356 const Eigen::MatrixXf I =
359 Eigen::MatrixXf jacobiL = rt.left.IK->getJacobianMatrix(
360 rt.left.tcp, VirtualRobot::IKSolver::CartesianSelection::All);
361 Eigen::MatrixXf jacobiR = rt.right.IK->getJacobianMatrix(
362 rt.right.tcp, VirtualRobot::IKSolver::CartesianSelection::All);
363 jacobiL.block<3, 8>(0, 0) = 0.001 * jacobiL.block<3, 8>(0, 0);
364 jacobiR.block<3, 8>(0, 0) = 0.001 * jacobiR.block<3, 8>(0, 0);
367 Eigen::VectorXf leftqpos(rt.left.positionSensors.size());
368 Eigen::VectorXf leftqvel(rt.left.velocitySensors.size());
369 for (
size_t i = 0; i < rt.left.velocitySensors.size(); ++i)
371 leftqpos(i) = rt.left.positionSensors[i]->position;
372 leftqvel(i) = rt.left.velocitySensors[i]->velocity;
375 Eigen::VectorXf rightqpos(rt.right.positionSensors.size());
376 Eigen::VectorXf rightqvel(rt.right.velocitySensors.size());
377 for (
size_t i = 0; i < rt.right.velocitySensors.size(); ++i)
379 rightqpos(i) = rt.right.positionSensors[i]->position;
380 rightqvel(i) = rt.right.velocitySensors[i]->velocity;
387 Eigen::Vector12f currentTwist;
388 currentTwist << currentLeftTwist, currentRightTwist;
389 boxCurrentTwist = pinvGraspMatrixT * currentTwist;
399 const Eigen::Vector3f gravity{0.0, 0.0, -9.8};
400 const Eigen::Vector3f localGravityLeft =
401 currentLeftPose.block<3, 3>(0, 0).
transpose() * gravity;
402 const Eigen::Vector3f localForceVecLeft = cfg.massLeft * localGravityLeft;
403 const Eigen::Vector3f localTorqueVecLeft = cfg.CoMVecLeft.cross(localForceVecLeft);
405 const Eigen::Vector3f localGravityRight =
406 currentRightPose.block<3, 3>(0, 0).
transpose() * gravity;
407 const Eigen::Vector3f localForceVecRight = cfg.massRight * localGravityRight;
408 const Eigen::Vector3f localTorqueVecRight = cfg.CoMVecRight.cross(localForceVecRight);
411 Eigen::Vector12f wrenchesMeasured;
412 wrenchesMeasured << rt.right.forceTorque->force - cfg.forceOffsetLeft,
413 rt.right.forceTorque->torque - cfg.torqueOffsetLeft,
414 rt.left.forceTorque->force - cfg.forceOffsetRight,
415 rt.left.forceTorque->torque - cfg.torqueOffsetRight;
416 for (
size_t i = 0; i < 12; i++)
418 wrenchesMeasured(i) = (1 - cfg.filterCoeff) * wrenchesMeasured(i) +
419 cfg.filterCoeff * rt.filteredOldValue(i);
421 rt.filteredOldValue = wrenchesMeasured;
422 wrenchesMeasured.block<3, 1>(0, 0) =
423 rt.left.sensorFrame2TcpFrame.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(0, 0) -
425 wrenchesMeasured.block<3, 1>(3, 0) =
426 rt.left.sensorFrame2TcpFrame.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(3, 0) -
428 wrenchesMeasured.block<3, 1>(6, 0) =
429 rt.right.sensorFrame2TcpFrame.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(6, 0) -
431 wrenchesMeasured.block<3, 1>(9, 0) =
432 rt.right.sensorFrame2TcpFrame.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(9, 0) -
439 Eigen::Vector12f wrenchesMeasuredInRoot;
440 wrenchesMeasuredInRoot.block<3, 1>(0, 0) =
441 currentLeftPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(0, 0);
442 wrenchesMeasuredInRoot.block<3, 1>(3, 0) =
443 currentLeftPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(3, 0);
444 wrenchesMeasuredInRoot.block<3, 1>(6, 0) =
445 currentRightPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(6, 0);
446 wrenchesMeasuredInRoot.block<3, 1>(9, 0) =
447 currentRightPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(9, 0);
451 for (
size_t i = 0; i < 6; i++)
453 if (fabs(objFTValue(i)) < cfg.forceThreshold(i))
459 objFTValue(i) -= cfg.forceThreshold(i) * objFTValue(i) / fabs(objFTValue(i));
469 objPoseError.head<3>() = rt.virtualPose.block<3, 1>(0, 3) - boxPose.block<3, 1>(0, 3);
471 rt.virtualPose.block<3, 3>(0, 0) * boxPose.block<3, 3>(0, 0).transpose();
472 objPoseError.tail<3>() = VirtualRobot::MathTools::eigen3f2rpy(objDiffMat);
477 for (
size_t i = 0; i < 6; i++)
479 objAcc(i) = KmAdmittance(i) * objFTValue(i) - cfg.KpAdmittance(i) * objPoseError(i) -
480 cfg.KdAdmittance(i) * rt.virtualVel(i);
482 objVel = rt.virtualVel + 0.5 * deltaT * (objAcc + rt.virtualAcc);
483 const Eigen::Vector6f deltaObjPose = 0.5 * deltaT * (objVel + rt.virtualVel);
484 rt.virtualAcc = objAcc;
485 rt.virtualVel = objVel;
486 rt.virtualPose.block<3, 1>(0, 3) += deltaObjPose.head<3>();
487 rt.virtualPose.block<3, 3>(0, 0) = VirtualRobot::MathTools::rpy2eigen3f(
488 deltaObjPose(3), deltaObjPose(4), deltaObjPose(5)) *
489 rt.virtualPose.block<3, 3>(0, 0);
494 tcpTargetPoseLeft.block<3, 1>(0, 3) +=
495 rt.virtualPose.block<3, 3>(0, 0) *
496 (objCom2TCPLeft - deltaPoseForWrenchControl.block<3, 1>(0, 0));
497 tcpTargetPoseRight.block<3, 1>(0, 3) +=
498 rt.virtualPose.block<3, 3>(0, 0) *
499 (objCom2TCPRight - deltaPoseForWrenchControl.block<3, 1>(6, 0));
502 Eigen::Vector12f poseError;
504 tcpTargetPoseLeft.block<3, 3>(0, 0) * currentLeftPose.block<3, 3>(0, 0).transpose();
505 poseError.block<3, 1>(0, 0) =
506 tcpTargetPoseLeft.block<3, 1>(0, 3) - currentLeftPose.block<3, 1>(0, 3);
507 poseError.block<3, 1>(3, 0) = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
510 tcpTargetPoseRight.block<3, 3>(0, 0) * currentRightPose.block<3, 3>(0, 0).transpose();
511 poseError.block<3, 1>(6, 0) =
512 tcpTargetPoseRight.block<3, 1>(0, 3) - currentRightPose.block<3, 1>(0, 3);
513 poseError.block<3, 1>(9, 0) = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
515 Eigen::Vector12f forceImpedance;
516 for (
size_t i = 0; i < 12; i++)
519 cfg.KpImpedance(i) * poseError(i) - cfg.KdImpedance(i) * currentTwist(i);
524 const Eigen::VectorXf leftNullspaceTorque =
525 cfg.knull * (cfg.desiredJointValuesLeft - leftqpos) - cfg.dnull * leftqvel;
526 const Eigen::VectorXf rightNullspaceTorque =
527 cfg.knull * (cfg.desiredJointValuesRight - rightqpos) - cfg.dnull * rightqvel;
533 const auto setTargets =
534 [&](
auto& rtarm,
const auto& jacobi,
const auto& nullspaceTorque,
int forceImpOffset)
536 const Eigen::MatrixXf jtpinv =
537 rtarm.IK->computePseudoInverseJacobianMatrix(jacobi.transpose(), lambda);
538 const Eigen::VectorXf desiredJointTorques =
539 jacobi.transpose() * forceImpedance.block<6, 1>(forceImpOffset, 0) +
540 (I - jacobi.transpose() * jtpinv) * nullspaceTorque;
541 for (
size_t i = 0; i < rtarm.targets.size(); ++i)
543 float desiredTorque = desiredJointTorques(i);
544 if (isnan(desiredTorque))
548 desiredTorque = (desiredTorque > cfg.torqueLimit) ? cfg.torqueLimit : desiredTorque;
550 (desiredTorque < -cfg.torqueLimit) ? -cfg.torqueLimit : desiredTorque;
551 dbgOut.desired_torques[rtarm.jointNames[i]] = desiredJointTorques(i);
552 rtarm.targets.at(i)->torque = desiredTorque;
555 setTargets(rt.left, jacobiL, leftNullspaceTorque, 0);
556 setTargets(rt.right, jacobiR, rightNullspaceTorque, 6);
558 const Eigen::MatrixXf jtpinvL =
559 rt.left.IK->computePseudoInverseJacobianMatrix(jacobiL.transpose(), lambda);
560 const Eigen::VectorXf leftJointDesiredTorques =
561 jacobiL.transpose() * forceImpedance.head<6>() +
562 (I - jacobiL.transpose() * jtpinvL) * leftNullspaceTorque;
563 for (
size_t i = 0; i < rt.left.targets.size(); ++i)
565 float desiredTorque = leftJointDesiredTorques(i);
566 if (isnan(desiredTorque))
570 desiredTorque = (desiredTorque > cfg.torqueLimit) ? cfg.torqueLimit : desiredTorque;
572 (desiredTorque < -cfg.torqueLimit) ? -cfg.torqueLimit : desiredTorque;
573 dbgOut.desired_torques[rt.left.jointNames[i]] = leftJointDesiredTorques(i);
574 rt.left.targets.at(i)->torque = desiredTorque;
579 const Eigen::MatrixXf jtpinvR =
580 rt.right.IK->computePseudoInverseJacobianMatrix(jacobiR.transpose(), lambda);
581 const Eigen::VectorXf rightJointDesiredTorques =
582 jacobiR.transpose() * forceImpedance.tail<6>() +
583 (I - jacobiR.transpose() * jtpinvR) * rightNullspaceTorque;
584 for (
size_t i = 0; i < rt.right.targets.size(); ++i)
586 float desiredTorque = rightJointDesiredTorques(i);
587 if (isnan(desiredTorque))
591 desiredTorque = (desiredTorque > cfg.torqueLimit) ? cfg.torqueLimit : desiredTorque;
593 (desiredTorque < -cfg.torqueLimit) ? -cfg.torqueLimit : desiredTorque;
594 dbgOut.desired_torques[rt.right.jointNames[i]] = rightJointDesiredTorques(i);
595 rt.right.targets.at(i)->torque = desiredTorque;
600 dbgOut.currentBoxPose = currentBoxPose;
601 dbgOut.forceImpedance = forceImpedance;
602 dbgOut.poseError = poseError;
604 dbgOut.wrenchesMeasuredInRoot = wrenchesMeasuredInRoot;
608 dbgOut.virtualPose_x = rt.virtualPose(0, 3);
609 dbgOut.virtualPose_y = rt.virtualPose(1, 3);
610 dbgOut.virtualPose_z = rt.virtualPose(2, 3);
612 dbgOut.objPose_x = boxCurrentPose(0, 3);
613 dbgOut.objPose_y = boxCurrentPose(1, 3);
614 dbgOut.objPose_z = boxCurrentPose(2, 3);
616 dbgOut.objForce_x = objFTValue(0);
617 dbgOut.objForce_y = objFTValue(1);
618 dbgOut.objForce_z = objFTValue(2);
619 dbgOut.objTorque_x = objFTValue(3);
620 dbgOut.objTorque_y = objFTValue(4);
621 dbgOut.objTorque_z = objFTValue(5);
623 dbgOut.objVel_x = objVel(0);
624 dbgOut.objVel_y = objVel(1);
625 dbgOut.objVel_z = objVel(2);
626 dbgOut.objVel_rx = objVel(3);
627 dbgOut.objVel_ry = objVel(4);
628 dbgOut.objVel_rz = objVel(5);
630 dbgOut.deltaPose_x = deltaObjPose(0);
631 dbgOut.deltaPose_y = deltaObjPose(1);
632 dbgOut.deltaPose_z = deltaObjPose(2);
633 dbgOut.deltaPose_rx = deltaObjPose(3);
634 dbgOut.deltaPose_ry = deltaObjPose(4);
635 dbgOut.deltaPose_rz = deltaObjPose(5);
637 dbgOut.modifiedPoseRight_x = tcpTargetPoseRight(0, 3);
638 dbgOut.modifiedPoseRight_y = tcpTargetPoseRight(1, 3);
639 dbgOut.modifiedPoseRight_z = tcpTargetPoseRight(2, 3);
641 dbgOut.currentPoseLeft_x = currentLeftPose(0, 3);
642 dbgOut.currentPoseLeft_y = currentLeftPose(1, 3);
643 dbgOut.currentPoseLeft_z = currentLeftPose(2, 3);
646 dbgOut.modifiedPoseLeft_x = tcpTargetPoseLeft(0, 3);
647 dbgOut.modifiedPoseLeft_y = tcpTargetPoseLeft(1, 3);
648 dbgOut.modifiedPoseLeft_z = tcpTargetPoseLeft(2, 3);
650 dbgOut.currentPoseRight_x = currentRightPose(0, 3);
651 dbgOut.currentPoseRight_y = currentRightPose(1, 3);
652 dbgOut.currentPoseRight_z = currentRightPose(2, 3);
655 dbgOut.dmpBoxPose_x = boxPose(0, 3);
656 dbgOut.dmpBoxPose_y = boxPose(1, 3);
657 dbgOut.dmpBoxPose_z = boxPose(2, 3);
659 dbgOut.dmpTwist_x = boxTwist(0);
660 dbgOut.dmpTwist_y = boxTwist(1);
661 dbgOut.dmpTwist_z = boxTwist(2);
662 dbgOut.rx = rRight(0);
663 dbgOut.ry = rRight(1);
664 dbgOut.rz = rRight(2);
684 std::lock_guard guard{debugOutputDataReadMutex};
688 for (
const auto& [name, val] : buf.desired_torques)
690 datafields[name] =
new Variant(val);
693 const auto& reportElements = [&](
const auto& vec,
const std::string& pre)
695 for (
int i = 0; i < vec.rows(); ++i)
700 reportElements(buf.forceImpedance,
"forceImpedance_");
701 reportElements(buf.forcePID,
"forcePID_");
702 reportElements(buf.poseError,
"poseError_");
703 reportElements(buf.wrenchesConstrained,
"wrenchesConstrained_");
704 reportElements(buf.wrenchesMeasuredInRoot,
"wrenchesMeasuredInRoot_");
705 reportElements(buf.wrenchesConstrained,
"wrenchesConstrained_");
706 reportElements(buf.wrenchesConstrained,
"wrenchesConstrained_");
708 datafields[
"virtualPose_x"] =
new Variant(buf.virtualPose_x);
709 datafields[
"virtualPose_y"] =
new Variant(buf.virtualPose_y);
710 datafields[
"virtualPose_z"] =
new Variant(buf.virtualPose_z);
712 datafields[
"objPose_x"] =
new Variant(buf.objPose_x);
713 datafields[
"objPose_y"] =
new Variant(buf.objPose_y);
714 datafields[
"objPose_z"] =
new Variant(buf.objPose_z);
716 datafields[
"objForce_x"] =
new Variant(buf.objForce_x);
717 datafields[
"objForce_y"] =
new Variant(buf.objForce_y);
718 datafields[
"objForce_z"] =
new Variant(buf.objForce_z);
719 datafields[
"objTorque_x"] =
new Variant(buf.objTorque_x);
720 datafields[
"objTorque_y"] =
new Variant(buf.objTorque_y);
721 datafields[
"objTorque_z"] =
new Variant(buf.objTorque_z);
723 datafields[
"objVel_x"] =
new Variant(buf.objVel_x);
724 datafields[
"objVel_y"] =
new Variant(buf.objVel_y);
725 datafields[
"objVel_z"] =
new Variant(buf.objVel_z);
726 datafields[
"objVel_rx"] =
new Variant(buf.objVel_rx);
727 datafields[
"objVel_ry"] =
new Variant(buf.objVel_ry);
728 datafields[
"objVel_rz"] =
new Variant(buf.objVel_rz);
730 datafields[
"deltaPose_x"] =
new Variant(buf.deltaPose_x);
731 datafields[
"deltaPose_y"] =
new Variant(buf.deltaPose_y);
732 datafields[
"deltaPose_z"] =
new Variant(buf.deltaPose_z);
733 datafields[
"deltaPose_rx"] =
new Variant(buf.deltaPose_rx);
734 datafields[
"deltaPose_ry"] =
new Variant(buf.deltaPose_ry);
735 datafields[
"deltaPose_rz"] =
new Variant(buf.deltaPose_rz);
737 datafields[
"modifiedPoseRight_x"] =
new Variant(buf.modifiedPoseRight_x);
738 datafields[
"modifiedPoseRight_y"] =
new Variant(buf.modifiedPoseRight_y);
739 datafields[
"modifiedPoseRight_z"] =
new Variant(buf.modifiedPoseRight_z);
740 datafields[
"currentPoseLeft_x"] =
new Variant(buf.currentPoseLeft_x);
741 datafields[
"currentPoseLeft_y"] =
new Variant(buf.currentPoseLeft_y);
742 datafields[
"currentPoseLeft_z"] =
new Variant(buf.currentPoseLeft_z);
745 datafields[
"modifiedPoseLeft_x"] =
new Variant(buf.modifiedPoseLeft_x);
746 datafields[
"modifiedPoseLeft_y"] =
new Variant(buf.modifiedPoseLeft_y);
747 datafields[
"modifiedPoseLeft_z"] =
new Variant(buf.modifiedPoseLeft_z);
749 datafields[
"currentPoseRight_x"] =
new Variant(buf.currentPoseRight_x);
750 datafields[
"currentPoseRight_y"] =
new Variant(buf.currentPoseRight_y);
751 datafields[
"currentPoseRight_z"] =
new Variant(buf.currentPoseRight_z);
752 datafields[
"dmpBoxPose_x"] =
new Variant(buf.dmpBoxPose_x);
753 datafields[
"dmpBoxPose_y"] =
new Variant(buf.dmpBoxPose_y);
754 datafields[
"dmpBoxPose_z"] =
new Variant(buf.dmpBoxPose_z);
755 datafields[
"dmpTwist_x"] =
new Variant(buf.dmpTwist_x);
756 datafields[
"dmpTwist_y"] =
new Variant(buf.dmpTwist_y);
757 datafields[
"dmpTwist_z"] =
new Variant(buf.dmpTwist_z);
759 datafields[
"modifiedTwist_lx"] =
new Variant(buf.modifiedTwist_lx);
760 datafields[
"modifiedTwist_ly"] =
new Variant(buf.modifiedTwist_ly);
761 datafields[
"modifiedTwist_lz"] =
new Variant(buf.modifiedTwist_lz);
762 datafields[
"modifiedTwist_rx"] =
new Variant(buf.modifiedTwist_rx);
763 datafields[
"modifiedTwist_ry"] =
new Variant(buf.modifiedTwist_ry);
764 datafields[
"modifiedTwist_rz"] =
new Variant(buf.modifiedTwist_rz);
766 datafields[
"rx"] =
new Variant(buf.rx);
767 datafields[
"ry"] =
new Variant(buf.ry);
768 datafields[
"rz"] =
new Variant(buf.rz);
771 debugObs->setDebugChannel(
"BimanualForceController", datafields);
777 std::lock_guard guard{debugOutputDataReadMutex};
786 std::lock_guard guard{targBufWriteMutex};
795 std::lock_guard{cfgBufWriteMutex};
802 const Eigen::Vector3f& velRPY,
807 std::lock_guard guard{targBufWriteMutex};
816 const Eigen::Vector3f& velXYZ,
817 const Eigen::Vector3f& velRPY,
823 std::lock_guard guard{targBufWriteMutex};
835 std::lock_guard guard{targBufWriteMutex};
846 std::lock_guard guard{targBufWriteMutex};
853 const NJointBimanualCartesianAdmittanceControllerConfigPtr& ptr,
857 ARMARX_CHECK_EQUAL(ptr->nullspace.desiredJointValuesLeft.size(), rt.left.targets.size());
858 ARMARX_CHECK_EQUAL(ptr->nullspace.desiredJointValuesRight.size(), rt.right.targets.size());
859 std::lock_guard{cfgBufWriteMutex};
866 const Ice::FloatSeq& vals,
869 std::lock_guard{cfgBufWriteMutex};
876 const Ice::FloatSeq& vals,
879 std::lock_guard{cfgBufWriteMutex};
889 std::lock_guard{cfgBufWriteMutex};
899 std::lock_guard{cfgBufWriteMutex};
910 std::lock_guard{cfgBufWriteMutex};
921 std::lock_guard{cfgBufWriteMutex};
930 std::lock_guard{cfgBufWriteMutex};
944 const Ice::FloatSeq& vals)
946 std::lock_guard{cfgBufWriteMutex};
949 buf.desiredJointValuesLeft = Eigen::Map<const Eigen::VectorXf>(vals.data(), vals.size());
954 const Ice::FloatSeq& vals)
956 std::lock_guard{cfgBufWriteMutex};
959 buf.desiredJointValuesRight = Eigen::Map<const Eigen::VectorXf>(vals.data(), vals.size());
966 std::lock_guard{cfgBufWriteMutex};
970 cfg.knull = nullspace.
k;
971 cfg.dnull = nullspace.
d;
978 std::lock_guard{cfgBufWriteMutex};
980 cfg.KmAdmittance.block<3, 1>(0, 0) = admittanceObject.
KmXYZ;
981 cfg.KmAdmittance.block<3, 1>(3, 0) = admittanceObject.
KmRPY;
983 cfg.KpAdmittance.block<3, 1>(0, 0) = admittanceObject.
KpXYZ;
984 cfg.KpAdmittance.block<3, 1>(3, 0) = admittanceObject.
KpRPY;
986 cfg.KdAdmittance.block<3, 1>(0, 0) = admittanceObject.
KdXYZ;
987 cfg.KdAdmittance.block<3, 1>(3, 0) = admittanceObject.
KdRPY;
995 std::lock_guard{cfgBufWriteMutex};
998 cfg.massLeft = forceLeft.
mass;
999 cfg.CoMVecLeft = forceLeft.
com;
1002 cfg.targetWrench.block<3, 1>(0, 0) = forceLeft.
wrenchXYZ;
1003 cfg.targetWrench.block<3, 1>(3, 0) = forceLeft.
wrenchRPY;
1006 cfg.massRight = forceRight.
mass;
1007 cfg.CoMVecRight = forceRight.
com;
1010 cfg.targetWrench.block<3, 1>(6, 0) = forceRight.
wrenchXYZ;
1011 cfg.targetWrench.block<3, 1>(9, 0) = forceRight.
wrenchRPY;
1012 cfg.forceThreshold.block<3, 1>(3, 0) = forceRight.
forceThreshold;
1020 std::lock_guard{cfgBufWriteMutex};
1022 cfg.KpImpedance.block<3, 1>(0, 0) = impedanceLeft.
KpXYZ;
1023 cfg.KpImpedance.block<3, 1>(3, 0) = impedanceLeft.
KpRPY;
1024 cfg.KpImpedance.block<3, 1>(6, 0) = impedanceRight.
KpXYZ;
1025 cfg.KpImpedance.block<3, 1>(9, 0) = impedanceRight.
KpRPY;
1027 cfg.KdImpedance.block<3, 1>(0, 0) = impedanceLeft.
KdXYZ;
1028 cfg.KdImpedance.block<3, 1>(3, 0) = impedanceLeft.
KdRPY;
1029 cfg.KdImpedance.block<3, 1>(6, 0) = impedanceRight.
KdXYZ;
1030 cfg.KdImpedance.block<3, 1>(9, 0) = impedanceRight.
KdRPY;