244 const IceUtil::Time& timeSinceLastIteration)
247 const Eigen::Matrix4f currentLeftPose =
248 simox::math::scaled_position(rt.left.tcp->getPoseInRootFrame(), 0.001);
249 const Eigen::Matrix4f currentRightPose =
250 simox::math::scaled_position(rt.right.tcp->getPoseInRootFrame(), 0.001);
251 const Eigen::Matrix4f currentBoxPose = [&]
253 Eigen::Matrix4f pose = Eigen::Matrix4f::Identity();
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;
275 if (cfgBuf.updateReadBuffer())
277 auto& cfg = cfgBuf._getNonConstReadBuffer();
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;
287 auto& trg = targBuf._getNonConstReadBuffer();
288 trg.pose = currentBoxPose;
291 auto& dbgOut = debugOutputData.getWriteBuffer();
292 const auto& targ = targBuf.getWriteBuffer();
293 const auto& cfg = cfgBuf.getReadBuffer();
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)
318 Eigen::Matrix3f mat = Eigen::MatrixXf::Zero(3, 3);
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();
332 graspMatrix.block<3, 3>(0, 0) = Eigen::MatrixXf::Identity(3, 3);
333 graspMatrix.block<3, 3>(0, 6) = Eigen::MatrixXf::Identity(3, 3);
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);
350 Eigen::Matrix4f boxCurrentPose = currentRightPose;
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 =
357 Eigen::MatrixXf::Identity(rt.left.targets.size(), rt.left.targets.size());
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));
464 const Eigen::Matrix4f boxPose = targ.pose;
469 objPoseError.head<3>() = rt.virtualPose.block<3, 1>(0, 3) - boxPose.block<3, 1>(0, 3);
470 const Eigen::Matrix3f objDiffMat =
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);
492 Eigen::Matrix4f tcpTargetPoseLeft = rt.virtualPose;
493 Eigen::Matrix4f tcpTargetPoseRight = rt.virtualPose;
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;
503 Eigen::Matrix3f diffMat =
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);
675 debugOutputData.commitWrite();