5 NJointControllerRegistration<NJointBimanualCCDMPController>
9 armarx::NJointControllerDescriptionProviderInterfacePtr prov,
10 const armarx::NJointControllerConfigPtr& config,
14 cfg = NJointBimanualCCDMPControllerConfigPtr::dynamicCast(config);
16 RobotUnitPtr robotUnit = RobotUnitPtr::dynamicCast(prov);
19 leftRNS = robotUnit->getRtRobot()->getRobotNodeSet(
"LeftArm");
20 rnsLeftBody = robotUnit->getRtRobot()->getRobotNodeSet(
"LeftArmCol");
21 for (
size_t i = 0; i < leftRNS->getSize(); ++i)
23 std::string jointName = leftRNS->getNode(i)->getName();
25 leftJointNames.push_back(jointName);
26 ControlTargetBase* ct = prov->getControlTarget(jointName, ControlModes::Torque1DoF);
27 const SensorValueBase* sv = prov->getSensorValue(jointName);
28 leftTargets.push_back(ct->asA<ControlTarget1DoFActuatorTorque>());
29 const SensorValue1DoFActuatorVelocity* velocitySensor =
30 sv->asA<SensorValue1DoFActuatorVelocity>();
31 const SensorValue1DoFActuatorPosition* positionSensor =
32 sv->asA<SensorValue1DoFActuatorPosition>();
33 const SensorValue1DoFActuatorAcceleration* accelerationSensor =
34 sv->asA<SensorValue1DoFActuatorAcceleration>();
45 if (!accelerationSensor)
47 ARMARX_WARNING <<
"No accelerationSensor available for " << jointName;
51 leftVelocitySensors.push_back(velocitySensor);
52 leftPositionSensors.push_back(positionSensor);
53 leftAccelerationSensors.push_back(accelerationSensor);
57 rnsRightBody = robotUnit->getRtRobot()->getRobotNodeSet(
"RightArmCol");
59 rightRNS = robotUnit->getRtRobot()->getRobotNodeSet(
"RightArm");
60 for (
size_t i = 0; i < rightRNS->getSize(); ++i)
62 std::string jointName = rightRNS->getNode(i)->getName();
63 rightJointNames.push_back(jointName);
64 ControlTargetBase* ct = prov->getControlTarget(jointName, ControlModes::Torque1DoF);
65 const SensorValueBase* sv = prov->getSensorValue(jointName);
66 rightTargets.push_back(ct->asA<ControlTarget1DoFActuatorTorque>());
67 const SensorValue1DoFActuatorVelocity* velocitySensor =
68 sv->asA<SensorValue1DoFActuatorVelocity>();
69 const SensorValue1DoFActuatorPosition* positionSensor =
70 sv->asA<SensorValue1DoFActuatorPosition>();
71 const SensorValue1DoFActuatorAcceleration* accelerationSensor =
72 sv->asA<SensorValue1DoFActuatorAcceleration>();
83 if (!accelerationSensor)
85 ARMARX_WARNING <<
"No accelerationSensor available for " << jointName;
88 rightVelocitySensors.push_back(velocitySensor);
89 rightPositionSensors.push_back(positionSensor);
90 rightAccelerationSensors.push_back(accelerationSensor);
94 const SensorValueBase* svlf = prov->getSensorValue(
"FT L");
95 leftForceTorque = svlf->
asA<SensorValueForceTorque>();
96 const SensorValueBase* svrf = prov->getSensorValue(
"FT R");
97 rightForceTorque = svrf->
asA<SensorValueForceTorque>();
99 leftIK.reset(
new VirtualRobot::DifferentialIK(
100 leftRNS, leftRNS->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
101 rightIK.reset(
new VirtualRobot::DifferentialIK(rightRNS,
102 rightRNS->getRobot()->getRootNode(),
103 VirtualRobot::JacobiProvider::eSVDDamped));
106 TaskSpaceDMPControllerConfig taskSpaceDMPConfig;
107 taskSpaceDMPConfig.motionTimeDuration = cfg->timeDuration;
108 taskSpaceDMPConfig.DMPKernelSize = cfg->kernelSize;
109 taskSpaceDMPConfig.DMPMode = cfg->dmpMode;
110 taskSpaceDMPConfig.DMPStyle = cfg->dmpType;
111 taskSpaceDMPConfig.DMPAmplitude = 1.0;
112 taskSpaceDMPConfig.phaseStopParas.goDist = cfg->phaseDist0;
113 taskSpaceDMPConfig.phaseStopParas.backDist = cfg->phaseDist1;
114 taskSpaceDMPConfig.phaseStopParas.Kpos = cfg->phaseKpPos;
115 taskSpaceDMPConfig.phaseStopParas.Dpos = 0;
116 taskSpaceDMPConfig.phaseStopParas.Kori = cfg->phaseKpOri;
117 taskSpaceDMPConfig.phaseStopParas.Dori = 0;
118 taskSpaceDMPConfig.phaseStopParas.mm2radi = cfg->posToOriRatio;
119 taskSpaceDMPConfig.phaseStopParas.maxValue = cfg->phaseL;
120 taskSpaceDMPConfig.phaseStopParas.slop = cfg->phaseK;
124 new TaskSpaceDMPController(
"leftLeader", taskSpaceDMPConfig));
126 new TaskSpaceDMPController(
"leftFollower", taskSpaceDMPConfig));
128 new TaskSpaceDMPController(
"rightLeader", taskSpaceDMPConfig));
130 new TaskSpaceDMPController(
"rightFollower", taskSpaceDMPConfig));
132 leftGroup.push_back(leftLeader);
133 leftGroup.push_back(rightFollower);
135 rightGroup.push_back(rightLeader);
136 rightGroup.push_back(leftFollower);
138 bothLeaderGroup.push_back(leftLeader);
139 bothLeaderGroup.push_back(rightLeader);
142 tcpLeft = leftRNS->getTCP();
143 tcpRight = rightRNS->getTCP();
144 NJointBimanualCCDMPControllerSensorData initSensorData;
145 initSensorData.deltaT = 0;
146 initSensorData.currentTime = 0;
147 initSensorData.currentLeftPose = leftRNS->getTCP()->getPoseInRootFrame();
148 initSensorData.currentRightPose = rightRNS->getTCP()->getPoseInRootFrame();
153 NJointBimanualCCDMPControllerControlData initData;
154 initData.leftTargetVel.resize(6);
155 initData.leftTargetVel.setZero();
156 initData.rightTargetVel.resize(6);
157 initData.rightTargetVel.setZero();
160 leftDesiredJointValues.resize(leftTargets.size());
163 for (
size_t i = 0; i < leftTargets.size(); ++i)
165 leftDesiredJointValues(i) = cfg->leftDesiredJointValues.at(i);
168 rightDesiredJointValues.resize(rightTargets.size());
171 for (
size_t i = 0; i < rightTargets.size(); ++i)
173 rightDesiredJointValues(i) = cfg->rightDesiredJointValues.at(i);
176 KoriFollower = cfg->KoriFollower;
177 KposFollower = cfg->KposFollower;
179 kpos << cfg->Kpos[0], cfg->Kpos[1], cfg->Kpos[2];
180 dpos << cfg->Dpos[0], cfg->Dpos[1], cfg->Dpos[2];
181 kori << cfg->Kori[0], cfg->Kori[1], cfg->Kori[2];
182 dori << cfg->Dori[0], cfg->Dori[1], cfg->Dori[2];
188 torqueLimit = cfg->torqueLimit;
192 forceC_des.resize(12);
199 for (
size_t i = 0; i < 12; i++)
201 kpf(i) = cfg->Kpf.at(i);
202 kif(i) = cfg->Kif.at(i);
203 forceC_des(i) = cfg->DesiredForce.at(i);
206 boxWidth = cfg->BoxWidth;
208 filtered_leftForce.setZero();
209 filtered_leftTorque.setZero();
210 filtered_rightForce.setZero();
211 filtered_rightTorque.setZero();
218 offset_leftForce(0) = -4.34;
219 offset_leftForce(1) = -8.21;
220 offset_leftForce(2) = 15.59;
222 offset_leftTorque(0) = 1.42;
223 offset_leftTorque(1) = 0.29;
224 offset_leftTorque(2) = 0.09;
226 offset_rightForce(0) = 2.88;
227 offset_rightForce(1) = 11.15;
228 offset_rightForce(2) = -20.18;
230 offset_rightTorque(0) = -1.83;
231 offset_rightTorque(1) = 0.34;
232 offset_rightTorque(2) = -0.01;
235 filterTimeConstant = cfg->FilterTimeConstant;
237 ftPIDController.resize(12);
238 for (
size_t i = 0; i < ftPIDController.size(); i++)
240 ftPIDController[i].reset(
new PIDController(kpf(i), kif(i), 0.0, 10, 10));
243 isForceCompensateDone =
false;
249 return "NJointBimanualCCDMPController";
263 Eigen::VectorXf leftTargetVel;
264 leftTargetVel.resize(6);
265 leftTargetVel.setZero();
266 Eigen::VectorXf rightTargetVel;
267 rightTargetVel.resize(6);
268 rightTargetVel.setZero();
270 std::vector<TaskSpaceDMPControllerPtr> currentControlGroup;
273 Eigen::VectorXf currentLeaderTwist;
274 Eigen::VectorXf currentFollowerTwist;
275 if (leaderName ==
"Left")
277 currentControlGroup = leftGroup;
278 currentLeaderPose = controllerSensorData.
getReadBuffer().currentLeftPose;
279 currentFollowerPose = controllerSensorData.
getReadBuffer().currentRightPose;
280 currentLeaderTwist = controllerSensorData.
getReadBuffer().currentLeftTwist;
281 currentFollowerTwist = controllerSensorData.
getReadBuffer().currentRightTwist;
283 else if (leaderName ==
"right")
285 currentControlGroup = rightGroup;
286 currentLeaderPose = controllerSensorData.
getReadBuffer().currentRightPose;
287 currentFollowerPose = controllerSensorData.
getReadBuffer().currentLeftPose;
288 currentLeaderTwist = controllerSensorData.
getReadBuffer().currentRightTwist;
289 currentFollowerTwist = controllerSensorData.
getReadBuffer().currentLeftTwist;
293 currentControlGroup = bothLeaderGroup;
297 leaderDMPleft->flow(deltaT,
300 leaderDMPright->flow(deltaT,
304 Eigen::VectorXf leftTargetVel = leaderDMPleft->getTargetVelocity();
306 Eigen::VectorXf rightTargetVel = leaderDMPright->getTargetVelocity();
309 virtualtimer = leaderDMPleft->canVal;
324 leaderDMP->flow(deltaT, currentLeaderPose, currentLeaderTwist);
327 currentFollowerLocalPose.block<3, 3>(0, 0) =
328 currentFollowerPose.block<3, 3>(0, 0) * currentLeaderPose.block<3, 3>(0, 0).inverse();
329 currentFollowerLocalPose.block<3, 1>(0, 3) =
330 currentFollowerLocalPose.block<3, 3>(0, 0) *
331 (currentFollowerPose.block<3, 1>(0, 3) - currentLeaderPose.block<3, 1>(0, 3));
332 followerDMP->flow(deltaT, currentFollowerPose, currentFollowerTwist);
334 Eigen::VectorXf leaderTargetVel = leaderDMP->getTargetVelocity();
336 Eigen::Matrix4f followerLocalTargetPose = followerDMP->getTargetPoseMat();
337 std::vector<double> followerLocalTargetPoseVec = followerDMP->getTargetPose();
340 followerTargetPose.block<3, 3>(0, 0) =
341 followerLocalTargetPose.block<3, 3>(0, 0) * currentLeaderPose.block<3, 3>(0, 0);
342 followerTargetPose.block<3, 1>(0, 3) =
343 currentLeaderPose.block<3, 3>(0, 0) * followerLocalTargetPose.block<3, 1>(0, 3) +
344 currentLeaderPose.block<3, 1>(0, 3);
347 Eigen::VectorXf followerLocalTargetVel = followerDMP->getTargetVelocity();
348 Eigen::VectorXf followerTargetVel = followerLocalTargetVel;
350 followerTargetVel.block<3, 1>(0, 0) =
352 (followerTargetPose.block<3, 1>(0, 3) - currentFollowerPose.block<3, 1>(0, 3));
356 followerTargetPose.block<3, 3>(0, 0) * currentFollowerPose.block<3, 3>(0, 0).inverse();
357 Eigen::Vector3f followerDiffRPY =
358 KoriFollower * VirtualRobot::MathTools::eigen3f2rpy(followerDiffMat);
359 followerTargetVel(3) = followerDiffRPY(0);
360 followerTargetVel(4) = followerDiffRPY(1);
361 followerTargetVel(5) = followerDiffRPY(2);
363 virtualtimer = leaderDMP->canVal;
366 std::vector<double> leftDMPTarget;
367 std::vector<double> rightDMPTarget;
372 if (leaderName ==
"Left")
374 leftTargetVel = leaderTargetVel;
375 rightTargetVel = followerTargetVel;
377 leftDMPTarget = leaderDMP->getTargetPose();
378 rightDMPTarget = followerLocalTargetPoseVec;
381 leftTargetPose = leaderTargetPose;
382 rightTargetPose = followerLocalTargetPose;
384 else if (leaderName ==
"right")
386 rightTargetVel = leaderTargetVel;
387 leftTargetVel = followerTargetVel;
389 rightDMPTarget = leaderDMP->getTargetPose();
390 leftDMPTarget = followerLocalTargetPoseVec;
392 rightTargetPose = leaderTargetPose;
393 leftTargetPose = followerLocalTargetPose;
473 NJointBimanualCCDMPController::getControlWrench(
const Eigen::VectorXf& tcptwist,
503 double deltaT = timeSinceLastIteration.toSecondsDouble();
504 controllerSensorData.
getWriteBuffer().currentLeftPose = tcpLeft->getPoseInRootFrame();
505 controllerSensorData.
getWriteBuffer().currentRightPose = tcpRight->getPoseInRootFrame();
544 Eigen::MatrixXf jacobiL =
545 leftIK->getJacobianMatrix(tcpLeft, VirtualRobot::IKSolver::CartesianSelection::All);
546 jacobiL.block<3, 8>(0, 0) = 0.001 * jacobiL.block<3, 8>(0, 0);
548 Eigen::VectorXf leftqpos;
549 Eigen::VectorXf leftqvel;
550 leftqpos.resize(leftPositionSensors.size());
551 leftqvel.resize(leftVelocitySensors.size());
552 for (
size_t i = 0; i < leftVelocitySensors.size(); ++i)
554 leftqpos(i) = leftPositionSensors[i]->position;
555 leftqvel(i) = leftVelocitySensors[i]->velocity;
558 Eigen::MatrixXf jacobiR =
559 rightIK->getJacobianMatrix(tcpRight, VirtualRobot::IKSolver::CartesianSelection::All);
560 jacobiR.block<3, 8>(0, 0) = 0.001 * jacobiR.block<3, 8>(0, 0);
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;
574 Eigen::VectorXf currentLeftTwist = jacobiL * leftqvel;
575 Eigen::VectorXf currentRightTwist = jacobiR * rightqvel;
578 controllerSensorData.
getWriteBuffer().currentLeftTwist = currentLeftTwist;
579 controllerSensorData.
getWriteBuffer().currentRightTwist = currentRightTwist;
591 int nl = leftRNS->getSize();
592 int nr = rightRNS->getSize();
602 Eigen::Vector3f localDistanceCoM;
603 localDistanceCoM << 0.5 * boxWidth, 0, 0;
607 -leftCurrentPose.block<3, 3>(0, 0) *
609 Eigen::Vector3f rr = rightCurrentPose.block<3, 3>(0, 0) * localDistanceCoM;
612 leftGraspMatrix.block<3, 3>(3, 0) << 0, -rl(2), rl(1), rl(2), 0, -rl(0), -rl(1), rl(0), 0;
613 rightGraspMatrix.block<3, 3>(3, 0) << 0, -rr(2), rr(1), rr(2), 0, -rr(0), -rr(1), rr(0), 0;
614 Eigen::MatrixXf graspMatrix;
615 graspMatrix.resize(6, 12);
616 graspMatrix << leftGraspMatrix, rightGraspMatrix;
619 Eigen::MatrixXf jacobi;
620 jacobi.resize(12, n);
621 jacobi.setZero(12, n);
622 jacobi.block<6, 8>(0, 0) = jacobiL;
623 jacobi.block<6, 8>(6, 8) = jacobiR;
625 Eigen::MatrixXf pinvGraspMatrix =
626 leftIK->computePseudoInverseJacobianMatrix(graspMatrix, 1);
627 Eigen::MatrixXf proj2GraspNullspace =
629 Eigen::MatrixXf jacobiConstrained = proj2GraspNullspace * jacobi;
631 Eigen::MatrixXf pinvJacobiC =
632 leftIK->computePseudoInverseJacobianMatrix(jacobiConstrained, 1);
633 Eigen::MatrixXf projection =
638 Eigen::MatrixXf leftInertialMatrix;
639 Eigen::MatrixXf rightInertialMatrix;
640 leftInertialMatrix.setZero(nl, nl);
641 rightInertialMatrix.setZero(nr, nr);
643 for (
size_t i = 0; i < rnsLeftBody->getNodeNames().size(); ++i)
645 VirtualRobot::RobotNodePtr rnbody = rnsLeftBody->getNode(i);
646 VirtualRobot::RobotNodePtr rnjoint = leftRNS->getNode(i + 1);
648 Eigen::MatrixXf jacobipos_rn =
649 0.001 * leftIK->getJacobianMatrix(
651 Eigen::MatrixXf jacobiori_rn = leftIK->getJacobianMatrix(
655 float m = rnbody->getMass();
657 leftInertialMatrix += m * jacobipos_rn.transpose() * jacobipos_rn +
658 jacobiori_rn.transpose() * InertiaMatrix * jacobiori_rn;
661 for (
size_t i = 0; i < rnsRightBody->getNodeNames().size(); ++i)
663 VirtualRobot::RobotNodePtr rnbody = rnsRightBody->getNode(i);
664 VirtualRobot::RobotNodePtr rnjoint = rightRNS->getNode(i + 1);
666 Eigen::MatrixXf jacobipos_rn =
667 0.001 * rightIK->getJacobianMatrix(
669 Eigen::MatrixXf jacobiori_rn = rightIK->getJacobianMatrix(
673 float m = rnbody->getMass();
676 rightInertialMatrix += m * jacobipos_rn.transpose() * jacobipos_rn +
677 jacobiori_rn.transpose() * InertiaMatrix * jacobiori_rn;
679 Eigen::MatrixXf M = Eigen::MatrixXf::Zero(n, n);
680 M.topLeftCorner(nl, nl) = leftInertialMatrix;
681 M.bottomRightCorner(nr, nr) = rightInertialMatrix;
683 Eigen::MatrixXf Mc = M + projection * M - M * projection;
687 double filterFactor = 1 / ((filterTimeConstant / deltaT) + 1);
689 filtered_leftForce = (1 - filterFactor) * filtered_leftForce +
690 filterFactor * (leftForceTorque->
force - offset_leftForce);
691 filtered_leftTorque = (1 - filterFactor) * filtered_leftTorque +
692 filterFactor * (leftForceTorque->
torque - offset_leftTorque);
693 filtered_rightForce = (1 - filterFactor) * filtered_rightForce +
694 filterFactor * (rightForceTorque->
force - offset_rightForce);
695 filtered_rightTorque = (1 - filterFactor) * filtered_rightForce +
696 filterFactor * (rightForceTorque->
torque - offset_rightTorque);
698 Eigen::VectorXf filteredForce;
699 filteredForce.resize(12);
700 filteredForce << filtered_leftForce, filtered_leftTorque, filtered_rightForce,
701 filtered_rightTorque;
702 filteredForce.block<3, 1>(0, 0) =
703 leftCurrentPose.block<3, 3>(0, 0) * filteredForce.block<3, 1>(0, 0);
704 filteredForce.block<3, 1>(3, 0) =
705 leftCurrentPose.block<3, 3>(0, 0) * filteredForce.block<3, 1>(3, 0);
706 filteredForce.block<3, 1>(6, 0) =
707 rightCurrentPose.block<3, 3>(0, 0) * filteredForce.block<3, 1>(6, 0);
708 filteredForce.block<3, 1>(9, 0) =
709 rightCurrentPose.block<3, 3>(0, 0) * filteredForce.block<3, 1>(9, 0);
713 Eigen::VectorXf constrainedForceMeasure = proj2GraspNullspace * filteredForce;
715 constrainedForceMeasure.block<3, 1>(0, 0) = leftCurrentPose.block<3, 3>(0, 0).transpose() *
716 constrainedForceMeasure.block<3, 1>(0, 0);
717 constrainedForceMeasure.block<3, 1>(3, 0) = leftCurrentPose.block<3, 3>(0, 0).transpose() *
718 constrainedForceMeasure.block<3, 1>(3, 0);
719 constrainedForceMeasure.block<3, 1>(6, 0) = rightCurrentPose.block<3, 3>(0, 0).transpose() *
720 constrainedForceMeasure.block<3, 1>(6, 0);
721 constrainedForceMeasure.block<3, 1>(9, 0) = rightCurrentPose.block<3, 3>(0, 0).transpose() *
722 constrainedForceMeasure.block<3, 1>(9, 0);
723 Eigen::VectorXf forceConstrained = Eigen::VectorXf::Zero(12);
724 for (
size_t i = 0; i < 12; i++)
726 ftPIDController[i]->update(constrainedForceMeasure(i), forceC_des(i));
727 forceConstrained(i) = ftPIDController[i]->getControlValue() + forceC_des(i);
733 forceConstrained.block<3, 1>(0, 0) =
734 leftCurrentPose.block<3, 3>(0, 0) * forceConstrained.block<3, 1>(0, 0);
735 forceConstrained.block<3, 1>(3, 0) =
736 leftCurrentPose.block<3, 3>(0, 0) * forceConstrained.block<3, 1>(3, 0);
737 forceConstrained.block<3, 1>(6, 0) =
738 rightCurrentPose.block<3, 3>(0, 0) * forceConstrained.block<3, 1>(6, 0);
739 forceConstrained.block<3, 1>(9, 0) =
740 rightCurrentPose.block<3, 3>(0, 0) * forceConstrained.block<3, 1>(9, 0);
746 Eigen::Vector3f targetTCPLinearVelocity;
747 targetTCPLinearVelocity << 0.001 * leftTargetVel(0), 0.001 * leftTargetVel(1),
748 0.001 * leftTargetVel(2);
750 Eigen::Vector3f currentTCPLinearVelocity;
751 currentTCPLinearVelocity << currentLeftTwist(0), currentLeftTwist(1),
753 Eigen::Vector3f currentTCPAngularVelocity;
754 currentTCPAngularVelocity << currentLeftTwist(3), currentLeftTwist(4),
756 Eigen::Vector3f currentTCPPosition = leftCurrentPose.block<3, 1>(0, 3);
757 Eigen::Vector3f desiredPosition = leftTargetPose.block<3, 1>(0, 3);
759 Eigen::Vector3f tcpDesiredForce =
760 0.001 * kpos.cwiseProduct(desiredPosition - currentTCPPosition) +
761 dpos.cwiseProduct(targetTCPLinearVelocity - currentTCPLinearVelocity);
763 Eigen::Matrix3f diffMat = leftTargetPose.block<3, 3>(0, 0) * currentRotMat.inverse();
764 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
765 Eigen::Vector3f tcpDesiredTorque =
766 kori.cwiseProduct(rpy) - dori.cwiseProduct(currentTCPAngularVelocity);
767 leftJointControlWrench << tcpDesiredForce, tcpDesiredTorque;
773 Eigen::Vector3f targetTCPLinearVelocity;
774 targetTCPLinearVelocity << 0.001 * rightTargetVel(0), 0.001 * rightTargetVel(1),
775 0.001 * rightTargetVel(2);
777 Eigen::Vector3f currentTCPLinearVelocity;
778 currentTCPLinearVelocity << currentRightTwist(0), currentRightTwist(1),
779 currentRightTwist(2);
780 Eigen::Vector3f currentTCPAngularVelocity;
781 currentTCPAngularVelocity << currentRightTwist(3), currentRightTwist(4),
782 currentRightTwist(5);
783 Eigen::Vector3f currentTCPPosition = rightCurrentPose.block<3, 1>(0, 3);
784 Eigen::Vector3f desiredPosition = rightTargetPose.block<3, 1>(0, 3);
786 Eigen::Vector3f tcpDesiredForce =
787 0.001 * kpos.cwiseProduct(desiredPosition - currentTCPPosition) -
788 dpos.cwiseProduct(targetTCPLinearVelocity - currentTCPLinearVelocity);
790 Eigen::Matrix3f diffMat = rightTargetPose.block<3, 3>(0, 0) * currentRotMat.inverse();
791 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
792 Eigen::Vector3f tcpDesiredTorque =
793 kori.cwiseProduct(rpy) - dori.cwiseProduct(currentTCPAngularVelocity);
794 rightJointControlWrench << tcpDesiredForce, tcpDesiredTorque;
797 Eigen::VectorXf forceUnconstrained(12);
798 forceUnconstrained << leftJointControlWrench, rightJointControlWrench;
800 Eigen::VectorXf unConstrainedForceMeasure = pinvGraspMatrix * graspMatrix * filteredForce;
802 Eigen::MatrixXf taskSpaceInertia = (jacobi * M.inverse() * jacobi.transpose()).inverse();
809 Eigen::VectorXf leftNullspaceTorque =
810 knull * (leftDesiredJointValues - leftqpos) - dnull * leftqvel;
811 Eigen::VectorXf rightNullspaceTorque =
812 knull * (rightDesiredJointValues - rightqpos) - dnull * rightqvel;
815 Eigen::MatrixXf jtpinvL =
816 leftIK->computePseudoInverseJacobianMatrix(jacobiL.transpose(), lambda);
817 Eigen::MatrixXf jtpinvR =
818 leftIK->computePseudoInverseJacobianMatrix(jacobiR.transpose(), lambda);
819 forceUnconstrained.head(8) =
820 forceUnconstrained.head(8) + (I - jacobiL.transpose() * jtpinvL) * leftNullspaceTorque;
821 forceUnconstrained.tail<8>() = forceUnconstrained.tail<8>() +
822 (I - jacobiR.transpose() * jtpinvR) * rightNullspaceTorque;
861 Eigen::VectorXf torqueInput = jacobi.transpose() * (forceUnconstrained + forceConstrained);
863 Eigen::VectorXf leftJointDesiredTorques = torqueInput.head(nl);
864 Eigen::VectorXf rightJointDesiredTorques = torqueInput.block<8, 1>(8, 0);
867 for (
size_t i = 0; i < leftTargets.size(); ++i)
869 float desiredTorque = leftJointDesiredTorques(i);
871 if (isnan(desiredTorque))
876 desiredTorque = (desiredTorque > torqueLimit) ? torqueLimit : desiredTorque;
877 desiredTorque = (desiredTorque < -torqueLimit) ? -torqueLimit : desiredTorque;
879 debugDataInfo.
getWriteBuffer().desired_torques[leftJointNames[i]] =
880 leftJointDesiredTorques(i);
882 leftTargets.at(i)->torque = desiredTorque;
886 for (
size_t i = 0; i < rightTargets.size(); ++i)
888 float desiredTorque = rightJointDesiredTorques(i);
890 if (isnan(desiredTorque))
895 desiredTorque = (desiredTorque > torqueLimit) ? torqueLimit : desiredTorque;
896 desiredTorque = (desiredTorque < -torqueLimit) ? -torqueLimit : desiredTorque;
898 debugDataInfo.
getWriteBuffer().desired_torques[rightJointNames[i]] =
899 rightJointDesiredTorques(i);
901 rightTargets.at(i)->torque = desiredTorque;
912 debugDataInfo.
getWriteBuffer().leftTargetPose_x = leftTargetPose(0, 3);
913 debugDataInfo.
getWriteBuffer().leftTargetPose_y = leftTargetPose(1, 3);
914 debugDataInfo.
getWriteBuffer().leftTargetPose_z = leftTargetPose(2, 3);
915 debugDataInfo.
getWriteBuffer().leftCurrentPose_x = leftCurrentPose(0, 3);
916 debugDataInfo.
getWriteBuffer().leftCurrentPose_y = leftCurrentPose(1, 3);
917 debugDataInfo.
getWriteBuffer().leftCurrentPose_z = leftCurrentPose(2, 3);
920 debugDataInfo.
getWriteBuffer().rightTargetPose_x = rightTargetPose(0, 3);
921 debugDataInfo.
getWriteBuffer().rightTargetPose_y = rightTargetPose(1, 3);
922 debugDataInfo.
getWriteBuffer().rightTargetPose_z = rightTargetPose(2, 3);
924 debugDataInfo.
getWriteBuffer().rightCurrentPose_x = rightCurrentPose(0, 3);
925 debugDataInfo.
getWriteBuffer().rightCurrentPose_y = rightCurrentPose(1, 3);
926 debugDataInfo.
getWriteBuffer().rightCurrentPose_z = rightCurrentPose(2, 3);
929 for (
size_t i = 0; i < 12; ++i)
931 std::stringstream ss;
933 std::string name =
"forceConstrained_" + ss.str();
934 debugDataInfo.
getWriteBuffer().constrained_force[name] = filteredForce(i);
985 const Ice::StringSeq& fileNames,
988 if (name ==
"LeftLeader")
990 leftGroup.at(0)->learnDMPFromFiles(fileNames);
992 else if (name ==
"LeftFollower")
994 rightGroup.at(1)->learnDMPFromFiles(fileNames);
996 else if (name ==
"RightLeader")
998 rightGroup.at(0)->learnDMPFromFiles(fileNames);
1002 leftGroup.at(1)->learnDMPFromFiles(fileNames);
1009 const Ice::DoubleSeq& viapoint,
1010 const Ice::Current&)
1013 if (leaderName ==
"Left")
1015 leftGroup.at(0)->setViaPose(u, viapoint);
1019 rightGroup.at(0)->setViaPose(u, viapoint);
1027 if (leaderName ==
"Left")
1029 leftGroup.at(0)->setGoalPoseVec(goals);
1033 rightGroup.at(0)->setGoalPoseVec(goals);
1042 if (leaderName ==
"Left")
1044 leaderName =
"Right";
1045 rightGroup.at(0)->canVal = virtualtimer;
1046 rightGroup.at(1)->canVal = virtualtimer;
1050 leaderName =
"Left";
1051 leftGroup.at(0)->canVal = virtualtimer;
1052 leftGroup.at(1)->canVal = virtualtimer;
1059 const Ice::DoubleSeq& rightGoals,
1060 const Ice::Current&)
1062 virtualtimer = cfg->timeDuration;
1067 leftGroup.at(0)->prepareExecution(leftGroup.at(0)->eigen4f2vec(leftPose), leftGoals);
1068 rightGroup.at(0)->prepareExecution(rightGroup.at(0)->eigen4f2vec(rightPose), rightGoals);
1071 ARMARX_INFO <<
"leftgroup goal local pose: " << getLocalPose(leftGoals, rightGoals);
1073 leftGroup.at(1)->prepareExecution(getLocalPose(leftPose, rightPose),
1074 getLocalPose(leftGoals, rightGoals));
1075 rightGroup.at(1)->prepareExecution(getLocalPose(rightPose, leftPose),
1076 getLocalPose(rightGoals, leftGoals));
1078 controllerTask->start();
1082 NJointBimanualCCDMPController::getLocalPose(
const Eigen::Matrix4f& newCoordinate,
1086 localPose.block<3, 3>(0, 0) =
1087 globalTargetPose.block<3, 3>(0, 0) * newCoordinate.block<3, 3>(0, 0).inverse();
1088 localPose.block<3, 1>(0, 3) =
1089 localPose.block<3, 3>(0, 0) *
1090 (globalTargetPose.block<3, 1>(0, 3) - newCoordinate.block<3, 1>(0, 3));
1104 for (
auto& pair :
values)
1106 datafields[pair.first] =
new Variant(pair.second);
1110 for (
auto& pair : constrained_force)
1112 datafields[pair.first] =
new Variant(pair.second);
1116 datafields[
"leftTargetPose_x"] =
1118 datafields[
"leftTargetPose_y"] =
1120 datafields[
"leftTargetPose_z"] =
1122 datafields[
"rightTargetPose_x"] =
1124 datafields[
"rightTargetPose_y"] =
1126 datafields[
"rightTargetPose_z"] =
1130 datafields[
"leftCurrentPose_x"] =
1132 datafields[
"leftCurrentPose_y"] =
1134 datafields[
"leftCurrentPose_z"] =
1136 datafields[
"rightCurrentPose_x"] =
1138 datafields[
"rightCurrentPose_y"] =
1140 datafields[
"rightCurrentPose_z"] =
1174 debugObs->setDebugChannel(
"DMPController", datafields);
1188 controllerTask->stop();