7 #include <VirtualRobot/IK/DifferentialIK.h>
8 #include <VirtualRobot/MathTools.h>
9 #include <VirtualRobot/Nodes/RobotNode.h>
10 #include <VirtualRobot/Nodes/Sensor.h>
11 #include <VirtualRobot/Robot.h>
12 #include <VirtualRobot/RobotNodeSet.h>
25 NJointControllerRegistration<NJointBimanualObjLevelController>
30 const armarx::NJointControllerConfigPtr& config,
33 ARMARX_INFO <<
"Initializing Bimanual Object Level Controller";
36 cfg = NJointBimanualObjLevelControllerConfigPtr::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);
98 const SensorValueBase* svlf = robUnit->getSensorDevice(
"FT L")->getSensorValue();
101 const SensorValueBase* svrf = robUnit->getSensorDevice(
"FT R")->getSensorValue();
104 leftIK.reset(
new VirtualRobot::DifferentialIK(
105 leftRNS, leftRNS->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
106 rightIK.reset(
new VirtualRobot::DifferentialIK(rightRNS,
107 rightRNS->getRobot()->getRootNode(),
108 VirtualRobot::JacobiProvider::eSVDDamped));
114 taskSpaceDMPConfig.
DMPMode = cfg->dmpMode;
115 taskSpaceDMPConfig.
DMPStyle = cfg->dmpType;
131 tcpLeft = leftRNS->getTCP();
132 tcpRight = rightRNS->getTCP();
135 KpImpedance.setZero(cfg->KpImpedance.size());
138 for (
int i = 0; i < KpImpedance.size(); ++i)
140 KpImpedance(i) = cfg->KpImpedance.at(i);
143 KdImpedance.setZero(cfg->KdImpedance.size());
146 for (
int i = 0; i < KdImpedance.size(); ++i)
148 KdImpedance(i) = cfg->KdImpedance.at(i);
151 KpAdmittance.setZero(cfg->KpAdmittance.size());
154 for (
int i = 0; i < KpAdmittance.size(); ++i)
156 KpAdmittance(i) = cfg->KpAdmittance.at(i);
159 KdAdmittance.setZero(cfg->KdAdmittance.size());
162 for (
int i = 0; i < KdAdmittance.size(); ++i)
164 KdAdmittance(i) = cfg->KdAdmittance.at(i);
167 KmAdmittance.setZero(cfg->KmAdmittance.size());
170 for (
int i = 0; i < KmAdmittance.size(); ++i)
172 KmAdmittance(i) = cfg->KmAdmittance.at(i);
176 Inferface2rtData initInt2rtData;
177 initInt2rtData.KpImpedance = KpImpedance;
178 initInt2rtData.KdImpedance = KdImpedance;
179 initInt2rtData.KmAdmittance = KmAdmittance;
180 initInt2rtData.KpAdmittance = KpAdmittance;
181 initInt2rtData.KdAdmittance = KdAdmittance;
184 leftDesiredJointValues.resize(leftTargets.size());
187 for (
size_t i = 0; i < leftTargets.size(); ++i)
189 leftDesiredJointValues(i) = cfg->leftDesiredJointValues.at(i);
192 rightDesiredJointValues.resize(rightTargets.size());
195 for (
size_t i = 0; i < rightTargets.size(); ++i)
197 rightDesiredJointValues(i) = cfg->rightDesiredJointValues.at(i);
200 KmPID.resize(cfg->KmPID.size());
203 for (
int i = 0; i < KmPID.size(); ++i)
205 KmPID(i) = cfg->KmPID.at(i);
208 virtualAcc.setZero(6);
209 virtualVel.setZero(6);
214 boxInitialPose = VirtualRobot::MathTools::quat2eigen4f(cfg->boxInitialPose[4],
215 cfg->boxInitialPose[5],
216 cfg->boxInitialPose[6],
217 cfg->boxInitialPose[3]);
218 for (
int i = 0; i < 3; ++i)
220 boxInitialPose(i, 3) = cfg->boxInitialPose[i];
223 rt2ControlData initSensorData;
224 initSensorData.deltaT = 0;
225 initSensorData.currentTime = 0;
226 initSensorData.currentPose = boxInitialPose;
227 initSensorData.currentTwist.setZero();
231 ControlInterfaceData initInterfaceData;
232 initInterfaceData.currentLeftPose = tcpLeft->getPoseInRootFrame();
233 initInterfaceData.currentRightPose = tcpRight->getPoseInRootFrame();
234 initInterfaceData.currentObjPose = boxInitialPose;
235 initInterfaceData.currentObjForce.setZero();
236 initInterfaceData.currentObjVel.setZero();
240 leftInitialPose = tcpLeft->getPoseInRootFrame();
241 rightInitialPose = tcpRight->getPoseInRootFrame();
242 leftInitialPose.block<3, 1>(0, 3) = 0.001 * leftInitialPose.block<3, 1>(0, 3);
243 rightInitialPose.block<3, 1>(0, 3) = 0.001 * rightInitialPose.block<3, 1>(0, 3);
250 forcePIDControllers.resize(12);
251 for (
size_t i = 0; i < 6; i++)
254 cfg->forceP[i], cfg->forceI[i], cfg->forceD[i], cfg->forcePIDLimits[i]));
256 cfg->forceP[i], cfg->forceI[i], cfg->forceD[i], cfg->forcePIDLimits[i]));
257 forcePIDControllers.at(i)->reset();
258 forcePIDControllers.at(i + 6)->reset();
262 filterCoeff = cfg->filterCoeff;
264 filteredOldValue.setZero(12);
267 massLeft = cfg->massLeft;
268 CoMVecLeft << cfg->CoMVecLeft[0], cfg->CoMVecLeft[1], cfg->CoMVecLeft[2];
269 forceOffsetLeft << cfg->forceOffsetLeft[0], cfg->forceOffsetLeft[1],
270 cfg->forceOffsetLeft[2];
271 torqueOffsetLeft << cfg->torqueOffsetLeft[0], cfg->torqueOffsetLeft[1],
272 cfg->torqueOffsetLeft[2];
274 massRight = cfg->massRight;
275 CoMVecRight << cfg->CoMVecRight[0], cfg->CoMVecRight[1], cfg->CoMVecRight[2];
276 forceOffsetRight << cfg->forceOffsetRight[0], cfg->forceOffsetRight[1],
277 cfg->forceOffsetRight[2];
278 torqueOffsetRight << cfg->torqueOffsetRight[0], cfg->torqueOffsetRight[1],
279 cfg->torqueOffsetRight[2];
281 sensorFrame2TcpFrameLeft.setZero();
282 sensorFrame2TcpFrameRight.setZero();
285 initData.
boxPose = boxInitialPose;
291 << leftInitialPose <<
"\n right initial pose: \n"
300 ftcalibrationTimer = 0;
301 ftOffset.setZero(12);
303 targetWrench.setZero(cfg->targetWrench.size());
304 for (
size_t i = 0; i < cfg->targetWrench.size(); ++i)
306 targetWrench(i) = cfg->targetWrench[i];
311 objCom2TCPLeftInObjFrame.setZero();
312 objCom2TCPRightInObjFrame.setZero();
318 objectDMP->setWeights(weights);
324 DMP::DVec2d res = objectDMP->getWeights();
326 for (
size_t i = 0; i < res.size(); ++i)
328 std::vector<double> cvec;
329 for (
size_t j = 0; j < res[i].size(); ++j)
331 cvec.push_back(res[i][j]);
333 resvec.push_back(cvec);
343 objectDMP->setRotWeights(weights);
349 DMP::DVec2d res = objectDMP->getRotWeights();
351 for (
size_t i = 0; i < res.size(); ++i)
353 std::vector<double> cvec;
354 for (
size_t j = 0; j < res[i].size(); ++j)
356 cvec.push_back(res[i][j]);
358 resvec.push_back(cvec);
370 leftPose.block<3, 1>(0, 3) = leftPose.block<3, 1>(0, 3) * 0.001;
371 rightPose.block<3, 1>(0, 3) = rightPose.block<3, 1>(0, 3) * 0.001;
372 boxInitPose.block<3, 1>(0, 3) =
373 0.5 * (leftPose.block<3, 1>(0, 3) + rightPose.block<3, 1>(0, 3));
374 boxInitPose.block<3, 3>(0, 0) = leftPose.block<3, 3>(0, 0);
377 initData.
boxPose = boxInitPose;
385 return "NJointBimanualObjLevelController";
398 Eigen::VectorXf currentTwist = rt2ControlBuffer.
getReadBuffer().currentTwist;
401 if (objectDMP->canVal < 1e-8)
407 objectDMP->flow(deltaT, currentPose, currentTwist);
422 controlInterfaceBuffer.
getWriteBuffer().currentLeftPose = currentLeftPose;
423 controlInterfaceBuffer.
getWriteBuffer().currentRightPose = currentRightPose;
424 double deltaT = timeSinceLastIteration.toSecondsDouble();
426 ftcalibrationTimer += deltaT;
433 leftPose.block<3, 1>(0, 3) = leftPose.block<3, 1>(0, 3) * 0.001;
434 rightPose.block<3, 1>(0, 3) = rightPose.block<3, 1>(0, 3) * 0.001;
436 virtualPose.block<3, 1>(0, 3) =
437 0.5 * (leftPose.block<3, 1>(0, 3) + rightPose.block<3, 1>(0, 3));
438 virtualPose.block<3, 3>(0, 0) = leftPose.block<3, 3>(0, 0);
439 fixedLeftRightRotOffset =
440 virtualPose.block<3, 3>(0, 0).
transpose() * rightPose.block<3, 3>(0, 0);
442 Eigen::Vector3f objCom2TCPLeftInGlobal =
443 leftPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
444 Eigen::Vector3f objCom2TCPRightInGlobal =
445 rightPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
449 objCom2TCPLeftInObjFrame =
450 virtualPose.block<3, 3>(0, 0).
transpose() * objCom2TCPLeftInGlobal;
451 objCom2TCPRightInObjFrame =
452 virtualPose.block<3, 3>(0, 0).
transpose() * objCom2TCPRightInGlobal;
456 rtGetRobot()->getSensor(
"FT L")->getRobotNode()->getPoseInRootFrame();
458 rtGetRobot()->getSensor(
"FT R")->getRobotNode()->getPoseInRootFrame();
459 leftSensorFrame.block<3, 1>(0, 3) = leftSensorFrame.block<3, 1>(0, 3) * 0.001;
460 rightSensorFrame.block<3, 1>(0, 3) = rightSensorFrame.block<3, 1>(0, 3) * 0.001;
462 sensorFrame2TcpFrameLeft.block<3, 3>(0, 0) =
463 leftPose.block<3, 3>(0, 0).transpose() * leftSensorFrame.block<3, 3>(0, 0);
464 sensorFrame2TcpFrameRight.block<3, 3>(0, 0) =
465 rightPose.block<3, 3>(0, 0).transpose() * rightSensorFrame.block<3, 3>(0, 0);
466 CoMVecLeft = sensorFrame2TcpFrameLeft.block<3, 3>(0, 0) * CoMVecLeft;
467 CoMVecRight = sensorFrame2TcpFrameRight.block<3, 3>(0, 0) * CoMVecRight;
469 ARMARX_INFO <<
"modified left pose:\n " << leftPose;
470 ARMARX_INFO <<
"modified right pose:\n " << rightPose;
480 if (ftcalibrationTimer < cfg->ftCalibrationTime)
482 ftOffset.block<3, 1>(0, 0) =
483 0.5 * ftOffset.block<3, 1>(0, 0) + 0.5 * leftForceTorque->
force;
484 ftOffset.block<3, 1>(3, 0) =
485 0.5 * ftOffset.block<3, 1>(3, 0) + 0.5 * leftForceTorque->
torque;
486 ftOffset.block<3, 1>(6, 0) =
487 0.5 * ftOffset.block<3, 1>(6, 0) + 0.5 * rightForceTorque->
force;
488 ftOffset.block<3, 1>(9, 0) =
489 0.5 * ftOffset.block<3, 1>(9, 0) + 0.5 * rightForceTorque->
torque;
491 for (
int i = 0; i < KmAdmittance.size(); ++i)
498 for (
int i = 0; i < KmAdmittance.size(); ++i)
500 KmAdmittance(i) = cfg->KmAdmittance.at(i);
505 Eigen::VectorXf deltaPoseForWrenchControl;
506 deltaPoseForWrenchControl.setZero(12);
507 for (
size_t i = 0; i < 12; ++i)
509 if (KpImpedance(i) == 0)
511 deltaPoseForWrenchControl(i) = 0;
515 deltaPoseForWrenchControl(i) = targetWrench(i) / KpImpedance(i);
516 if (deltaPoseForWrenchControl(i) > 0.1)
518 deltaPoseForWrenchControl(i) = 0.1;
520 else if (deltaPoseForWrenchControl(i) < -0.1)
522 deltaPoseForWrenchControl(i) = -0.1;
530 currentLeftPose.block<3, 1>(0, 3) = 0.001 * currentLeftPose.block<3, 1>(0, 3);
531 currentRightPose.block<3, 1>(0, 3) = 0.001 * currentRightPose.block<3, 1>(0, 3);
535 Eigen::MatrixXf graspMatrix;
536 graspMatrix.setZero(6, 12);
542 Eigen::Vector3f rvec = virtualPose.block<3, 3>(0, 0) * objCom2TCPLeftInObjFrame;
543 graspMatrix.block<3, 3>(3, 0) =
skew(rvec);
545 rvec = virtualPose.block<3, 3>(0, 0) * objCom2TCPRightInObjFrame;
546 graspMatrix.block<3, 3>(3, 6) =
skew(rvec);
553 Eigen::MatrixXf pinvGraspMatrixT =
554 leftIK->computePseudoInverseJacobianMatrix(graspMatrix.transpose(), lambda);
558 boxCurrentPose.block<3, 1>(0, 3) =
559 0.5 * (currentLeftPose.block<3, 1>(0, 3) + currentRightPose.block<3, 1>(0, 3));
560 Eigen::VectorXf boxCurrentTwist;
561 boxCurrentTwist.setZero(6);
566 Eigen::MatrixXf jacobiL =
567 leftIK->getJacobianMatrix(tcpLeft, VirtualRobot::IKSolver::CartesianSelection::All);
568 Eigen::MatrixXf jacobiR =
569 rightIK->getJacobianMatrix(tcpRight, VirtualRobot::IKSolver::CartesianSelection::All);
570 jacobiL.block<3, 8>(0, 0) = 0.001 * jacobiL.block<3, 8>(0, 0);
571 jacobiR.block<3, 8>(0, 0) = 0.001 * jacobiR.block<3, 8>(0, 0);
574 Eigen::VectorXf leftqpos;
575 Eigen::VectorXf leftqvel;
576 leftqpos.resize(leftPositionSensors.size());
577 leftqvel.resize(leftVelocitySensors.size());
578 for (
size_t i = 0; i < leftVelocitySensors.size(); ++i)
580 leftqpos(i) = leftPositionSensors[i]->position;
581 leftqvel(i) = leftVelocitySensors[i]->velocity;
584 Eigen::VectorXf rightqpos;
585 Eigen::VectorXf rightqvel;
586 rightqpos.resize(rightPositionSensors.size());
587 rightqvel.resize(rightVelocitySensors.size());
589 for (
size_t i = 0; i < rightVelocitySensors.size(); ++i)
591 rightqpos(i) = rightPositionSensors[i]->position;
592 rightqvel(i) = rightVelocitySensors[i]->velocity;
596 Eigen::VectorXf currentLeftTwist = jacobiL * leftqvel;
597 Eigen::VectorXf currentRightTwist = jacobiR * rightqvel;
599 Eigen::VectorXf currentTwist(12);
600 currentTwist << currentLeftTwist, currentRightTwist;
601 boxCurrentTwist = pinvGraspMatrixT * currentTwist;
612 Eigen::Vector3f gravity;
613 gravity << 0.0, 0.0, -9.8;
614 Eigen::Vector3f localGravityLeft = currentLeftPose.block<3, 3>(0, 0).
transpose() * gravity;
615 Eigen::Vector3f localForceVecLeft = massLeft * localGravityLeft;
616 Eigen::Vector3f localTorqueVecLeft = CoMVecLeft.cross(localForceVecLeft);
618 Eigen::Vector3f localGravityRight =
619 currentRightPose.block<3, 3>(0, 0).
transpose() * gravity;
620 Eigen::Vector3f localForceVecRight = massRight * localGravityRight;
621 Eigen::Vector3f localTorqueVecRight = CoMVecRight.cross(localForceVecRight);
624 Eigen::VectorXf wrenchesMeasured(12);
625 wrenchesMeasured << leftForceTorque->
force - forceOffsetLeft,
626 leftForceTorque->
torque - torqueOffsetLeft, rightForceTorque->
force - forceOffsetRight,
627 rightForceTorque->
torque - torqueOffsetRight;
628 for (
size_t i = 0; i < 12; i++)
630 wrenchesMeasured(i) =
631 (1 - filterCoeff) * wrenchesMeasured(i) + filterCoeff * filteredOldValue(i);
633 filteredOldValue = wrenchesMeasured;
634 wrenchesMeasured.block<3, 1>(0, 0) =
635 sensorFrame2TcpFrameLeft.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(0, 0) -
637 wrenchesMeasured.block<3, 1>(3, 0) =
638 sensorFrame2TcpFrameLeft.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(3, 0) -
640 wrenchesMeasured.block<3, 1>(6, 0) =
641 sensorFrame2TcpFrameRight.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(6, 0) -
643 wrenchesMeasured.block<3, 1>(9, 0) =
644 sensorFrame2TcpFrameRight.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(9, 0) -
651 Eigen::VectorXf wrenchesMeasuredInRoot(12);
652 wrenchesMeasuredInRoot.block<3, 1>(0, 0) =
653 currentLeftPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(0, 0);
654 wrenchesMeasuredInRoot.block<3, 1>(3, 0) =
655 currentLeftPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(3, 0);
656 wrenchesMeasuredInRoot.block<3, 1>(6, 0) =
657 currentRightPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(6, 0);
658 wrenchesMeasuredInRoot.block<3, 1>(9, 0) =
659 currentRightPose.block<3, 3>(0, 0) * wrenchesMeasured.block<3, 1>(9, 0);
663 Eigen::VectorXf objFTValue = graspMatrix * wrenchesMeasuredInRoot;
664 for (
size_t i = 0; i < 6; i++)
666 if (fabs(objFTValue(i)) < cfg->forceThreshold.at(i))
672 objFTValue(i) -= cfg->forceThreshold.at(i) * objFTValue(i) / fabs(objFTValue(i));
677 controlInterfaceBuffer.
getWriteBuffer().currentObjPose = boxCurrentPose;
678 controlInterfaceBuffer.
getWriteBuffer().currentObjVel = boxCurrentTwist.head<3>();
679 controlInterfaceBuffer.
getWriteBuffer().currentObjForce = objFTValue.head<3>();
690 Eigen::VectorXf objPoseError(6);
691 objPoseError.head<3>() = virtualPose.block<3, 1>(0, 3) - boxPose.block<3, 1>(0, 3);
693 virtualPose.block<3, 3>(0, 0) * boxPose.block<3, 3>(0, 0).transpose();
694 objPoseError.tail<3>() = VirtualRobot::MathTools::eigen3f2rpy(objDiffMat);
697 Eigen::VectorXf objAcc;
698 Eigen::VectorXf objVel;
701 for (
size_t i = 0; i < 6; i++)
704 objAcc(i) = KmAdmittance(i) * objFTValue(i) - KpAdmittance(i) * objPoseError(i) -
705 KdAdmittance(i) * virtualVel(i);
707 objVel = virtualVel + 0.5 * deltaT * (objAcc + virtualAcc);
708 Eigen::VectorXf deltaObjPose = 0.5 * deltaT * (objVel + virtualVel);
711 virtualPose.block<3, 1>(0, 3) += deltaObjPose.head<3>();
712 virtualPose.block<3, 3>(0, 0) = VirtualRobot::MathTools::rpy2eigen3f(
713 deltaObjPose(3), deltaObjPose(4), deltaObjPose(5)) *
714 virtualPose.block<3, 3>(0, 0);
720 tcpTargetPoseRight.block<3, 3>(0, 0) =
721 virtualPose.block<3, 3>(0, 0) * fixedLeftRightRotOffset;
723 tcpTargetPoseLeft.block<3, 1>(0, 3) +=
724 virtualPose.block<3, 3>(0, 0) *
725 (objCom2TCPLeftInObjFrame - deltaPoseForWrenchControl.block<3, 1>(0, 0));
726 tcpTargetPoseRight.block<3, 1>(0, 3) +=
727 virtualPose.block<3, 3>(0, 0) *
728 (objCom2TCPRightInObjFrame - deltaPoseForWrenchControl.block<3, 1>(6, 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);
752 Eigen::VectorXf leftNullspaceTorque =
753 cfg->knull * (leftDesiredJointValues - leftqpos) - cfg->dnull * leftqvel;
754 Eigen::VectorXf rightNullspaceTorque =
755 cfg->knull * (rightDesiredJointValues - rightqpos) - cfg->dnull * rightqvel;
759 Eigen::MatrixXf jtpinvL =
760 leftIK->computePseudoInverseJacobianMatrix(jacobiL.transpose(), lambda);
761 Eigen::MatrixXf jtpinvR =
762 rightIK->computePseudoInverseJacobianMatrix(jacobiR.transpose(), lambda);
763 Eigen::VectorXf leftJointDesiredTorques =
764 jacobiL.transpose() * forceImpedance.head<6>() +
765 (I - jacobiL.transpose() * jtpinvL) * leftNullspaceTorque;
766 Eigen::VectorXf rightJointDesiredTorques =
767 jacobiR.transpose() * forceImpedance.tail<6>() +
768 (I - jacobiR.transpose() * jtpinvR) * rightNullspaceTorque;
771 for (
size_t i = 0; i < leftTargets.size(); ++i)
773 float desiredTorque = leftJointDesiredTorques(i);
774 if (isnan(desiredTorque))
778 desiredTorque = (desiredTorque > cfg->torqueLimit) ? cfg->torqueLimit : desiredTorque;
779 desiredTorque = (desiredTorque < -cfg->torqueLimit) ? -cfg->torqueLimit : desiredTorque;
780 debugOutputData.
getWriteBuffer().desired_torques[leftJointNames[i]] =
781 leftJointDesiredTorques(i);
782 leftTargets.at(i)->torque = desiredTorque;
785 for (
size_t i = 0; i < rightTargets.size(); ++i)
787 float desiredTorque = rightJointDesiredTorques(i);
788 if (isnan(desiredTorque))
792 desiredTorque = (desiredTorque > cfg->torqueLimit) ? cfg->torqueLimit : desiredTorque;
793 desiredTorque = (desiredTorque < -cfg->torqueLimit) ? -cfg->torqueLimit : desiredTorque;
794 debugOutputData.
getWriteBuffer().desired_torques[rightJointNames[i]] =
795 rightJointDesiredTorques(i);
796 rightTargets.at(i)->torque = desiredTorque;
803 debugOutputData.
getWriteBuffer().wrenchesMeasuredInRoot = wrenchesMeasuredInRoot;
807 debugOutputData.
getWriteBuffer().virtualPose_x = virtualPose(0, 3);
808 debugOutputData.
getWriteBuffer().virtualPose_y = virtualPose(1, 3);
809 debugOutputData.
getWriteBuffer().virtualPose_z = virtualPose(2, 3);
811 debugOutputData.
getWriteBuffer().objPose_x = boxCurrentPose(0, 3);
812 debugOutputData.
getWriteBuffer().objPose_y = boxCurrentPose(1, 3);
813 debugOutputData.
getWriteBuffer().objPose_z = boxCurrentPose(2, 3);
836 debugOutputData.
getWriteBuffer().modifiedPoseRight_x = tcpTargetPoseRight(0, 3);
837 debugOutputData.
getWriteBuffer().modifiedPoseRight_y = tcpTargetPoseRight(1, 3);
838 debugOutputData.
getWriteBuffer().modifiedPoseRight_z = tcpTargetPoseRight(2, 3);
840 debugOutputData.
getWriteBuffer().currentPoseLeft_x = currentLeftPose(0, 3);
841 debugOutputData.
getWriteBuffer().currentPoseLeft_y = currentLeftPose(1, 3);
842 debugOutputData.
getWriteBuffer().currentPoseLeft_z = currentLeftPose(2, 3);
846 VirtualRobot::MathTools::eigen4f2quat(currentLeftPose);
852 debugOutputData.
getWriteBuffer().modifiedPoseLeft_x = tcpTargetPoseLeft(0, 3);
853 debugOutputData.
getWriteBuffer().modifiedPoseLeft_y = tcpTargetPoseLeft(1, 3);
854 debugOutputData.
getWriteBuffer().modifiedPoseLeft_z = tcpTargetPoseLeft(2, 3);
856 debugOutputData.
getWriteBuffer().currentPoseRight_x = currentRightPose(0, 3);
857 debugOutputData.
getWriteBuffer().currentPoseRight_y = currentRightPose(1, 3);
858 debugOutputData.
getWriteBuffer().currentPoseRight_z = currentRightPose(2, 3);
861 VirtualRobot::MathTools::eigen4f2quat(currentRightPose);
895 objectDMP->learnDMPFromFiles(fileNames);
902 objectDMP->setGoalPoseVec(goals);
919 VirtualRobot::MathTools::eigen4f2quat(leftPose);
920 Eigen::Vector3f boxPosi = (leftPose.block<3, 1>(0, 3) + rightPose.block<3, 1>(0, 3)) / 2;
924 std::vector<double> boxInitialPose;
925 for (
size_t i = 0; i < 3; ++i)
927 boxInitialPose.push_back(boxPosi(i) * 0.001);
929 boxInitialPose.push_back(boxOri.w);
930 boxInitialPose.push_back(boxOri.x);
931 boxInitialPose.push_back(boxOri.y);
932 boxInitialPose.push_back(boxOri.z);
934 objectDMP->prepareExecution(boxInitialPose, goals);
935 objectDMP->canVal = timeDuration;
936 objectDMP->config.motionTimeDuration = timeDuration;
945 const Ice::DoubleSeq& goals,
954 objectDMP->prepareExecution(starts, goals);
955 objectDMP->canVal = timeDuration;
956 objectDMP->config.motionTimeDuration = timeDuration;
966 const Ice::DoubleSeq& viapoint,
971 objectDMP->setViaPose(u, viapoint);
977 objectDMP->removeAllViaPoints();
985 Eigen::VectorXf setpoint;
986 setpoint.setZero(
value.size());
989 for (
size_t i = 0; i <
value.size(); ++i)
991 setpoint(i) =
value.at(i);
1001 const Ice::Current&)
1003 Eigen::VectorXf setpoint;
1004 setpoint.setZero(
value.size());
1007 for (
size_t i = 0; i <
value.size(); ++i)
1009 setpoint(i) =
value.at(i);
1019 const Ice::Current&)
1021 Eigen::VectorXf setpoint;
1022 setpoint.setZero(
value.size());
1025 for (
size_t i = 0; i <
value.size(); ++i)
1027 setpoint(i) =
value.at(i);
1037 const Ice::Current&)
1039 Eigen::VectorXf setpoint;
1040 setpoint.setZero(
value.size());
1043 for (
size_t i = 0; i <
value.size(); ++i)
1045 setpoint(i) =
value.at(i);
1057 std::vector<float> tvelvec = {tvel(0), tvel(1), tvel(2)};
1065 std::vector<float> fvelvec = {fvel(0), fvel(1), fvel(2)};
1071 const Ice::Current&)
1073 Eigen::VectorXf setpoint;
1074 setpoint.setZero(
value.size());
1077 for (
size_t i = 0; i <
value.size(); ++i)
1079 setpoint(i) =
value.at(i);
1095 for (
auto& pair :
values)
1097 datafields[pair.first] =
new Variant(pair.second);
1101 for (
int i = 0; i < forceImpedance.rows(); ++i)
1103 std::stringstream ss;
1105 std::string data_name =
"forceImpedance_" + ss.str();
1106 datafields[data_name] =
new Variant(forceImpedance(i));
1110 for (
int i = 0; i < forcePID.rows(); ++i)
1112 std::stringstream ss;
1114 std::string data_name =
"forcePID_" + ss.str();
1115 datafields[data_name] =
new Variant(forcePID(i));
1120 for (
int i = 0; i < poseError.rows(); ++i)
1122 std::stringstream ss;
1124 std::string data_name =
"poseError_" + ss.str();
1125 datafields[data_name] =
new Variant(poseError(i));
1128 Eigen::VectorXf wrenchesConstrained =
1130 for (
int i = 0; i < wrenchesConstrained.rows(); ++i)
1132 std::stringstream ss;
1134 std::string data_name =
"wrenchesConstrained_" + ss.str();
1135 datafields[data_name] =
new Variant(wrenchesConstrained(i));
1138 Eigen::VectorXf wrenchesMeasuredInRoot =
1140 for (
int i = 0; i < wrenchesMeasuredInRoot.rows(); ++i)
1142 std::stringstream ss;
1144 std::string data_name =
"wrenchesMeasuredInRoot_" + ss.str();
1145 datafields[data_name] =
new Variant(wrenchesMeasuredInRoot(i));
1168 datafields[
"virtualPose_x"] =
1170 datafields[
"virtualPose_y"] =
1172 datafields[
"virtualPose_z"] =
1182 datafields[
"objTorque_x"] =
1184 datafields[
"objTorque_y"] =
1186 datafields[
"objTorque_z"] =
1196 datafields[
"deltaPose_x"] =
1198 datafields[
"deltaPose_y"] =
1200 datafields[
"deltaPose_z"] =
1202 datafields[
"deltaPose_rx"] =
1204 datafields[
"deltaPose_ry"] =
1206 datafields[
"deltaPose_rz"] =
1209 datafields[
"modifiedPoseRight_x"] =
1211 datafields[
"modifiedPoseRight_y"] =
1213 datafields[
"modifiedPoseRight_z"] =
1215 datafields[
"currentPoseLeft_x"] =
1217 datafields[
"currentPoseLeft_y"] =
1219 datafields[
"currentPoseLeft_z"] =
1226 datafields[
"rightQuat_w"] =
1228 datafields[
"rightQuat_x"] =
1230 datafields[
"rightQuat_y"] =
1232 datafields[
"rightQuat_z"] =
1235 datafields[
"modifiedPoseLeft_x"] =
1237 datafields[
"modifiedPoseLeft_y"] =
1239 datafields[
"modifiedPoseLeft_z"] =
1242 datafields[
"currentPoseRight_x"] =
1244 datafields[
"currentPoseRight_y"] =
1246 datafields[
"currentPoseRight_z"] =
1248 datafields[
"dmpBoxPose_x"] =
1250 datafields[
"dmpBoxPose_y"] =
1252 datafields[
"dmpBoxPose_z"] =
1258 datafields[
"modifiedTwist_lx"] =
1260 datafields[
"modifiedTwist_ly"] =
1262 datafields[
"modifiedTwist_lz"] =
1264 datafields[
"modifiedTwist_rx"] =
1266 datafields[
"modifiedTwist_ry"] =
1268 datafields[
"modifiedTwist_rz"] =
1276 debugObs->setDebugChannel(
"BimanualForceController", datafields);
1285 runTask(
"NJointBimanualObjLevelController",
1290 while (
getState() == eManagedIceObjectStarted)
1296 c.waitForCycleDuration();