1 #include <VirtualRobot/IK/DifferentialIK.h>
2 #include <VirtualRobot/Robot.h>
9 #include <RobotAPI/interface/units/RobotUnit/NJointTaskSpaceDMPController.h>
10 #include <RobotAPI/libraries/DMPController/TaskSpaceDMPController.h>
15 #include <dmp/representation/dmp/umitsmp.h>
19 NJointControllerRegistration<NJointBimanualCCDMPController>
23 armarx::NJointControllerDescriptionProviderInterfacePtr prov,
24 const armarx::NJointControllerConfigPtr& config,
28 cfg = NJointBimanualCCDMPControllerConfigPtr::dynamicCast(config);
30 RobotUnitPtr robotUnit = RobotUnitPtr::dynamicCast(prov);
33 leftRNS = robotUnit->getRtRobot()->getRobotNodeSet(
"LeftArm");
34 rnsLeftBody = robotUnit->getRtRobot()->getRobotNodeSet(
"LeftArmCol");
35 for (
size_t i = 0; i < leftRNS->getSize(); ++i)
37 std::string jointName = leftRNS->getNode(i)->getName();
39 leftJointNames.push_back(jointName);
40 ControlTargetBase* ct = prov->getControlTarget(jointName, ControlModes::Torque1DoF);
41 const SensorValueBase* sv = prov->getSensorValue(jointName);
42 leftTargets.push_back(ct->asA<ControlTarget1DoFActuatorTorque>());
43 const SensorValue1DoFActuatorVelocity* velocitySensor =
44 sv->asA<SensorValue1DoFActuatorVelocity>();
45 const SensorValue1DoFActuatorPosition* positionSensor =
46 sv->asA<SensorValue1DoFActuatorPosition>();
47 const SensorValue1DoFActuatorAcceleration* accelerationSensor =
48 sv->asA<SensorValue1DoFActuatorAcceleration>();
59 if (!accelerationSensor)
61 ARMARX_WARNING <<
"No accelerationSensor available for " << jointName;
65 leftVelocitySensors.push_back(velocitySensor);
66 leftPositionSensors.push_back(positionSensor);
67 leftAccelerationSensors.push_back(accelerationSensor);
71 rnsRightBody = robotUnit->getRtRobot()->getRobotNodeSet(
"RightArmCol");
73 rightRNS = robotUnit->getRtRobot()->getRobotNodeSet(
"RightArm");
74 for (
size_t i = 0; i < rightRNS->getSize(); ++i)
76 std::string jointName = rightRNS->getNode(i)->getName();
77 rightJointNames.push_back(jointName);
78 ControlTargetBase* ct = prov->getControlTarget(jointName, ControlModes::Torque1DoF);
79 const SensorValueBase* sv = prov->getSensorValue(jointName);
80 rightTargets.push_back(ct->asA<ControlTarget1DoFActuatorTorque>());
81 const SensorValue1DoFActuatorVelocity* velocitySensor =
82 sv->asA<SensorValue1DoFActuatorVelocity>();
83 const SensorValue1DoFActuatorPosition* positionSensor =
84 sv->asA<SensorValue1DoFActuatorPosition>();
85 const SensorValue1DoFActuatorAcceleration* accelerationSensor =
86 sv->asA<SensorValue1DoFActuatorAcceleration>();
97 if (!accelerationSensor)
99 ARMARX_WARNING <<
"No accelerationSensor available for " << jointName;
102 rightVelocitySensors.push_back(velocitySensor);
103 rightPositionSensors.push_back(positionSensor);
104 rightAccelerationSensors.push_back(accelerationSensor);
108 const SensorValueBase* svlf = prov->getSensorValue(
"FT L");
109 leftForceTorque = svlf->
asA<SensorValueForceTorque>();
110 const SensorValueBase* svrf = prov->getSensorValue(
"FT R");
111 rightForceTorque = svrf->
asA<SensorValueForceTorque>();
113 leftIK.reset(
new VirtualRobot::DifferentialIK(
114 leftRNS, leftRNS->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
115 rightIK.reset(
new VirtualRobot::DifferentialIK(rightRNS,
116 rightRNS->getRobot()->getRootNode(),
117 VirtualRobot::JacobiProvider::eSVDDamped));
120 TaskSpaceDMPControllerConfig taskSpaceDMPConfig;
121 taskSpaceDMPConfig.motionTimeDuration = cfg->timeDuration;
122 taskSpaceDMPConfig.DMPKernelSize = cfg->kernelSize;
123 taskSpaceDMPConfig.DMPMode = cfg->dmpMode;
124 taskSpaceDMPConfig.DMPStyle = cfg->dmpType;
125 taskSpaceDMPConfig.DMPAmplitude = 1.0;
126 taskSpaceDMPConfig.phaseStopParas.goDist = cfg->phaseDist0;
127 taskSpaceDMPConfig.phaseStopParas.backDist = cfg->phaseDist1;
128 taskSpaceDMPConfig.phaseStopParas.Kpos = cfg->phaseKpPos;
129 taskSpaceDMPConfig.phaseStopParas.Dpos = 0;
130 taskSpaceDMPConfig.phaseStopParas.Kori = cfg->phaseKpOri;
131 taskSpaceDMPConfig.phaseStopParas.Dori = 0;
132 taskSpaceDMPConfig.phaseStopParas.mm2radi = cfg->posToOriRatio;
133 taskSpaceDMPConfig.phaseStopParas.maxValue = cfg->phaseL;
134 taskSpaceDMPConfig.phaseStopParas.slop = cfg->phaseK;
138 new TaskSpaceDMPController(
"leftLeader", taskSpaceDMPConfig));
140 new TaskSpaceDMPController(
"leftFollower", taskSpaceDMPConfig));
142 new TaskSpaceDMPController(
"rightLeader", taskSpaceDMPConfig));
144 new TaskSpaceDMPController(
"rightFollower", taskSpaceDMPConfig));
146 leftGroup.push_back(leftLeader);
147 leftGroup.push_back(rightFollower);
149 rightGroup.push_back(rightLeader);
150 rightGroup.push_back(leftFollower);
152 bothLeaderGroup.push_back(leftLeader);
153 bothLeaderGroup.push_back(rightLeader);
156 tcpLeft = leftRNS->getTCP();
157 tcpRight = rightRNS->getTCP();
158 NJointBimanualCCDMPControllerSensorData initSensorData;
159 initSensorData.deltaT = 0;
160 initSensorData.currentTime = 0;
161 initSensorData.currentLeftPose = leftRNS->getTCP()->getPoseInRootFrame();
162 initSensorData.currentRightPose = rightRNS->getTCP()->getPoseInRootFrame();
167 NJointBimanualCCDMPControllerControlData initData;
168 initData.leftTargetVel.resize(6);
169 initData.leftTargetVel.setZero();
170 initData.rightTargetVel.resize(6);
171 initData.rightTargetVel.setZero();
174 leftDesiredJointValues.resize(leftTargets.size());
177 for (
size_t i = 0; i < leftTargets.size(); ++i)
179 leftDesiredJointValues(i) = cfg->leftDesiredJointValues.at(i);
182 rightDesiredJointValues.resize(rightTargets.size());
185 for (
size_t i = 0; i < rightTargets.size(); ++i)
187 rightDesiredJointValues(i) = cfg->rightDesiredJointValues.at(i);
190 KoriFollower = cfg->KoriFollower;
191 KposFollower = cfg->KposFollower;
193 kpos << cfg->Kpos[0], cfg->Kpos[1], cfg->Kpos[2];
194 dpos << cfg->Dpos[0], cfg->Dpos[1], cfg->Dpos[2];
195 kori << cfg->Kori[0], cfg->Kori[1], cfg->Kori[2];
196 dori << cfg->Dori[0], cfg->Dori[1], cfg->Dori[2];
202 torqueLimit = cfg->torqueLimit;
206 forceC_des.resize(12);
213 for (
size_t i = 0; i < 12; i++)
215 kpf(i) = cfg->Kpf.at(i);
216 kif(i) = cfg->Kif.at(i);
217 forceC_des(i) = cfg->DesiredForce.at(i);
220 boxWidth = cfg->BoxWidth;
222 filtered_leftForce.setZero();
223 filtered_leftTorque.setZero();
224 filtered_rightForce.setZero();
225 filtered_rightTorque.setZero();
232 offset_leftForce(0) = -4.34;
233 offset_leftForce(1) = -8.21;
234 offset_leftForce(2) = 15.59;
236 offset_leftTorque(0) = 1.42;
237 offset_leftTorque(1) = 0.29;
238 offset_leftTorque(2) = 0.09;
240 offset_rightForce(0) = 2.88;
241 offset_rightForce(1) = 11.15;
242 offset_rightForce(2) = -20.18;
244 offset_rightTorque(0) = -1.83;
245 offset_rightTorque(1) = 0.34;
246 offset_rightTorque(2) = -0.01;
249 filterTimeConstant = cfg->FilterTimeConstant;
251 ftPIDController.resize(12);
252 for (
size_t i = 0; i < ftPIDController.size(); i++)
254 ftPIDController[i].reset(
new PIDController(kpf(i), kif(i), 0.0, 10, 10));
257 isForceCompensateDone =
false;
263 return "NJointBimanualCCDMPController";
277 Eigen::VectorXf leftTargetVel;
278 leftTargetVel.resize(6);
279 leftTargetVel.setZero();
280 Eigen::VectorXf rightTargetVel;
281 rightTargetVel.resize(6);
282 rightTargetVel.setZero();
284 std::vector<TaskSpaceDMPControllerPtr> currentControlGroup;
287 Eigen::VectorXf currentLeaderTwist;
288 Eigen::VectorXf currentFollowerTwist;
289 if (leaderName ==
"Left")
291 currentControlGroup = leftGroup;
292 currentLeaderPose = controllerSensorData.
getReadBuffer().currentLeftPose;
293 currentFollowerPose = controllerSensorData.
getReadBuffer().currentRightPose;
294 currentLeaderTwist = controllerSensorData.
getReadBuffer().currentLeftTwist;
295 currentFollowerTwist = controllerSensorData.
getReadBuffer().currentRightTwist;
297 else if (leaderName ==
"right")
299 currentControlGroup = rightGroup;
300 currentLeaderPose = controllerSensorData.
getReadBuffer().currentRightPose;
301 currentFollowerPose = controllerSensorData.
getReadBuffer().currentLeftPose;
302 currentLeaderTwist = controllerSensorData.
getReadBuffer().currentRightTwist;
303 currentFollowerTwist = controllerSensorData.
getReadBuffer().currentLeftTwist;
307 currentControlGroup = bothLeaderGroup;
311 leaderDMPleft->flow(deltaT,
314 leaderDMPright->flow(deltaT,
318 Eigen::VectorXf leftTargetVel = leaderDMPleft->getTargetVelocity();
320 Eigen::VectorXf rightTargetVel = leaderDMPright->getTargetVelocity();
323 virtualtimer = leaderDMPleft->canVal;
338 leaderDMP->flow(deltaT, currentLeaderPose, currentLeaderTwist);
341 currentFollowerLocalPose.block<3, 3>(0, 0) =
342 currentFollowerPose.block<3, 3>(0, 0) * currentLeaderPose.block<3, 3>(0, 0).inverse();
343 currentFollowerLocalPose.block<3, 1>(0, 3) =
344 currentFollowerLocalPose.block<3, 3>(0, 0) *
345 (currentFollowerPose.block<3, 1>(0, 3) - currentLeaderPose.block<3, 1>(0, 3));
346 followerDMP->flow(deltaT, currentFollowerPose, currentFollowerTwist);
348 Eigen::VectorXf leaderTargetVel = leaderDMP->getTargetVelocity();
350 Eigen::Matrix4f followerLocalTargetPose = followerDMP->getTargetPoseMat();
351 std::vector<double> followerLocalTargetPoseVec = followerDMP->getTargetPose();
354 followerTargetPose.block<3, 3>(0, 0) =
355 followerLocalTargetPose.block<3, 3>(0, 0) * currentLeaderPose.block<3, 3>(0, 0);
356 followerTargetPose.block<3, 1>(0, 3) =
357 currentLeaderPose.block<3, 3>(0, 0) * followerLocalTargetPose.block<3, 1>(0, 3) +
358 currentLeaderPose.block<3, 1>(0, 3);
361 Eigen::VectorXf followerLocalTargetVel = followerDMP->getTargetVelocity();
362 Eigen::VectorXf followerTargetVel = followerLocalTargetVel;
364 followerTargetVel.block<3, 1>(0, 0) =
366 (followerTargetPose.block<3, 1>(0, 3) - currentFollowerPose.block<3, 1>(0, 3));
370 followerTargetPose.block<3, 3>(0, 0) * currentFollowerPose.block<3, 3>(0, 0).inverse();
371 Eigen::Vector3f followerDiffRPY =
372 KoriFollower * VirtualRobot::MathTools::eigen3f2rpy(followerDiffMat);
373 followerTargetVel(3) = followerDiffRPY(0);
374 followerTargetVel(4) = followerDiffRPY(1);
375 followerTargetVel(5) = followerDiffRPY(2);
377 virtualtimer = leaderDMP->canVal;
380 std::vector<double> leftDMPTarget;
381 std::vector<double> rightDMPTarget;
386 if (leaderName ==
"Left")
388 leftTargetVel = leaderTargetVel;
389 rightTargetVel = followerTargetVel;
391 leftDMPTarget = leaderDMP->getTargetPose();
392 rightDMPTarget = followerLocalTargetPoseVec;
395 leftTargetPose = leaderTargetPose;
396 rightTargetPose = followerLocalTargetPose;
398 else if (leaderName ==
"right")
400 rightTargetVel = leaderTargetVel;
401 leftTargetVel = followerTargetVel;
403 rightDMPTarget = leaderDMP->getTargetPose();
404 leftDMPTarget = followerLocalTargetPoseVec;
406 rightTargetPose = leaderTargetPose;
407 leftTargetPose = followerLocalTargetPose;
487 NJointBimanualCCDMPController::getControlWrench(
const Eigen::VectorXf& tcptwist,
516 double deltaT = timeSinceLastIteration.toSecondsDouble();
517 controllerSensorData.
getWriteBuffer().currentLeftPose = tcpLeft->getPoseInRootFrame();
518 controllerSensorData.
getWriteBuffer().currentRightPose = tcpRight->getPoseInRootFrame();
557 Eigen::MatrixXf jacobiL =
558 leftIK->getJacobianMatrix(tcpLeft, VirtualRobot::IKSolver::CartesianSelection::All);
559 jacobiL.block<3, 8>(0, 0) = 0.001 * jacobiL.block<3, 8>(0, 0);
561 Eigen::VectorXf leftqpos;
562 Eigen::VectorXf leftqvel;
563 leftqpos.resize(leftPositionSensors.size());
564 leftqvel.resize(leftVelocitySensors.size());
565 for (
size_t i = 0; i < leftVelocitySensors.size(); ++i)
567 leftqpos(i) = leftPositionSensors[i]->position;
568 leftqvel(i) = leftVelocitySensors[i]->velocity;
571 Eigen::MatrixXf jacobiR =
572 rightIK->getJacobianMatrix(tcpRight, VirtualRobot::IKSolver::CartesianSelection::All);
573 jacobiR.block<3, 8>(0, 0) = 0.001 * jacobiR.block<3, 8>(0, 0);
576 Eigen::VectorXf rightqpos;
577 Eigen::VectorXf rightqvel;
578 rightqpos.resize(rightPositionSensors.size());
579 rightqvel.resize(rightVelocitySensors.size());
581 for (
size_t i = 0; i < rightVelocitySensors.size(); ++i)
583 rightqpos(i) = rightPositionSensors[i]->position;
584 rightqvel(i) = rightVelocitySensors[i]->velocity;
587 Eigen::VectorXf currentLeftTwist = jacobiL * leftqvel;
588 Eigen::VectorXf currentRightTwist = jacobiR * rightqvel;
591 controllerSensorData.
getWriteBuffer().currentLeftTwist = currentLeftTwist;
592 controllerSensorData.
getWriteBuffer().currentRightTwist = currentRightTwist;
604 int nl = leftRNS->getSize();
605 int nr = rightRNS->getSize();
615 Eigen::Vector3f localDistanceCoM;
616 localDistanceCoM << 0.5 * boxWidth, 0, 0;
620 -leftCurrentPose.block<3, 3>(0, 0) *
622 Eigen::Vector3f rr = rightCurrentPose.block<3, 3>(0, 0) * localDistanceCoM;
625 leftGraspMatrix.block<3, 3>(3, 0) << 0, -rl(2), rl(1), rl(2), 0, -rl(0), -rl(1), rl(0), 0;
626 rightGraspMatrix.block<3, 3>(3, 0) << 0, -rr(2), rr(1), rr(2), 0, -rr(0), -rr(1), rr(0), 0;
627 Eigen::MatrixXf graspMatrix;
628 graspMatrix.resize(6, 12);
629 graspMatrix << leftGraspMatrix, rightGraspMatrix;
632 Eigen::MatrixXf jacobi;
633 jacobi.resize(12, n);
634 jacobi.setZero(12, n);
635 jacobi.block<6, 8>(0, 0) = jacobiL;
636 jacobi.block<6, 8>(6, 8) = jacobiR;
638 Eigen::MatrixXf pinvGraspMatrix =
639 leftIK->computePseudoInverseJacobianMatrix(graspMatrix, 1);
640 Eigen::MatrixXf proj2GraspNullspace =
642 Eigen::MatrixXf jacobiConstrained = proj2GraspNullspace * jacobi;
644 Eigen::MatrixXf pinvJacobiC =
645 leftIK->computePseudoInverseJacobianMatrix(jacobiConstrained, 1);
646 Eigen::MatrixXf projection =
651 Eigen::MatrixXf leftInertialMatrix;
652 Eigen::MatrixXf rightInertialMatrix;
653 leftInertialMatrix.setZero(nl, nl);
654 rightInertialMatrix.setZero(nr, nr);
656 for (
size_t i = 0; i < rnsLeftBody->getNodeNames().size(); ++i)
658 VirtualRobot::RobotNodePtr rnbody = rnsLeftBody->getNode(i);
659 VirtualRobot::RobotNodePtr rnjoint = leftRNS->getNode(i + 1);
661 Eigen::MatrixXf jacobipos_rn =
662 0.001 * leftIK->getJacobianMatrix(
664 Eigen::MatrixXf jacobiori_rn = leftIK->getJacobianMatrix(
668 float m = rnbody->getMass();
670 leftInertialMatrix += m * jacobipos_rn.transpose() * jacobipos_rn +
671 jacobiori_rn.transpose() * InertiaMatrix * jacobiori_rn;
674 for (
size_t i = 0; i < rnsRightBody->getNodeNames().size(); ++i)
676 VirtualRobot::RobotNodePtr rnbody = rnsRightBody->getNode(i);
677 VirtualRobot::RobotNodePtr rnjoint = rightRNS->getNode(i + 1);
679 Eigen::MatrixXf jacobipos_rn =
680 0.001 * rightIK->getJacobianMatrix(
682 Eigen::MatrixXf jacobiori_rn = rightIK->getJacobianMatrix(
686 float m = rnbody->getMass();
689 rightInertialMatrix += m * jacobipos_rn.transpose() * jacobipos_rn +
690 jacobiori_rn.transpose() * InertiaMatrix * jacobiori_rn;
692 Eigen::MatrixXf M = Eigen::MatrixXf::Zero(n, n);
693 M.topLeftCorner(nl, nl) = leftInertialMatrix;
694 M.bottomRightCorner(nr, nr) = rightInertialMatrix;
696 Eigen::MatrixXf Mc = M + projection * M - M * projection;
700 double filterFactor = 1 / ((filterTimeConstant / deltaT) + 1);
702 filtered_leftForce = (1 - filterFactor) * filtered_leftForce +
703 filterFactor * (leftForceTorque->
force - offset_leftForce);
704 filtered_leftTorque = (1 - filterFactor) * filtered_leftTorque +
705 filterFactor * (leftForceTorque->
torque - offset_leftTorque);
706 filtered_rightForce = (1 - filterFactor) * filtered_rightForce +
707 filterFactor * (rightForceTorque->
force - offset_rightForce);
708 filtered_rightTorque = (1 - filterFactor) * filtered_rightForce +
709 filterFactor * (rightForceTorque->
torque - offset_rightTorque);
711 Eigen::VectorXf filteredForce;
712 filteredForce.resize(12);
713 filteredForce << filtered_leftForce, filtered_leftTorque, filtered_rightForce,
714 filtered_rightTorque;
715 filteredForce.block<3, 1>(0, 0) =
716 leftCurrentPose.block<3, 3>(0, 0) * filteredForce.block<3, 1>(0, 0);
717 filteredForce.block<3, 1>(3, 0) =
718 leftCurrentPose.block<3, 3>(0, 0) * filteredForce.block<3, 1>(3, 0);
719 filteredForce.block<3, 1>(6, 0) =
720 rightCurrentPose.block<3, 3>(0, 0) * filteredForce.block<3, 1>(6, 0);
721 filteredForce.block<3, 1>(9, 0) =
722 rightCurrentPose.block<3, 3>(0, 0) * filteredForce.block<3, 1>(9, 0);
726 Eigen::VectorXf constrainedForceMeasure = proj2GraspNullspace * filteredForce;
728 constrainedForceMeasure.block<3, 1>(0, 0) = leftCurrentPose.block<3, 3>(0, 0).transpose() *
729 constrainedForceMeasure.block<3, 1>(0, 0);
730 constrainedForceMeasure.block<3, 1>(3, 0) = leftCurrentPose.block<3, 3>(0, 0).transpose() *
731 constrainedForceMeasure.block<3, 1>(3, 0);
732 constrainedForceMeasure.block<3, 1>(6, 0) = rightCurrentPose.block<3, 3>(0, 0).transpose() *
733 constrainedForceMeasure.block<3, 1>(6, 0);
734 constrainedForceMeasure.block<3, 1>(9, 0) = rightCurrentPose.block<3, 3>(0, 0).transpose() *
735 constrainedForceMeasure.block<3, 1>(9, 0);
736 Eigen::VectorXf forceConstrained = Eigen::VectorXf::Zero(12);
737 for (
size_t i = 0; i < 12; i++)
739 ftPIDController[i]->update(constrainedForceMeasure(i), forceC_des(i));
740 forceConstrained(i) = ftPIDController[i]->getControlValue() + forceC_des(i);
746 forceConstrained.block<3, 1>(0, 0) =
747 leftCurrentPose.block<3, 3>(0, 0) * forceConstrained.block<3, 1>(0, 0);
748 forceConstrained.block<3, 1>(3, 0) =
749 leftCurrentPose.block<3, 3>(0, 0) * forceConstrained.block<3, 1>(3, 0);
750 forceConstrained.block<3, 1>(6, 0) =
751 rightCurrentPose.block<3, 3>(0, 0) * forceConstrained.block<3, 1>(6, 0);
752 forceConstrained.block<3, 1>(9, 0) =
753 rightCurrentPose.block<3, 3>(0, 0) * forceConstrained.block<3, 1>(9, 0);
759 Eigen::Vector3f targetTCPLinearVelocity;
760 targetTCPLinearVelocity << 0.001 * leftTargetVel(0), 0.001 * leftTargetVel(1),
761 0.001 * leftTargetVel(2);
763 Eigen::Vector3f currentTCPLinearVelocity;
764 currentTCPLinearVelocity << currentLeftTwist(0), currentLeftTwist(1),
766 Eigen::Vector3f currentTCPAngularVelocity;
767 currentTCPAngularVelocity << currentLeftTwist(3), currentLeftTwist(4),
769 Eigen::Vector3f currentTCPPosition = leftCurrentPose.block<3, 1>(0, 3);
770 Eigen::Vector3f desiredPosition = leftTargetPose.block<3, 1>(0, 3);
772 Eigen::Vector3f tcpDesiredForce =
773 0.001 * kpos.cwiseProduct(desiredPosition - currentTCPPosition) +
774 dpos.cwiseProduct(targetTCPLinearVelocity - currentTCPLinearVelocity);
776 Eigen::Matrix3f diffMat = leftTargetPose.block<3, 3>(0, 0) * currentRotMat.inverse();
777 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
778 Eigen::Vector3f tcpDesiredTorque =
779 kori.cwiseProduct(rpy) - dori.cwiseProduct(currentTCPAngularVelocity);
780 leftJointControlWrench << tcpDesiredForce, tcpDesiredTorque;
786 Eigen::Vector3f targetTCPLinearVelocity;
787 targetTCPLinearVelocity << 0.001 * rightTargetVel(0), 0.001 * rightTargetVel(1),
788 0.001 * rightTargetVel(2);
790 Eigen::Vector3f currentTCPLinearVelocity;
791 currentTCPLinearVelocity << currentRightTwist(0), currentRightTwist(1),
792 currentRightTwist(2);
793 Eigen::Vector3f currentTCPAngularVelocity;
794 currentTCPAngularVelocity << currentRightTwist(3), currentRightTwist(4),
795 currentRightTwist(5);
796 Eigen::Vector3f currentTCPPosition = rightCurrentPose.block<3, 1>(0, 3);
797 Eigen::Vector3f desiredPosition = rightTargetPose.block<3, 1>(0, 3);
799 Eigen::Vector3f tcpDesiredForce =
800 0.001 * kpos.cwiseProduct(desiredPosition - currentTCPPosition) -
801 dpos.cwiseProduct(targetTCPLinearVelocity - currentTCPLinearVelocity);
803 Eigen::Matrix3f diffMat = rightTargetPose.block<3, 3>(0, 0) * currentRotMat.inverse();
804 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
805 Eigen::Vector3f tcpDesiredTorque =
806 kori.cwiseProduct(rpy) - dori.cwiseProduct(currentTCPAngularVelocity);
807 rightJointControlWrench << tcpDesiredForce, tcpDesiredTorque;
810 Eigen::VectorXf forceUnconstrained(12);
811 forceUnconstrained << leftJointControlWrench, rightJointControlWrench;
813 Eigen::VectorXf unConstrainedForceMeasure = pinvGraspMatrix * graspMatrix * filteredForce;
815 Eigen::MatrixXf taskSpaceInertia = (jacobi * M.inverse() * jacobi.transpose()).inverse();
822 Eigen::VectorXf leftNullspaceTorque =
823 knull * (leftDesiredJointValues - leftqpos) - dnull * leftqvel;
824 Eigen::VectorXf rightNullspaceTorque =
825 knull * (rightDesiredJointValues - rightqpos) - dnull * rightqvel;
828 Eigen::MatrixXf jtpinvL =
829 leftIK->computePseudoInverseJacobianMatrix(jacobiL.transpose(), lambda);
830 Eigen::MatrixXf jtpinvR =
831 leftIK->computePseudoInverseJacobianMatrix(jacobiR.transpose(), lambda);
832 forceUnconstrained.head<8>()) =
833 forceUnconstrained.head<8>()) + (I - jacobiL.transpose() * jtpinvL) * leftNullspaceTorque;
834 forceUnconstrained.tail<8>() = forceUnconstrained.tail<8>() +
835 (I - jacobiR.transpose() * jtpinvR) * rightNullspaceTorque;
874 Eigen::VectorXf torqueInput = jacobi.transpose() * (forceUnconstrained + forceConstrained);
876 Eigen::VectorXf leftJointDesiredTorques = torqueInput.head(nl);
877 Eigen::VectorXf rightJointDesiredTorques = torqueInput.block<8, 1>(8, 0);
880 for (
size_t i = 0; i < leftTargets.size(); ++i)
882 float desiredTorque = leftJointDesiredTorques(i);
884 if (isnan(desiredTorque))
889 desiredTorque = (desiredTorque > torqueLimit) ? torqueLimit : desiredTorque;
890 desiredTorque = (desiredTorque < -torqueLimit) ? -torqueLimit : desiredTorque;
892 debugDataInfo.
getWriteBuffer().desired_torques[leftJointNames[i]] =
893 leftJointDesiredTorques(i);
895 leftTargets.at(i)->torque = desiredTorque;
899 for (
size_t i = 0; i < rightTargets.size(); ++i)
901 float desiredTorque = rightJointDesiredTorques(i);
903 if (isnan(desiredTorque))
908 desiredTorque = (desiredTorque > torqueLimit) ? torqueLimit : desiredTorque;
909 desiredTorque = (desiredTorque < -torqueLimit) ? -torqueLimit : desiredTorque;
911 debugDataInfo.
getWriteBuffer().desired_torques[rightJointNames[i]] =
912 rightJointDesiredTorques(i);
914 rightTargets.at(i)->torque = desiredTorque;
925 debugDataInfo.
getWriteBuffer().leftTargetPose_x = leftTargetPose(0, 3);
926 debugDataInfo.
getWriteBuffer().leftTargetPose_y = leftTargetPose(1, 3);
927 debugDataInfo.
getWriteBuffer().leftTargetPose_z = leftTargetPose(2, 3);
928 debugDataInfo.
getWriteBuffer().leftCurrentPose_x = leftCurrentPose(0, 3);
929 debugDataInfo.
getWriteBuffer().leftCurrentPose_y = leftCurrentPose(1, 3);
930 debugDataInfo.
getWriteBuffer().leftCurrentPose_z = leftCurrentPose(2, 3);
933 debugDataInfo.
getWriteBuffer().rightTargetPose_x = rightTargetPose(0, 3);
934 debugDataInfo.
getWriteBuffer().rightTargetPose_y = rightTargetPose(1, 3);
935 debugDataInfo.
getWriteBuffer().rightTargetPose_z = rightTargetPose(2, 3);
937 debugDataInfo.
getWriteBuffer().rightCurrentPose_x = rightCurrentPose(0, 3);
938 debugDataInfo.
getWriteBuffer().rightCurrentPose_y = rightCurrentPose(1, 3);
939 debugDataInfo.
getWriteBuffer().rightCurrentPose_z = rightCurrentPose(2, 3);
942 for (
size_t i = 0; i < 12; ++i)
944 std::stringstream ss;
946 std::string name =
"forceConstrained_" + ss.str();
947 debugDataInfo.
getWriteBuffer().constrained_force[name] = filteredForce(i);
998 const Ice::StringSeq& fileNames,
1001 if (name ==
"LeftLeader")
1003 leftGroup.at(0)->learnDMPFromFiles(fileNames);
1005 else if (name ==
"LeftFollower")
1007 rightGroup.at(1)->learnDMPFromFiles(fileNames);
1009 else if (name ==
"RightLeader")
1011 rightGroup.at(0)->learnDMPFromFiles(fileNames);
1015 leftGroup.at(1)->learnDMPFromFiles(fileNames);
1021 const Ice::DoubleSeq& viapoint,
1022 const Ice::Current&)
1025 if (leaderName ==
"Left")
1027 leftGroup.at(0)->setViaPose(u, viapoint);
1031 rightGroup.at(0)->setViaPose(u, viapoint);
1039 if (leaderName ==
"Left")
1041 leftGroup.at(0)->setGoalPoseVec(goals);
1045 rightGroup.at(0)->setGoalPoseVec(goals);
1054 if (leaderName ==
"Left")
1056 leaderName =
"Right";
1057 rightGroup.at(0)->canVal = virtualtimer;
1058 rightGroup.at(1)->canVal = virtualtimer;
1062 leaderName =
"Left";
1063 leftGroup.at(0)->canVal = virtualtimer;
1064 leftGroup.at(1)->canVal = virtualtimer;
1070 const Ice::DoubleSeq& rightGoals,
1071 const Ice::Current&)
1073 virtualtimer = cfg->timeDuration;
1078 leftGroup.at(0)->prepareExecution(leftGroup.at(0)->eigen4f2vec(leftPose), leftGoals);
1079 rightGroup.at(0)->prepareExecution(rightGroup.at(0)->eigen4f2vec(rightPose), rightGoals);
1082 ARMARX_INFO <<
"leftgroup goal local pose: " << getLocalPose(leftGoals, rightGoals);
1084 leftGroup.at(1)->prepareExecution(getLocalPose(leftPose, rightPose),
1085 getLocalPose(leftGoals, rightGoals));
1086 rightGroup.at(1)->prepareExecution(getLocalPose(rightPose, leftPose),
1087 getLocalPose(rightGoals, leftGoals));
1089 controllerTask->start();
1093 NJointBimanualCCDMPController::getLocalPose(
const Eigen::Matrix4f& newCoordinate,
1097 localPose.block<3, 3>(0, 0) =
1098 globalTargetPose.block<3, 3>(0, 0) * newCoordinate.block<3, 3>(0, 0).inverse();
1099 localPose.block<3, 1>(0, 3) =
1100 localPose.block<3, 3>(0, 0) *
1101 (globalTargetPose.block<3, 1>(0, 3) - newCoordinate.block<3, 1>(0, 3));
1114 for (
auto& pair :
values)
1116 datafields[pair.first] =
new Variant(pair.second);
1120 for (
auto& pair : constrained_force)
1122 datafields[pair.first] =
new Variant(pair.second);
1126 datafields[
"leftTargetPose_x"] =
1128 datafields[
"leftTargetPose_y"] =
1130 datafields[
"leftTargetPose_z"] =
1132 datafields[
"rightTargetPose_x"] =
1134 datafields[
"rightTargetPose_y"] =
1136 datafields[
"rightTargetPose_z"] =
1140 datafields[
"leftCurrentPose_x"] =
1142 datafields[
"leftCurrentPose_y"] =
1144 datafields[
"leftCurrentPose_z"] =
1146 datafields[
"rightCurrentPose_x"] =
1148 datafields[
"rightCurrentPose_y"] =
1150 datafields[
"rightCurrentPose_z"] =
1184 debugObs->setDebugChannel(
"DMPController", datafields);
1198 controllerTask->stop();