8 #include <VirtualRobot/IK/DifferentialIK.h>
9 #include <VirtualRobot/MathTools.h>
10 #include <VirtualRobot/Nodes/RobotNode.h>
11 #include <VirtualRobot/Robot.h>
12 #include <VirtualRobot/RobotNodeSet.h>
25 NJointControllerRegistration<NJointBimanualObjLevelMultiMPController>
27 "NJointBimanualObjLevelMultiMPController");
31 const armarx::NJointControllerConfigPtr& config,
34 ARMARX_INFO <<
"Initializing Bimanual Object Level Controller";
38 cfg = NJointBimanualObjLevelMultiMPControllerConfigPtr::dynamicCast(config);
40 leftRNS =
rtGetRobot()->getRobotNodeSet(
"LeftArm");
42 for (
size_t i = 0; i < leftRNS->getSize(); ++i)
44 std::string jointName = leftRNS->getNode(i)->getName();
45 leftJointNames.push_back(jointName);
48 leftTargets.push_back(ct->
asA<ControlTarget1DoFActuatorTorque>());
49 const SensorValue1DoFActuatorVelocity* velocitySensor =
50 sv->
asA<SensorValue1DoFActuatorVelocity>();
51 const SensorValue1DoFActuatorPosition* positionSensor =
52 sv->
asA<SensorValue1DoFActuatorPosition>();
64 leftVelocitySensors.push_back(velocitySensor);
65 leftPositionSensors.push_back(positionSensor);
68 rightRNS =
rtGetRobot()->getRobotNodeSet(
"RightArm");
70 for (
size_t i = 0; i < rightRNS->getSize(); ++i)
72 std::string jointName = rightRNS->getNode(i)->getName();
73 rightJointNames.push_back(jointName);
76 rightTargets.push_back(ct->
asA<ControlTarget1DoFActuatorTorque>());
78 const SensorValue1DoFActuatorVelocity* velocitySensor =
79 sv->
asA<SensorValue1DoFActuatorVelocity>();
80 const SensorValue1DoFActuatorPosition* positionSensor =
81 sv->
asA<SensorValue1DoFActuatorPosition>();
92 rightVelocitySensors.push_back(velocitySensor);
93 rightPositionSensors.push_back(positionSensor);
97 const SensorValueBase* svlf = robUnit->getSensorDevice(
"FT L")->getSensorValue();
99 const SensorValueBase* svrf = robUnit->getSensorDevice(
"FT R")->getSensorValue();
102 leftIK.reset(
new VirtualRobot::DifferentialIK(
103 leftRNS, leftRNS->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
104 rightIK.reset(
new VirtualRobot::DifferentialIK(rightRNS,
105 rightRNS->getRobot()->getRootNode(),
106 VirtualRobot::JacobiProvider::eSVDDamped));
108 tcpLeft = leftRNS->getTCP();
109 tcpRight = rightRNS->getTCP();
114 taskSpaceDMPConfig.
DMPMode = cfg->dmpMode;
127 taskSpaceDMPConfig.
DMPStyle = cfg->dmpObjType;
129 taskSpaceDMPConfig.
DMPStyle = cfg->dmpLeftType;
130 leftTCPInObjDMP.reset(
132 taskSpaceDMPConfig.
DMPStyle = cfg->dmpRightType;
133 rightTCPInObjDMP.reset(
138 auto setParamVec = [&](Eigen::VectorXf& param, ::Ice::FloatSeq& cfgParam,
const size_t n)
143 for (
size_t i = 0; i < n; ++i)
145 param(i) = cfgParam.at(i);
149 setParamVec(KpImpedance, cfg->KpImpedance, 12);
150 setParamVec(KdImpedance, cfg->KdImpedance, 12);
151 setParamVec(KpAdmittance, cfg->KpAdmittance, 6);
152 setParamVec(KdAdmittance, cfg->KdAdmittance, 6);
153 setParamVec(KmAdmittance, cfg->KmAdmittance, 6);
154 setParamVec(KmPID, cfg->KmPID, 6);
159 leftDesiredJointValues.resize(leftTargets.size());
162 for (
size_t i = 0; i < leftTargets.size(); ++i)
164 leftDesiredJointValues(i) = cfg->leftDesiredJointValues.at(i);
167 rightDesiredJointValues.resize(rightTargets.size());
170 for (
size_t i = 0; i < rightTargets.size(); ++i)
172 rightDesiredJointValues(i) = cfg->rightDesiredJointValues.at(i);
177 objInitialPose = VirtualRobot::MathTools::quat2eigen4f(cfg->objInitialPose[4],
178 cfg->objInitialPose[5],
179 cfg->objInitialPose[6],
180 cfg->objInitialPose[3]);
181 for (
int i = 0; i < 3; ++i)
183 objInitialPose(i, 3) = cfg->objInitialPose[i];
186 virtualAcc.setZero(6);
187 virtualVel.setZero(6);
188 virtualPose = objInitialPose;
197 leftInitialPose.block<3, 3>(0, 0) =
198 objInitialPose.block<3, 3>(0, 0).transpose() * leftPose.block<3, 3>(0, 0);
199 leftInitialPose.block<3, 1>(0, 3) =
200 objInitialPose.block<3, 3>(0, 0).transpose() *
201 (leftPose.block<3, 1>(0, 3) * 0.001 - objInitialPose.block<3, 1>(0, 3));
202 rightInitialPose.block<3, 3>(0, 0) =
203 objInitialPose.block<3, 3>(0, 0).transpose() * rightPose.block<3, 3>(0, 0);
204 rightInitialPose.block<3, 1>(0, 3) =
205 objInitialPose.block<3, 3>(0, 0).transpose() *
206 (rightPose.block<3, 1>(0, 3) * 0.001 - objInitialPose.block<3, 1>(0, 3));
208 integratedPoseObj = virtualPose;
209 integratedPoseLeft = leftInitialPose;
210 integratedPoseRight = rightInitialPose;
213 Inferface2rtData interface2rtData;
214 interface2rtData.KpImpedance = KpImpedance;
215 interface2rtData.KdImpedance = KdImpedance;
216 interface2rtData.KmAdmittance = KmAdmittance;
217 interface2rtData.KpAdmittance = KpAdmittance;
218 interface2rtData.KdAdmittance = KdAdmittance;
222 RT2ControlData rt2ControlData;
223 rt2ControlData.deltaT = 0;
224 rt2ControlData.currentTime = 0;
225 rt2ControlData.currentPoseObj = objInitialPose;
226 rt2ControlData.currentTwistObj.setZero();
227 rt2ControlData.currentPoseObj = leftInitialPose;
228 rt2ControlData.currentTwistObj.setZero();
229 rt2ControlData.currentPoseObj = rightInitialPose;
230 rt2ControlData.currentTwistObj.setZero();
246 RT2InterfaceData rt2InterfaceData;
247 rt2InterfaceData.currentLeftPoseInObjFrame = leftInitialPose;
248 rt2InterfaceData.currentRightPoseInObjFrame = rightInitialPose;
249 rt2InterfaceData.currentObjPose = objInitialPose;
250 rt2InterfaceData.currentObjForce.setZero();
251 rt2InterfaceData.currentObjVel.setZero();
256 forcePIDControllers.resize(12);
257 for (
size_t i = 0; i < 6; i++)
260 cfg->forceP[i], cfg->forceI[i], cfg->forceD[i], cfg->forcePIDLimits[i]));
262 cfg->forceP[i], cfg->forceI[i], cfg->forceD[i], cfg->forcePIDLimits[i]));
263 forcePIDControllers.at(i)->reset();
264 forcePIDControllers.at(i + 6)->reset();
269 sensorFrame2TcpFrameLeft.setZero();
270 sensorFrame2TcpFrameRight.setZero();
273 filterCoeff = cfg->filterCoeff;
274 filteredOldValue.setZero(12);
277 ftcalibrationTimer = 0;
278 ftOffset.setZero(12);
281 targetWrench.setZero(cfg->targetWrench.size());
282 for (
size_t i = 0; i < cfg->targetWrench.size(); ++i)
284 targetWrench(i) = cfg->targetWrench[i];
288 massLeft = cfg->massLeft;
289 CoMVecLeft << cfg->CoMVecLeft[0], cfg->CoMVecLeft[1], cfg->CoMVecLeft[2];
290 forceOffsetLeft << cfg->forceOffsetLeft[0], cfg->forceOffsetLeft[1],
291 cfg->forceOffsetLeft[2];
292 torqueOffsetLeft << cfg->torqueOffsetLeft[0], cfg->torqueOffsetLeft[1],
293 cfg->torqueOffsetLeft[2];
295 massRight = cfg->massRight;
296 CoMVecRight << cfg->CoMVecRight[0], cfg->CoMVecRight[1], cfg->CoMVecRight[2];
297 forceOffsetRight << cfg->forceOffsetRight[0], cfg->forceOffsetRight[1],
298 cfg->forceOffsetRight[2];
299 torqueOffsetRight << cfg->torqueOffsetRight[0], cfg->torqueOffsetRight[1],
300 cfg->torqueOffsetRight[2];
304 objCom2TCPLeftInObjFrame.setZero();
305 objCom2TCPRightInObjFrame.setZero();
321 return "NJointBimanualObjLevelMultiMPController";
335 Eigen::VectorXf currentTwistObj = rt2ControlBuffer.
getReadBuffer().currentTwistObj;
338 Eigen::VectorXf currentTwistLeftInObj =
342 Eigen::VectorXf currentTwistRightInObj =
346 rightTCPInObjDMP->flow(deltaT, currentPoseRightInObj, currentTwistRightInObj);
349 bool objectDMPFinished =
false;
350 bool leftTCPInObjDMPFinished =
false;
351 bool rightTCPInObjDMPFinished =
false;
353 if (objectDMP->canVal > 1e-8 || objectDMP->config.DMPStyle ==
"Periodic")
355 objectDMP->flow(deltaT, currentPoseObj, currentTwistObj);
361 objectDMPFinished =
true;
365 if (leftTCPInObjDMP->canVal > 1e-8 || leftTCPInObjDMP->config.DMPStyle ==
"Periodic")
367 leftTCPInObjDMP->flow(deltaT, currentPoseLeftInObj, currentTwistLeftInObj);
373 leftTCPInObjDMPFinished =
true;
376 if (rightTCPInObjDMP->canVal > 1e-8 || rightTCPInObjDMP->config.DMPStyle ==
"Periodic")
378 rightTCPInObjDMP->flow(deltaT, currentPoseRightInObj, currentTwistRightInObj);
384 rightTCPInObjDMPFinished =
true;
388 if (objectDMPFinished && leftTCPInObjDMPFinished && rightTCPInObjDMPFinished)
407 currentLeftPose.block<3, 1>(0, 3) = 0.001 * currentLeftPose.block<3, 1>(0, 3);
408 currentRightPose.block<3, 1>(0, 3) = 0.001 * currentRightPose.block<3, 1>(0, 3);
410 double deltaT = timeSinceLastIteration.toSecondsDouble();
411 ftcalibrationTimer += deltaT;
418 Eigen::Vector3f objCom2TCPLeftInGlobal =
419 leftPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
420 Eigen::Vector3f objCom2TCPRightInGlobal =
421 rightPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
425 objTransMatrixInAnchor.block<3, 3>(0, 0) =
426 leftPose.block<3, 3>(0, 0).transpose() * objInitialPose.block<3, 3>(0, 0);
427 objTransMatrixInAnchor.block<3, 1>(0, 3) =
428 leftPose.block<3, 3>(0, 0).transpose() *
429 (objInitialPose.block<3, 1>(0, 3) - leftPose.block<3, 1>(0, 3));
431 objCom2TCPLeftInObjFrame =
432 virtualPose.block<3, 3>(0, 0).
transpose() * objCom2TCPLeftInGlobal;
433 objCom2TCPRightInObjFrame =
434 virtualPose.block<3, 3>(0, 0).
transpose() * objCom2TCPRightInGlobal;
438 leftRNS->getRobot()->getRobotNode(
"ArmL8_Wri2")->getPoseInRootFrame();
440 rightRNS->getRobot()->getRobotNode(
"ArmR8_Wri2")->getPoseInRootFrame();
441 leftSensorFrame.block<3, 1>(0, 3) = leftSensorFrame.block<3, 1>(0, 3) * 0.001;
442 rightSensorFrame.block<3, 1>(0, 3) = rightSensorFrame.block<3, 1>(0, 3) * 0.001;
445 sensorFrame2TcpFrameLeft.block<3, 3>(0, 0) =
446 leftPose.block<3, 3>(0, 0).transpose() * leftSensorFrame.block<3, 3>(0, 0);
447 sensorFrame2TcpFrameRight.block<3, 3>(0, 0) =
448 rightPose.block<3, 3>(0, 0).transpose() * rightSensorFrame.block<3, 3>(0, 0);
449 CoMVecLeft = sensorFrame2TcpFrameLeft.block<3, 3>(0, 0) * CoMVecLeft;
450 CoMVecRight = sensorFrame2TcpFrameRight.block<3, 3>(0, 0) * CoMVecRight;
456 currentLeftPoseInObjFrame.block<3, 3>(0, 0) =
457 virtualPose.block<3, 3>(0, 0).transpose() * currentLeftPose.block<3, 3>(0, 0);
458 currentLeftPoseInObjFrame.block<3, 1>(0, 3) =
459 virtualPose.block<3, 3>(0, 0).transpose() *
460 (currentLeftPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3));
461 currentRightPoseInObjFrame.block<3, 3>(0, 0) =
462 virtualPose.block<3, 3>(0, 0).transpose() * currentRightPose.block<3, 3>(0, 0);
463 currentRightPoseInObjFrame.block<3, 1>(0, 3) =
464 virtualPose.block<3, 3>(0, 0).transpose() *
465 (currentRightPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3));
466 rt2InterfaceBuffer.
getWriteBuffer().currentLeftPoseInObjFrame = currentLeftPoseInObjFrame;
467 rt2InterfaceBuffer.
getWriteBuffer().currentRightPoseInObjFrame = currentRightPoseInObjFrame;
477 if (ftcalibrationTimer < cfg->ftCalibrationTime)
479 ftOffset.block<3, 1>(0, 0) =
480 0.5 * ftOffset.block<3, 1>(0, 0) + 0.5 * leftForceTorque->
force;
481 ftOffset.block<3, 1>(3, 0) =
482 0.5 * ftOffset.block<3, 1>(3, 0) + 0.5 * leftForceTorque->
torque;
483 ftOffset.block<3, 1>(6, 0) =
484 0.5 * ftOffset.block<3, 1>(6, 0) + 0.5 * rightForceTorque->
force;
485 ftOffset.block<3, 1>(9, 0) =
486 0.5 * ftOffset.block<3, 1>(9, 0) + 0.5 * rightForceTorque->
torque;
488 for (
int i = 0; i < KmAdmittance.size(); ++i)
495 for (
int i = 0; i < KmAdmittance.size(); ++i)
497 KmAdmittance(i) = cfg->KmAdmittance.at(i);
502 Eigen::VectorXf deltaPoseForWrenchControl;
503 deltaPoseForWrenchControl.setZero(12);
504 for (
size_t i = 0; i < 12; ++i)
506 if (KpImpedance(i) == 0)
508 deltaPoseForWrenchControl(i) = 0;
512 deltaPoseForWrenchControl(i) = targetWrench(i) / KpImpedance(i);
513 if (deltaPoseForWrenchControl(i) > 0.1)
515 deltaPoseForWrenchControl(i) = 0.1;
517 else if (deltaPoseForWrenchControl(i) < -0.1)
519 deltaPoseForWrenchControl(i) = -0.1;
528 Eigen::Vector3f objCom2TCPLeftInGlobal =
529 currentLeftPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
530 Eigen::Vector3f objCom2TCPRightInGlobal =
531 currentRightPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
533 Eigen::MatrixXf graspMatrix;
534 graspMatrix.setZero(6, 12);
541 graspMatrix.block<3, 3>(3, 0) =
skew(objCom2TCPLeftInGlobal);
544 graspMatrix.block<3, 3>(3, 6) =
skew(objCom2TCPRightInGlobal);
551 Eigen::MatrixXf pinvGraspMatrixT =
552 leftIK->computePseudoInverseJacobianMatrix(graspMatrix.transpose(), lambda);
555 Eigen::Matrix4f objCurrentPose = currentLeftPose * objTransMatrixInAnchor;
556 Eigen::VectorXf objCurrentTwist;
558 objCurrentTwist.setZero(6);
563 Eigen::MatrixXf jacobiL =
564 leftIK->getJacobianMatrix(tcpLeft, VirtualRobot::IKSolver::CartesianSelection::All);
565 Eigen::MatrixXf jacobiR =
566 rightIK->getJacobianMatrix(tcpRight, VirtualRobot::IKSolver::CartesianSelection::All);
567 jacobiL.block<3, 8>(0, 0) = 0.001 * jacobiL.block<3, 8>(0, 0);
568 jacobiR.block<3, 8>(0, 0) = 0.001 * jacobiR.block<3, 8>(0, 0);
571 Eigen::VectorXf leftqpos;
572 Eigen::VectorXf leftqvel;
573 leftqpos.resize(leftPositionSensors.size());
574 leftqvel.resize(leftVelocitySensors.size());
575 for (
size_t i = 0; i < leftVelocitySensors.size(); ++i)
577 leftqpos(i) = leftPositionSensors[i]->position;
578 leftqvel(i) = leftVelocitySensors[i]->velocity;
581 Eigen::VectorXf rightqpos;
582 Eigen::VectorXf rightqvel;
583 rightqpos.resize(rightPositionSensors.size());
584 rightqvel.resize(rightVelocitySensors.size());
586 for (
size_t i = 0; i < rightVelocitySensors.size(); ++i)
588 rightqpos(i) = rightPositionSensors[i]->position;
589 rightqvel(i) = rightVelocitySensors[i]->velocity;
593 Eigen::VectorXf currentLeftTwist = jacobiL * leftqvel;
594 Eigen::VectorXf currentRightTwist = jacobiR * rightqvel;
596 Eigen::VectorXf currentTwist(12);
597 currentTwist << currentLeftTwist, currentRightTwist;
598 objCurrentTwist = pinvGraspMatrixT * currentTwist;
600 rt2ControlBuffer.
getWriteBuffer().currentPoseObj = objCurrentPose;
601 rt2ControlBuffer.
getWriteBuffer().currentTwistObj = objCurrentTwist;
608 Eigen::Vector3f gravity;
609 gravity << 0.0, 0.0, -9.8;
610 Eigen::Vector3f localGravityLeft = currentLeftPose.block<3, 3>(0, 0).
transpose() * gravity;
611 Eigen::Vector3f localForceVecLeft = massLeft * localGravityLeft;
612 Eigen::Vector3f localTorqueVecLeft = CoMVecLeft.cross(localForceVecLeft);
614 Eigen::Vector3f localGravityRight =
615 currentRightPose.block<3, 3>(0, 0).
transpose() * gravity;
616 Eigen::Vector3f localForceVecRight = massRight * localGravityRight;
617 Eigen::Vector3f localTorqueVecRight = CoMVecRight.cross(localForceVecRight);
620 Eigen::VectorXf wrenchesMeasured(12);
621 wrenchesMeasured << leftForceTorque->
force - forceOffsetLeft,
622 leftForceTorque->
torque - torqueOffsetLeft, rightForceTorque->
force - forceOffsetRight,
623 rightForceTorque->
torque - torqueOffsetRight;
624 for (
size_t i = 0; i < 12; i++)
626 wrenchesMeasured(i) =
627 (1 - filterCoeff) * wrenchesMeasured(i) + filterCoeff * filteredOldValue(i);
629 filteredOldValue = wrenchesMeasured;
630 wrenchesMeasured.block<3, 1>(0, 0) =
631 sensorFrame2TcpFrameLeft.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(0, 0) -
633 wrenchesMeasured.block<3, 1>(3, 0) =
634 sensorFrame2TcpFrameLeft.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(3, 0) -
636 wrenchesMeasured.block<3, 1>(6, 0) =
637 sensorFrame2TcpFrameRight.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(6, 0) -
639 wrenchesMeasured.block<3, 1>(9, 0) =
640 sensorFrame2TcpFrameRight.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(9, 0) -
647 Eigen::VectorXf forceTorqueMeasurementInRoot(12);
648 forceTorqueMeasurementInRoot.block<3, 1>(0, 0) =
649 currentLeftPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(0, 0);
650 forceTorqueMeasurementInRoot.block<3, 1>(3, 0) =
651 currentLeftPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(3, 0);
652 forceTorqueMeasurementInRoot.block<3, 1>(6, 0) =
653 currentRightPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(6, 0);
654 forceTorqueMeasurementInRoot.block<3, 1>(9, 0) =
655 currentRightPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(9, 0);
659 Eigen::VectorXf objFTValue = graspMatrix * forceTorqueMeasurementInRoot;
660 for (
size_t i = 0; i < 6; i++)
662 if (fabs(objFTValue(i)) < cfg->forceThreshold.at(i))
668 objFTValue(i) -= cfg->forceThreshold.at(i) * objFTValue(i) / fabs(objFTValue(i));
673 rt2InterfaceBuffer.
getWriteBuffer().currentObjPose = objCurrentPose;
674 rt2InterfaceBuffer.
getWriteBuffer().currentObjVel = objCurrentTwist.head<3>();
675 rt2InterfaceBuffer.
getWriteBuffer().currentObjForce = objFTValue.head<3>();
696 Eigen::VectorXf objPoseError(6);
697 objPoseError.head<3>() = virtualPose.block<3, 1>(0, 3) - objTargetPose.block<3, 1>(0, 3);
699 virtualPose.block<3, 3>(0, 0) * objTargetPose.block<3, 3>(0, 0).transpose();
700 objPoseError.tail<3>() = VirtualRobot::MathTools::eigen3f2rpy(objDiffMat);
703 Eigen::VectorXf objAcc;
704 Eigen::VectorXf objVel;
707 for (
size_t i = 0; i < 6; i++)
710 objAcc(i) = KmAdmittance(i) * objFTValue(i) - KpAdmittance(i) * objPoseError(i) -
711 KdAdmittance(i) * virtualVel(i);
713 objVel = virtualVel + 0.5 * deltaT * (objAcc + virtualAcc);
714 Eigen::VectorXf deltaObjPose = 0.5 * deltaT * (objVel + virtualVel);
717 virtualPose.block<3, 1>(0, 3) += deltaObjPose.head<3>();
718 virtualPose.block<3, 3>(0, 0) = VirtualRobot::MathTools::rpy2eigen3f(
719 deltaObjPose(3), deltaObjPose(4), deltaObjPose(5)) *
720 virtualPose.block<3, 3>(0, 0);
731 Eigen::VectorXf poseError(12);
733 tcpTargetPoseLeft.block<3, 3>(0, 0) * currentLeftPose.block<3, 3>(0, 0).transpose();
734 poseError.block<3, 1>(0, 0) =
735 tcpTargetPoseLeft.block<3, 1>(0, 3) - currentLeftPose.block<3, 1>(0, 3);
736 poseError.block<3, 1>(3, 0) = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
739 tcpTargetPoseRight.block<3, 3>(0, 0) * currentRightPose.block<3, 3>(0, 0).transpose();
740 poseError.block<3, 1>(6, 0) =
741 tcpTargetPoseRight.block<3, 1>(0, 3) - currentRightPose.block<3, 1>(0, 3);
742 poseError.block<3, 1>(9, 0) = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
744 Eigen::VectorXf forceImpedance(12);
745 for (
size_t i = 0; i < 12; i++)
747 forceImpedance(i) = KpImpedance(i) * poseError(i) - KdImpedance(i) * currentTwist(i);
751 Eigen::VectorXf leftNullspaceTorque =
752 cfg->knull * (leftDesiredJointValues - leftqpos) - cfg->dnull * leftqvel;
753 Eigen::VectorXf rightNullspaceTorque =
754 cfg->knull * (rightDesiredJointValues - rightqpos) - cfg->dnull * rightqvel;
758 Eigen::MatrixXf jtpinvL =
759 leftIK->computePseudoInverseJacobianMatrix(jacobiL.transpose(), lambda);
760 Eigen::MatrixXf jtpinvR =
761 rightIK->computePseudoInverseJacobianMatrix(jacobiR.transpose(), lambda);
762 Eigen::VectorXf leftJointDesiredTorques =
763 jacobiL.transpose() * forceImpedance.head<6>() +
764 (I - jacobiL.transpose() * jtpinvL) * leftNullspaceTorque;
765 Eigen::VectorXf rightJointDesiredTorques =
766 jacobiR.transpose() * forceImpedance.tail<6>() +
767 (I - jacobiR.transpose() * jtpinvR) * rightNullspaceTorque;
770 for (
size_t i = 0; i < leftTargets.size(); ++i)
772 float desiredTorque = leftJointDesiredTorques(i);
773 if (isnan(desiredTorque))
777 desiredTorque = (desiredTorque > cfg->torqueLimit) ? cfg->torqueLimit : desiredTorque;
778 desiredTorque = (desiredTorque < -cfg->torqueLimit) ? -cfg->torqueLimit : desiredTorque;
779 rt2DebugBuffer.
getWriteBuffer().desired_torques[leftJointNames[i]] =
780 leftJointDesiredTorques(i);
781 leftTargets.at(i)->torque = desiredTorque;
784 for (
size_t i = 0; i < rightTargets.size(); ++i)
786 float desiredTorque = rightJointDesiredTorques(i);
787 if (isnan(desiredTorque))
791 desiredTorque = (desiredTorque > cfg->torqueLimit) ? cfg->torqueLimit : desiredTorque;
792 desiredTorque = (desiredTorque < -cfg->torqueLimit) ? -cfg->torqueLimit : desiredTorque;
793 rt2DebugBuffer.
getWriteBuffer().desired_torques[rightJointNames[i]] =
794 rightJointDesiredTorques(i);
795 rightTargets.at(i)->torque = desiredTorque;
802 rt2DebugBuffer.
getWriteBuffer().forceTorqueMeasurementInRoot = forceTorqueMeasurementInRoot;
806 rt2DebugBuffer.
getWriteBuffer().objCurrentTwist = objCurrentTwist;
854 Eigen::VectorXf& twist)
859 leftPose.block<3, 1>(0, 3) *= 0.001;
860 pose = leftPose * objTransMatrixInAnchor;
875 objectDMP->learnDMPFromFiles(fileNames);
880 const Ice::StringSeq& objFileNames,
881 const Ice::StringSeq& leftFileNames,
882 const Ice::StringSeq& rightFileNames,
885 objectDMP->learnDMPFromFiles(objFileNames);
886 leftTCPInObjDMP->learnDMPFromFiles(leftFileNames);
887 rightTCPInObjDMP->learnDMPFromFiles(rightFileNames);
892 const Ice::Current& ice)
895 objectDMP->setGoalPoseVec(goals);
900 const Ice::DoubleSeq& goalLeft,
901 const Ice::DoubleSeq& goalRight,
902 const Ice::Current& ice)
905 objectDMP->setGoalPoseVec(goalObj);
906 leftTCPInObjDMP->setGoalPoseVec(goalLeft);
907 rightTCPInObjDMP->setGoalPoseVec(goalRight);
912 Eigen::VectorXf& vel,
916 VirtualRobot::MathTools::rpy2eigen3f(vel.tail<3>() *
static_cast<float>(deltaT));
917 pose.block<3, 3>(0, 0) = deltaRot * pose.block<3, 3>(0, 0);
918 pose.block<3, 1>(0, 3) += vel.head<3>() *
static_cast<float>(deltaT);
925 std::vector<double> poseVec{pose(0, 3), pose(1, 3), pose(2, 3), ori.w, ori.x, ori.y, ori.z};
933 Eigen::VectorXf poseVec;
935 poseVec(0) = pose(0, 3);
936 poseVec(1) = pose(1, 3);
937 poseVec(2) = pose(2, 3);
947 const Ice::DoubleSeq& goalLeft,
948 const Ice::DoubleSeq& goalRight,
962 std::vector<double> objInitPoseVec =
eigenPose2Vec(objInitPose);
963 std::vector<double> leftInitPoseVec =
eigenPose2Vec(leftInitPose);
964 std::vector<double> rightInitPoseVec =
eigenPose2Vec(rightInitPose);
966 <<
VAROUT(objInitPoseVec) <<
"\n"
967 <<
VAROUT(leftInitPoseVec) <<
"\n"
968 <<
VAROUT(rightInitPoseVec);
971 integratedPoseObj = objInitPose;
972 integratedPoseLeft = leftInitPose;
973 integratedPoseRight = rightInitPose;
975 objectDMP->prepareExecution(objInitPoseVec, goalObj);
976 objectDMP->canVal = timeDuration;
977 objectDMP->config.motionTimeDuration = timeDuration;
979 leftTCPInObjDMP->prepareExecution(leftInitPose,
getLocalPose(goalObj, goalLeft));
980 leftTCPInObjDMP->canVal = timeDuration;
981 leftTCPInObjDMP->config.motionTimeDuration = timeDuration;
983 rightTCPInObjDMP->prepareExecution(rightInitPose,
getLocalPose(goalObj, goalRight));
984 rightTCPInObjDMP->canVal = timeDuration;
985 rightTCPInObjDMP->config.motionTimeDuration = timeDuration;
998 localPose.block<3, 3>(0, 0) =
999 newCoordinate.block<3, 3>(0, 0).inverse() * globalTargetPose.block<3, 3>(0, 0);
1000 localPose.block<3, 1>(0, 3) =
1001 newCoordinate.block<3, 3>(0, 0).inverse() *
1002 (globalTargetPose.block<3, 1>(0, 3) - newCoordinate.block<3, 1>(0, 3));
1010 const std::vector<double>& newCoordinateVec,
1011 const std::vector<double>& globalTargetPoseVec)
1014 VirtualRobot::MathTools::quat2eigen4f(newCoordinateVec.at(4),
1015 newCoordinateVec.at(5),
1016 newCoordinateVec.at(6),
1017 newCoordinateVec.at(3));
1018 newCoordinate(0, 3) = newCoordinateVec.at(0);
1019 newCoordinate(1, 3) = newCoordinateVec.at(1);
1020 newCoordinate(2, 3) = newCoordinateVec.at(2);
1023 VirtualRobot::MathTools::quat2eigen4f(globalTargetPoseVec.at(4),
1024 globalTargetPoseVec.at(5),
1025 globalTargetPoseVec.at(6),
1026 globalTargetPoseVec.at(3));
1027 globalTargetPose(0, 3) = globalTargetPoseVec.at(0);
1028 globalTargetPose(1, 3) = globalTargetPoseVec.at(1);
1029 globalTargetPose(2, 3) = globalTargetPoseVec.at(2);
1036 const Ice::DoubleSeq& goals,
1038 const Ice::Current&)
1046 objectDMP->prepareExecution(starts, goals);
1047 objectDMP->canVal = timeDuration;
1048 objectDMP->config.motionTimeDuration = timeDuration;
1058 const Ice::DoubleSeq& viapoint,
1059 const Ice::Current&)
1063 objectDMP->setViaPose(u, viapoint);
1069 objectDMP->removeAllViaPoints();
1074 const Ice::Current&)
1077 Eigen::VectorXf setpoint;
1078 setpoint.setZero(
value.size());
1081 for (
size_t i = 0; i <
value.size(); ++i)
1083 setpoint(i) =
value.at(i);
1095 if (objectDMP->config.DMPStyle ==
"Periodic")
1097 objectDMP->setAmplitude(amp);
1100 if (leftTCPInObjDMP->config.DMPStyle ==
"Periodic")
1102 leftTCPInObjDMP->setAmplitude(amp);
1105 if (rightTCPInObjDMP->config.DMPStyle ==
"Periodic")
1107 rightTCPInObjDMP->setAmplitude(amp);
1113 const Ice::Current&)
1115 Eigen::VectorXf setpoint;
1116 setpoint.setZero(
value.size());
1119 for (
size_t i = 0; i <
value.size(); ++i)
1121 setpoint(i) =
value.at(i);
1131 const Ice::Current&)
1133 Eigen::VectorXf setpoint;
1134 setpoint.setZero(
value.size());
1137 for (
size_t i = 0; i <
value.size(); ++i)
1139 setpoint(i) =
value.at(i);
1149 const Ice::Current&)
1151 Eigen::VectorXf setpoint;
1152 setpoint.setZero(
value.size());
1155 for (
size_t i = 0; i <
value.size(); ++i)
1157 setpoint(i) =
value.at(i);
1167 const Ice::Current&)
1169 Eigen::VectorXf setpoint;
1170 setpoint.setZero(
value.size());
1173 for (
size_t i = 0; i <
value.size(); ++i)
1175 setpoint(i) =
value.at(i);
1187 std::vector<float> tvelvec = {tvel(0), tvel(1), tvel(2)};
1195 std::vector<float> fvelvec = {fvel(0), fvel(1), fvel(2)};
1201 const std::string name,
1204 for (
int i = 0; i < bufferVec.rows(); ++i)
1207 datafields[data_name] =
new Variant(bufferVec(i));
1219 for (
auto& pair :
values)
1221 datafields[pair.first] =
new Variant(pair.second);
1231 "forceTorqueMeasurementInRoot",
1250 "targetHandPoseInRootLeft",
1253 "targetHandPoseInRootRight",
1256 "currentHandPoseInRootLeft",
1259 "currentHandPoseInRootRight",
1270 "rightPoseVecInObj",
1276 "integratedPoseObjVec",
1279 "integratedPoseLeftVec",
1282 "integratedPoseRightVec",
1496 debugObs->setDebugChannel(
"BimanualForceController", datafields);
1502 ARMARX_INFO <<
"====== init bimanual multi mp controller ======";
1503 runTask(
"NJointBimanualObjLevelMultiMPController",
1508 while (
getState() == eManagedIceObjectStarted)
1514 c.waitForCycleDuration();
1522 ARMARX_INFO <<
"====== stop bimanual multi mp controller ======";