8 NJointControllerRegistration<NJointBimanualObjLevelMultiMPController>
10 "NJointBimanualObjLevelMultiMPController");
13 const RobotUnitPtr& robUnit,
14 const armarx::NJointControllerConfigPtr& config,
17 ARMARX_INFO <<
"Initializing Bimanual Object Level Controller";
21 cfg = NJointBimanualObjLevelMultiMPControllerConfigPtr::dynamicCast(config);
23 leftRNS =
rtGetRobot()->getRobotNodeSet(
"LeftArm");
25 for (
size_t i = 0; i < leftRNS->getSize(); ++i)
27 std::string jointName = leftRNS->getNode(i)->getName();
28 leftJointNames.push_back(jointName);
31 leftTargets.push_back(ct->
asA<ControlTarget1DoFActuatorTorque>());
32 const SensorValue1DoFActuatorVelocity* velocitySensor =
33 sv->
asA<SensorValue1DoFActuatorVelocity>();
34 const SensorValue1DoFActuatorPosition* positionSensor =
35 sv->
asA<SensorValue1DoFActuatorPosition>();
47 leftVelocitySensors.push_back(velocitySensor);
48 leftPositionSensors.push_back(positionSensor);
51 rightRNS =
rtGetRobot()->getRobotNodeSet(
"RightArm");
53 for (
size_t i = 0; i < rightRNS->getSize(); ++i)
55 std::string jointName = rightRNS->getNode(i)->getName();
56 rightJointNames.push_back(jointName);
59 rightTargets.push_back(ct->
asA<ControlTarget1DoFActuatorTorque>());
61 const SensorValue1DoFActuatorVelocity* velocitySensor =
62 sv->
asA<SensorValue1DoFActuatorVelocity>();
63 const SensorValue1DoFActuatorPosition* positionSensor =
64 sv->
asA<SensorValue1DoFActuatorPosition>();
75 rightVelocitySensors.push_back(velocitySensor);
76 rightPositionSensors.push_back(positionSensor);
80 const SensorValueBase* svlf = robUnit->getSensorDevice(
"FT L")->getSensorValue();
82 const SensorValueBase* svrf = robUnit->getSensorDevice(
"FT R")->getSensorValue();
85 leftIK.reset(
new VirtualRobot::DifferentialIK(
86 leftRNS, leftRNS->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
87 rightIK.reset(
new VirtualRobot::DifferentialIK(rightRNS,
88 rightRNS->getRobot()->getRootNode(),
89 VirtualRobot::JacobiProvider::eSVDDamped));
91 tcpLeft = leftRNS->getTCP();
92 tcpRight = rightRNS->getTCP();
97 taskSpaceDMPConfig.
DMPMode = cfg->dmpMode;
110 taskSpaceDMPConfig.
DMPStyle = cfg->dmpObjType;
112 taskSpaceDMPConfig.
DMPStyle = cfg->dmpLeftType;
114 taskSpaceDMPConfig.
DMPStyle = cfg->dmpRightType;
119 auto setParamVec = [&](Eigen::VectorXf& param, ::Ice::FloatSeq& cfgParam,
const size_t n)
124 for (
size_t i = 0; i < n; ++i)
126 param(i) = cfgParam.at(i);
130 setParamVec(KpImpedance, cfg->KpImpedance, 12);
131 setParamVec(KdImpedance, cfg->KdImpedance, 12);
132 setParamVec(KpAdmittance, cfg->KpAdmittance, 6);
133 setParamVec(KdAdmittance, cfg->KdAdmittance, 6);
134 setParamVec(KmAdmittance, cfg->KmAdmittance, 6);
135 setParamVec(KmPID, cfg->KmPID, 6);
140 leftDesiredJointValues.resize(leftTargets.size());
143 for (
size_t i = 0; i < leftTargets.size(); ++i)
145 leftDesiredJointValues(i) = cfg->leftDesiredJointValues.at(i);
148 rightDesiredJointValues.resize(rightTargets.size());
151 for (
size_t i = 0; i < rightTargets.size(); ++i)
153 rightDesiredJointValues(i) = cfg->rightDesiredJointValues.at(i);
158 objInitialPose = VirtualRobot::MathTools::quat2eigen4f(cfg->objInitialPose[4],
159 cfg->objInitialPose[5],
160 cfg->objInitialPose[6],
161 cfg->objInitialPose[3]);
162 for (
int i = 0; i < 3; ++i)
164 objInitialPose(i, 3) = cfg->objInitialPose[i];
167 virtualAcc.setZero(6);
168 virtualVel.setZero(6);
169 virtualPose = objInitialPose;
178 leftInitialPose.block<3, 3>(0, 0) =
179 objInitialPose.block<3, 3>(0, 0).transpose() * leftPose.block<3, 3>(0, 0);
180 leftInitialPose.block<3, 1>(0, 3) =
181 objInitialPose.block<3, 3>(0, 0).transpose() *
182 (leftPose.block<3, 1>(0, 3) * 0.001 - objInitialPose.block<3, 1>(0, 3));
183 rightInitialPose.block<3, 3>(0, 0) =
184 objInitialPose.block<3, 3>(0, 0).transpose() * rightPose.block<3, 3>(0, 0);
185 rightInitialPose.block<3, 1>(0, 3) =
186 objInitialPose.block<3, 3>(0, 0).transpose() *
187 (rightPose.block<3, 1>(0, 3) * 0.001 - objInitialPose.block<3, 1>(0, 3));
189 integratedPoseObj = virtualPose;
190 integratedPoseLeft = leftInitialPose;
191 integratedPoseRight = rightInitialPose;
194 Inferface2rtData interface2rtData;
195 interface2rtData.KpImpedance = KpImpedance;
196 interface2rtData.KdImpedance = KdImpedance;
197 interface2rtData.KmAdmittance = KmAdmittance;
198 interface2rtData.KpAdmittance = KpAdmittance;
199 interface2rtData.KdAdmittance = KdAdmittance;
203 RT2ControlData rt2ControlData;
204 rt2ControlData.deltaT = 0;
205 rt2ControlData.currentTime = 0;
206 rt2ControlData.currentPoseObj = objInitialPose;
207 rt2ControlData.currentTwistObj.setZero();
208 rt2ControlData.currentPoseObj = leftInitialPose;
209 rt2ControlData.currentTwistObj.setZero();
210 rt2ControlData.currentPoseObj = rightInitialPose;
211 rt2ControlData.currentTwistObj.setZero();
227 RT2InterfaceData rt2InterfaceData;
228 rt2InterfaceData.currentLeftPoseInObjFrame = leftInitialPose;
229 rt2InterfaceData.currentRightPoseInObjFrame = rightInitialPose;
230 rt2InterfaceData.currentObjPose = objInitialPose;
231 rt2InterfaceData.currentObjForce.setZero();
232 rt2InterfaceData.currentObjVel.setZero();
237 forcePIDControllers.resize(12);
238 for (
size_t i = 0; i < 6; i++)
241 cfg->forceP[i], cfg->forceI[i], cfg->forceD[i], cfg->forcePIDLimits[i]));
243 cfg->forceP[i], cfg->forceI[i], cfg->forceD[i], cfg->forcePIDLimits[i]));
244 forcePIDControllers.at(i)->reset();
245 forcePIDControllers.at(i + 6)->reset();
250 sensorFrame2TcpFrameLeft.setZero();
251 sensorFrame2TcpFrameRight.setZero();
254 filterCoeff = cfg->filterCoeff;
255 filteredOldValue.setZero(12);
258 ftcalibrationTimer = 0;
259 ftOffset.setZero(12);
262 targetWrench.setZero(cfg->targetWrench.size());
263 for (
size_t i = 0; i < cfg->targetWrench.size(); ++i)
265 targetWrench(i) = cfg->targetWrench[i];
269 massLeft = cfg->massLeft;
270 CoMVecLeft << cfg->CoMVecLeft[0], cfg->CoMVecLeft[1], cfg->CoMVecLeft[2];
271 forceOffsetLeft << cfg->forceOffsetLeft[0], cfg->forceOffsetLeft[1],
272 cfg->forceOffsetLeft[2];
273 torqueOffsetLeft << cfg->torqueOffsetLeft[0], cfg->torqueOffsetLeft[1],
274 cfg->torqueOffsetLeft[2];
276 massRight = cfg->massRight;
277 CoMVecRight << cfg->CoMVecRight[0], cfg->CoMVecRight[1], cfg->CoMVecRight[2];
278 forceOffsetRight << cfg->forceOffsetRight[0], cfg->forceOffsetRight[1],
279 cfg->forceOffsetRight[2];
280 torqueOffsetRight << cfg->torqueOffsetRight[0], cfg->torqueOffsetRight[1],
281 cfg->torqueOffsetRight[2];
285 objCom2TCPLeftInObjFrame.setZero();
286 objCom2TCPRightInObjFrame.setZero();
303 return "NJointBimanualObjLevelMultiMPController";
317 Eigen::VectorXf currentTwistObj = rt2ControlBuffer.
getReadBuffer().currentTwistObj;
320 Eigen::VectorXf currentTwistLeftInObj =
324 Eigen::VectorXf currentTwistRightInObj =
328 rightTCPInObjDMP->flow(deltaT, currentPoseRightInObj, currentTwistRightInObj);
331 bool objectDMPFinished =
false;
332 bool leftTCPInObjDMPFinished =
false;
333 bool rightTCPInObjDMPFinished =
false;
335 if (objectDMP->canVal > 1e-8 || objectDMP->config.DMPStyle ==
"Periodic")
337 objectDMP->flow(deltaT, currentPoseObj, currentTwistObj);
343 objectDMPFinished =
true;
347 if (leftTCPInObjDMP->canVal > 1e-8 || leftTCPInObjDMP->config.DMPStyle ==
"Periodic")
349 leftTCPInObjDMP->flow(deltaT, currentPoseLeftInObj, currentTwistLeftInObj);
355 leftTCPInObjDMPFinished =
true;
358 if (rightTCPInObjDMP->canVal > 1e-8 || rightTCPInObjDMP->config.DMPStyle ==
"Periodic")
360 rightTCPInObjDMP->flow(deltaT, currentPoseRightInObj, currentTwistRightInObj);
366 rightTCPInObjDMPFinished =
true;
370 if (objectDMPFinished && leftTCPInObjDMPFinished && rightTCPInObjDMPFinished)
389 currentLeftPose.block<3, 1>(0, 3) = 0.001 * currentLeftPose.block<3, 1>(0, 3);
390 currentRightPose.block<3, 1>(0, 3) = 0.001 * currentRightPose.block<3, 1>(0, 3);
392 double deltaT = timeSinceLastIteration.toSecondsDouble();
393 ftcalibrationTimer += deltaT;
400 Eigen::Vector3f objCom2TCPLeftInGlobal =
401 leftPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
402 Eigen::Vector3f objCom2TCPRightInGlobal =
403 rightPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
407 objTransMatrixInAnchor.block<3, 3>(0, 0) =
408 leftPose.block<3, 3>(0, 0).transpose() * objInitialPose.block<3, 3>(0, 0);
409 objTransMatrixInAnchor.block<3, 1>(0, 3) =
410 leftPose.block<3, 3>(0, 0).transpose() *
411 (objInitialPose.block<3, 1>(0, 3) - leftPose.block<3, 1>(0, 3));
413 objCom2TCPLeftInObjFrame =
414 virtualPose.block<3, 3>(0, 0).
transpose() * objCom2TCPLeftInGlobal;
415 objCom2TCPRightInObjFrame =
416 virtualPose.block<3, 3>(0, 0).
transpose() * objCom2TCPRightInGlobal;
420 leftRNS->getRobot()->getRobotNode(
"ArmL8_Wri2")->getPoseInRootFrame();
422 rightRNS->getRobot()->getRobotNode(
"ArmR8_Wri2")->getPoseInRootFrame();
423 leftSensorFrame.block<3, 1>(0, 3) = leftSensorFrame.block<3, 1>(0, 3) * 0.001;
424 rightSensorFrame.block<3, 1>(0, 3) = rightSensorFrame.block<3, 1>(0, 3) * 0.001;
427 sensorFrame2TcpFrameLeft.block<3, 3>(0, 0) =
428 leftPose.block<3, 3>(0, 0).transpose() * leftSensorFrame.block<3, 3>(0, 0);
429 sensorFrame2TcpFrameRight.block<3, 3>(0, 0) =
430 rightPose.block<3, 3>(0, 0).transpose() * rightSensorFrame.block<3, 3>(0, 0);
431 CoMVecLeft = sensorFrame2TcpFrameLeft.block<3, 3>(0, 0) * CoMVecLeft;
432 CoMVecRight = sensorFrame2TcpFrameRight.block<3, 3>(0, 0) * CoMVecRight;
438 currentLeftPoseInObjFrame.block<3, 3>(0, 0) =
439 virtualPose.block<3, 3>(0, 0).transpose() * currentLeftPose.block<3, 3>(0, 0);
440 currentLeftPoseInObjFrame.block<3, 1>(0, 3) =
441 virtualPose.block<3, 3>(0, 0).transpose() *
442 (currentLeftPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3));
443 currentRightPoseInObjFrame.block<3, 3>(0, 0) =
444 virtualPose.block<3, 3>(0, 0).transpose() * currentRightPose.block<3, 3>(0, 0);
445 currentRightPoseInObjFrame.block<3, 1>(0, 3) =
446 virtualPose.block<3, 3>(0, 0).transpose() *
447 (currentRightPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3));
448 rt2InterfaceBuffer.
getWriteBuffer().currentLeftPoseInObjFrame = currentLeftPoseInObjFrame;
449 rt2InterfaceBuffer.
getWriteBuffer().currentRightPoseInObjFrame = currentRightPoseInObjFrame;
459 if (ftcalibrationTimer < cfg->ftCalibrationTime)
461 ftOffset.block<3, 1>(0, 0) =
462 0.5 * ftOffset.block<3, 1>(0, 0) + 0.5 * leftForceTorque->
force;
463 ftOffset.block<3, 1>(3, 0) =
464 0.5 * ftOffset.block<3, 1>(3, 0) + 0.5 * leftForceTorque->
torque;
465 ftOffset.block<3, 1>(6, 0) =
466 0.5 * ftOffset.block<3, 1>(6, 0) + 0.5 * rightForceTorque->
force;
467 ftOffset.block<3, 1>(9, 0) =
468 0.5 * ftOffset.block<3, 1>(9, 0) + 0.5 * rightForceTorque->
torque;
470 for (
int i = 0; i < KmAdmittance.size(); ++i)
477 for (
int i = 0; i < KmAdmittance.size(); ++i)
479 KmAdmittance(i) = cfg->KmAdmittance.at(i);
484 Eigen::VectorXf deltaPoseForWrenchControl;
485 deltaPoseForWrenchControl.setZero(12);
486 for (
size_t i = 0; i < 12; ++i)
488 if (KpImpedance(i) == 0)
490 deltaPoseForWrenchControl(i) = 0;
494 deltaPoseForWrenchControl(i) = targetWrench(i) / KpImpedance(i);
495 if (deltaPoseForWrenchControl(i) > 0.1)
497 deltaPoseForWrenchControl(i) = 0.1;
499 else if (deltaPoseForWrenchControl(i) < -0.1)
501 deltaPoseForWrenchControl(i) = -0.1;
510 Eigen::Vector3f objCom2TCPLeftInGlobal =
511 currentLeftPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
512 Eigen::Vector3f objCom2TCPRightInGlobal =
513 currentRightPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
515 Eigen::MatrixXf graspMatrix;
516 graspMatrix.setZero(6, 12);
523 graspMatrix.block<3, 3>(3, 0) =
skew(objCom2TCPLeftInGlobal);
526 graspMatrix.block<3, 3>(3, 6) =
skew(objCom2TCPRightInGlobal);
533 Eigen::MatrixXf pinvGraspMatrixT =
534 leftIK->computePseudoInverseJacobianMatrix(graspMatrix.transpose(), lambda);
537 Eigen::Matrix4f objCurrentPose = currentLeftPose * objTransMatrixInAnchor;
538 Eigen::VectorXf objCurrentTwist;
540 objCurrentTwist.setZero(6);
545 Eigen::MatrixXf jacobiL =
546 leftIK->getJacobianMatrix(tcpLeft, VirtualRobot::IKSolver::CartesianSelection::All);
547 Eigen::MatrixXf jacobiR =
548 rightIK->getJacobianMatrix(tcpRight, VirtualRobot::IKSolver::CartesianSelection::All);
549 jacobiL.block<3, 8>(0, 0) = 0.001 * jacobiL.block<3, 8>(0, 0);
550 jacobiR.block<3, 8>(0, 0) = 0.001 * jacobiR.block<3, 8>(0, 0);
553 Eigen::VectorXf leftqpos;
554 Eigen::VectorXf leftqvel;
555 leftqpos.resize(leftPositionSensors.size());
556 leftqvel.resize(leftVelocitySensors.size());
557 for (
size_t i = 0; i < leftVelocitySensors.size(); ++i)
559 leftqpos(i) = leftPositionSensors[i]->position;
560 leftqvel(i) = leftVelocitySensors[i]->velocity;
563 Eigen::VectorXf rightqpos;
564 Eigen::VectorXf rightqvel;
565 rightqpos.resize(rightPositionSensors.size());
566 rightqvel.resize(rightVelocitySensors.size());
568 for (
size_t i = 0; i < rightVelocitySensors.size(); ++i)
570 rightqpos(i) = rightPositionSensors[i]->position;
571 rightqvel(i) = rightVelocitySensors[i]->velocity;
575 Eigen::VectorXf currentLeftTwist = jacobiL * leftqvel;
576 Eigen::VectorXf currentRightTwist = jacobiR * rightqvel;
578 Eigen::VectorXf currentTwist(12);
579 currentTwist << currentLeftTwist, currentRightTwist;
580 objCurrentTwist = pinvGraspMatrixT * currentTwist;
582 rt2ControlBuffer.
getWriteBuffer().currentPoseObj = objCurrentPose;
583 rt2ControlBuffer.
getWriteBuffer().currentTwistObj = objCurrentTwist;
590 Eigen::Vector3f gravity;
591 gravity << 0.0, 0.0, -9.8;
592 Eigen::Vector3f localGravityLeft = currentLeftPose.block<3, 3>(0, 0).
transpose() * gravity;
593 Eigen::Vector3f localForceVecLeft = massLeft * localGravityLeft;
594 Eigen::Vector3f localTorqueVecLeft = CoMVecLeft.cross(localForceVecLeft);
596 Eigen::Vector3f localGravityRight =
597 currentRightPose.block<3, 3>(0, 0).
transpose() * gravity;
598 Eigen::Vector3f localForceVecRight = massRight * localGravityRight;
599 Eigen::Vector3f localTorqueVecRight = CoMVecRight.cross(localForceVecRight);
602 Eigen::VectorXf wrenchesMeasured(12);
603 wrenchesMeasured << leftForceTorque->
force - forceOffsetLeft,
604 leftForceTorque->
torque - torqueOffsetLeft, rightForceTorque->
force - forceOffsetRight,
605 rightForceTorque->
torque - torqueOffsetRight;
606 for (
size_t i = 0; i < 12; i++)
608 wrenchesMeasured(i) =
609 (1 - filterCoeff) * wrenchesMeasured(i) + filterCoeff * filteredOldValue(i);
611 filteredOldValue = wrenchesMeasured;
612 wrenchesMeasured.block<3, 1>(0, 0) =
613 sensorFrame2TcpFrameLeft.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(0, 0) -
615 wrenchesMeasured.block<3, 1>(3, 0) =
616 sensorFrame2TcpFrameLeft.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(3, 0) -
618 wrenchesMeasured.block<3, 1>(6, 0) =
619 sensorFrame2TcpFrameRight.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(6, 0) -
621 wrenchesMeasured.block<3, 1>(9, 0) =
622 sensorFrame2TcpFrameRight.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(9, 0) -
629 Eigen::VectorXf forceTorqueMeasurementInRoot(12);
630 forceTorqueMeasurementInRoot.block<3, 1>(0, 0) =
631 currentLeftPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(0, 0);
632 forceTorqueMeasurementInRoot.block<3, 1>(3, 0) =
633 currentLeftPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(3, 0);
634 forceTorqueMeasurementInRoot.block<3, 1>(6, 0) =
635 currentRightPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(6, 0);
636 forceTorqueMeasurementInRoot.block<3, 1>(9, 0) =
637 currentRightPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(9, 0);
641 Eigen::VectorXf objFTValue = graspMatrix * forceTorqueMeasurementInRoot;
642 for (
size_t i = 0; i < 6; i++)
644 if (fabs(objFTValue(i)) < cfg->forceThreshold.at(i))
650 objFTValue(i) -= cfg->forceThreshold.at(i) * objFTValue(i) / fabs(objFTValue(i));
655 rt2InterfaceBuffer.
getWriteBuffer().currentObjPose = objCurrentPose;
656 rt2InterfaceBuffer.
getWriteBuffer().currentObjVel = objCurrentTwist.head(3);
657 rt2InterfaceBuffer.
getWriteBuffer().currentObjForce = objFTValue.head(3);
678 Eigen::VectorXf objPoseError(6);
679 objPoseError.head(3) = virtualPose.block<3, 1>(0, 3) - objTargetPose.block<3, 1>(0, 3);
681 virtualPose.block<3, 3>(0, 0) * objTargetPose.block<3, 3>(0, 0).transpose();
682 objPoseError.tail(3) = VirtualRobot::MathTools::eigen3f2rpy(objDiffMat);
685 Eigen::VectorXf objAcc;
686 Eigen::VectorXf objVel;
689 for (
size_t i = 0; i < 6; i++)
692 objAcc(i) = KmAdmittance(i) * objFTValue(i) - KpAdmittance(i) * objPoseError(i) -
693 KdAdmittance(i) * virtualVel(i);
695 objVel = virtualVel + 0.5 * deltaT * (objAcc + virtualAcc);
696 Eigen::VectorXf deltaObjPose = 0.5 * deltaT * (objVel + virtualVel);
699 virtualPose.block<3, 1>(0, 3) += deltaObjPose.head(3);
700 virtualPose.block<3, 3>(0, 0) = VirtualRobot::MathTools::rpy2eigen3f(
701 deltaObjPose(3), deltaObjPose(4), deltaObjPose(5)) *
702 virtualPose.block<3, 3>(0, 0);
713 Eigen::VectorXf poseError(12);
715 tcpTargetPoseLeft.block<3, 3>(0, 0) * currentLeftPose.block<3, 3>(0, 0).transpose();
716 poseError.block<3, 1>(0, 0) =
717 tcpTargetPoseLeft.block<3, 1>(0, 3) - currentLeftPose.block<3, 1>(0, 3);
718 poseError.block<3, 1>(3, 0) = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
721 tcpTargetPoseRight.block<3, 3>(0, 0) * currentRightPose.block<3, 3>(0, 0).transpose();
722 poseError.block<3, 1>(6, 0) =
723 tcpTargetPoseRight.block<3, 1>(0, 3) - currentRightPose.block<3, 1>(0, 3);
724 poseError.block<3, 1>(9, 0) = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
726 Eigen::VectorXf forceImpedance(12);
727 for (
size_t i = 0; i < 12; i++)
729 forceImpedance(i) = KpImpedance(i) * poseError(i) - KdImpedance(i) * currentTwist(i);
733 Eigen::VectorXf leftNullspaceTorque =
734 cfg->knull * (leftDesiredJointValues - leftqpos) - cfg->dnull * leftqvel;
735 Eigen::VectorXf rightNullspaceTorque =
736 cfg->knull * (rightDesiredJointValues - rightqpos) - cfg->dnull * rightqvel;
740 Eigen::MatrixXf jtpinvL =
741 leftIK->computePseudoInverseJacobianMatrix(jacobiL.transpose(), lambda);
742 Eigen::MatrixXf jtpinvR =
743 rightIK->computePseudoInverseJacobianMatrix(jacobiR.transpose(), lambda);
744 Eigen::VectorXf leftJointDesiredTorques =
745 jacobiL.transpose() * forceImpedance.head(6) +
746 (I - jacobiL.transpose() * jtpinvL) * leftNullspaceTorque;
747 Eigen::VectorXf rightJointDesiredTorques =
748 jacobiR.transpose() * forceImpedance.tail(6) +
749 (I - jacobiR.transpose() * jtpinvR) * rightNullspaceTorque;
752 for (
size_t i = 0; i < leftTargets.size(); ++i)
754 float desiredTorque = leftJointDesiredTorques(i);
755 if (isnan(desiredTorque))
759 desiredTorque = (desiredTorque > cfg->torqueLimit) ? cfg->torqueLimit : desiredTorque;
760 desiredTorque = (desiredTorque < -cfg->torqueLimit) ? -cfg->torqueLimit : desiredTorque;
761 rt2DebugBuffer.
getWriteBuffer().desired_torques[leftJointNames[i]] =
762 leftJointDesiredTorques(i);
763 leftTargets.at(i)->torque = desiredTorque;
766 for (
size_t i = 0; i < rightTargets.size(); ++i)
768 float desiredTorque = rightJointDesiredTorques(i);
769 if (isnan(desiredTorque))
773 desiredTorque = (desiredTorque > cfg->torqueLimit) ? cfg->torqueLimit : desiredTorque;
774 desiredTorque = (desiredTorque < -cfg->torqueLimit) ? -cfg->torqueLimit : desiredTorque;
775 rt2DebugBuffer.
getWriteBuffer().desired_torques[rightJointNames[i]] =
776 rightJointDesiredTorques(i);
777 rightTargets.at(i)->torque = desiredTorque;
784 rt2DebugBuffer.
getWriteBuffer().forceTorqueMeasurementInRoot = forceTorqueMeasurementInRoot;
788 rt2DebugBuffer.
getWriteBuffer().objCurrentTwist = objCurrentTwist;
836 Eigen::VectorXf& twist)
841 leftPose.block<3, 1>(0, 3) *= 0.001;
842 pose = leftPose * objTransMatrixInAnchor;
857 objectDMP->learnDMPFromFiles(fileNames);
862 const Ice::StringSeq& objFileNames,
863 const Ice::StringSeq& leftFileNames,
864 const Ice::StringSeq& rightFileNames,
867 objectDMP->learnDMPFromFiles(objFileNames);
868 leftTCPInObjDMP->learnDMPFromFiles(leftFileNames);
869 rightTCPInObjDMP->learnDMPFromFiles(rightFileNames);
874 const Ice::Current& ice)
877 objectDMP->setGoalPoseVec(goals);
882 const Ice::DoubleSeq& goalLeft,
883 const Ice::DoubleSeq& goalRight,
884 const Ice::Current& ice)
887 objectDMP->setGoalPoseVec(goalObj);
888 leftTCPInObjDMP->setGoalPoseVec(goalLeft);
889 rightTCPInObjDMP->setGoalPoseVec(goalRight);
894 Eigen::VectorXf& vel,
898 VirtualRobot::MathTools::rpy2eigen3f(vel.tail(3) *
static_cast<float>(deltaT));
899 pose.block<3, 3>(0, 0) = deltaRot * pose.block<3, 3>(0, 0);
900 pose.block<3, 1>(0, 3) += vel.head(3) *
static_cast<float>(deltaT);
907 std::vector<double> poseVec{pose(0, 3), pose(1, 3), pose(2, 3), ori.w, ori.x, ori.y, ori.z};
915 Eigen::VectorXf poseVec;
917 poseVec(0) = pose(0, 3);
918 poseVec(1) = pose(1, 3);
919 poseVec(2) = pose(2, 3);
929 const Ice::DoubleSeq& goalLeft,
930 const Ice::DoubleSeq& goalRight,
944 std::vector<double> objInitPoseVec =
eigenPose2Vec(objInitPose);
945 std::vector<double> leftInitPoseVec =
eigenPose2Vec(leftInitPose);
946 std::vector<double> rightInitPoseVec =
eigenPose2Vec(rightInitPose);
948 <<
VAROUT(objInitPoseVec) <<
"\n"
949 <<
VAROUT(leftInitPoseVec) <<
"\n"
950 <<
VAROUT(rightInitPoseVec);
953 integratedPoseObj = objInitPose;
954 integratedPoseLeft = leftInitPose;
955 integratedPoseRight = rightInitPose;
957 objectDMP->prepareExecution(objInitPoseVec, goalObj);
958 objectDMP->canVal = timeDuration;
959 objectDMP->config.motionTimeDuration = timeDuration;
961 leftTCPInObjDMP->prepareExecution(leftInitPose,
getLocalPose(goalObj, goalLeft));
962 leftTCPInObjDMP->canVal = timeDuration;
963 leftTCPInObjDMP->config.motionTimeDuration = timeDuration;
965 rightTCPInObjDMP->prepareExecution(rightInitPose,
getLocalPose(goalObj, goalRight));
966 rightTCPInObjDMP->canVal = timeDuration;
967 rightTCPInObjDMP->config.motionTimeDuration = timeDuration;
981 localPose.block<3, 3>(0, 0) =
982 newCoordinate.block<3, 3>(0, 0).inverse() * globalTargetPose.block<3, 3>(0, 0);
983 localPose.block<3, 1>(0, 3) =
984 newCoordinate.block<3, 3>(0, 0).inverse() *
985 (globalTargetPose.block<3, 1>(0, 3) - newCoordinate.block<3, 1>(0, 3));
993 const std::vector<double>& newCoordinateVec,
994 const std::vector<double>& globalTargetPoseVec)
997 VirtualRobot::MathTools::quat2eigen4f(newCoordinateVec.at(4),
998 newCoordinateVec.at(5),
999 newCoordinateVec.at(6),
1000 newCoordinateVec.at(3));
1001 newCoordinate(0, 3) = newCoordinateVec.at(0);
1002 newCoordinate(1, 3) = newCoordinateVec.at(1);
1003 newCoordinate(2, 3) = newCoordinateVec.at(2);
1006 VirtualRobot::MathTools::quat2eigen4f(globalTargetPoseVec.at(4),
1007 globalTargetPoseVec.at(5),
1008 globalTargetPoseVec.at(6),
1009 globalTargetPoseVec.at(3));
1010 globalTargetPose(0, 3) = globalTargetPoseVec.at(0);
1011 globalTargetPose(1, 3) = globalTargetPoseVec.at(1);
1012 globalTargetPose(2, 3) = globalTargetPoseVec.at(2);
1019 const Ice::DoubleSeq& goals,
1021 const Ice::Current&)
1029 objectDMP->prepareExecution(starts, goals);
1030 objectDMP->canVal = timeDuration;
1031 objectDMP->config.motionTimeDuration = timeDuration;
1041 const Ice::DoubleSeq& viapoint,
1042 const Ice::Current&)
1046 objectDMP->setViaPose(u, viapoint);
1052 objectDMP->removeAllViaPoints();
1057 const Ice::Current&)
1060 Eigen::VectorXf setpoint;
1061 setpoint.setZero(
value.size());
1064 for (
size_t i = 0; i <
value.size(); ++i)
1066 setpoint(i) =
value.at(i);
1078 if (objectDMP->config.DMPStyle ==
"Periodic")
1080 objectDMP->setAmplitude(amp);
1083 if (leftTCPInObjDMP->config.DMPStyle ==
"Periodic")
1085 leftTCPInObjDMP->setAmplitude(amp);
1088 if (rightTCPInObjDMP->config.DMPStyle ==
"Periodic")
1090 rightTCPInObjDMP->setAmplitude(amp);
1096 const Ice::Current&)
1098 Eigen::VectorXf setpoint;
1099 setpoint.setZero(
value.size());
1102 for (
size_t i = 0; i <
value.size(); ++i)
1104 setpoint(i) =
value.at(i);
1114 const Ice::Current&)
1116 Eigen::VectorXf setpoint;
1117 setpoint.setZero(
value.size());
1120 for (
size_t i = 0; i <
value.size(); ++i)
1122 setpoint(i) =
value.at(i);
1132 const Ice::Current&)
1134 Eigen::VectorXf setpoint;
1135 setpoint.setZero(
value.size());
1138 for (
size_t i = 0; i <
value.size(); ++i)
1140 setpoint(i) =
value.at(i);
1150 const Ice::Current&)
1152 Eigen::VectorXf setpoint;
1153 setpoint.setZero(
value.size());
1156 for (
size_t i = 0; i <
value.size(); ++i)
1158 setpoint(i) =
value.at(i);
1170 std::vector<float> tvelvec = {tvel(0), tvel(1), tvel(2)};
1178 std::vector<float> fvelvec = {fvel(0), fvel(1), fvel(2)};
1184 const std::string name,
1187 for (
int i = 0; i < bufferVec.rows(); ++i)
1190 datafields[data_name] =
new Variant(bufferVec(i));
1202 for (
auto& pair :
values)
1204 datafields[pair.first] =
new Variant(pair.second);
1214 "forceTorqueMeasurementInRoot",
1233 "targetHandPoseInRootLeft",
1236 "targetHandPoseInRootRight",
1239 "currentHandPoseInRootLeft",
1242 "currentHandPoseInRootRight",
1253 "rightPoseVecInObj",
1259 "integratedPoseObjVec",
1262 "integratedPoseLeftVec",
1265 "integratedPoseRightVec",
1479 debugObs->setDebugChannel(
"BimanualForceController", datafields);
1485 ARMARX_INFO <<
"====== init bimanual multi mp controller ======";
1486 runTask(
"NJointBimanualObjLevelMultiMPController",
1491 while (
getState() == eManagedIceObjectStarted)
1497 c.waitForCycleDuration();
1505 ARMARX_INFO <<
"====== stop bimanual multi mp controller ======";