10 cfg = NJointBimanualCCDMPControllerConfigPtr::dynamicCast(config);
15 leftRNS =
rtGetRobot()->getRobotNodeSet(
"LeftArm");
16 leftNullSpaceCoefs.resize(leftRNS->getSize());
17 leftNullSpaceCoefs.setOnes();
19 for (
size_t i = 0; i < leftRNS->getSize(); ++i)
21 std::string jointName = leftRNS->getNode(i)->getName();
23 if (leftRNS->getNode(i)->isLimitless())
25 leftNullSpaceCoefs(i) = 1;
28 leftJointNames.push_back(jointName);
29 ControlTargetBase* ct =
useControlTarget(jointName, ControlModes::Torque1DoF);
31 leftTargets.push_back(ct->asA<ControlTarget1DoFActuatorTorque>());
32 const SensorValue1DoFActuatorVelocity* velocitySensor = sv->asA<SensorValue1DoFActuatorVelocity>();
33 const SensorValue1DoFActuatorPosition* positionSensor = sv->asA<SensorValue1DoFActuatorPosition>();
34 const SensorValue1DoFActuatorAcceleration* accelerationSensor = 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);
56 rightRNS =
rtGetRobot()->getRobotNodeSet(
"RightArm");
58 rightNullSpaceCoefs.resize(rightRNS->getSize());
59 rightNullSpaceCoefs.setOnes();
60 for (
size_t i = 0; i < rightRNS->getSize(); ++i)
62 std::string jointName = rightRNS->getNode(i)->getName();
64 if (rightRNS->getNode(i)->isLimitless())
66 rightNullSpaceCoefs(i) = 1;
69 rightJointNames.push_back(jointName);
70 ControlTargetBase* ct =
useControlTarget(jointName, ControlModes::Torque1DoF);
72 rightTargets.push_back(ct->asA<ControlTarget1DoFActuatorTorque>());
73 const SensorValue1DoFActuatorVelocity* velocitySensor = sv->asA<SensorValue1DoFActuatorVelocity>();
74 const SensorValue1DoFActuatorPosition* positionSensor = sv->asA<SensorValue1DoFActuatorPosition>();
75 const SensorValue1DoFActuatorAcceleration* accelerationSensor = sv->asA<SensorValue1DoFActuatorAcceleration>();
86 if (!accelerationSensor)
88 ARMARX_WARNING <<
"No accelerationSensor available for " << jointName;
91 rightVelocitySensors.push_back(velocitySensor);
92 rightPositionSensors.push_back(positionSensor);
93 rightAccelerationSensors.push_back(accelerationSensor);
99 leftForceTorque = svlf->
asA<SensorValueForceTorque>();
101 rightForceTorque = svrf->
asA<SensorValueForceTorque>();
103 leftIK.reset(
new VirtualRobot::DifferentialIK(leftRNS,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
104 rightIK.reset(
new VirtualRobot::DifferentialIK(rightRNS,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
110 taskSpaceDMPConfig.
DMPMode = cfg->dmpMode;
111 taskSpaceDMPConfig.
DMPStyle = cfg->dmpType;
129 leftGroup.push_back(leftLeader);
130 leftGroup.push_back(rightFollower);
132 rightGroup.push_back(rightLeader);
133 rightGroup.push_back(leftFollower);
135 bothLeaderGroup.push_back(leftLeader);
136 bothLeaderGroup.push_back(rightLeader);
139 tcpLeft = leftRNS->getTCP();
140 tcpRight = rightRNS->getTCP();
143 leaderName = cfg->defautLeader;
146 leftDesiredJointValues.resize(leftTargets.size());
149 for (
size_t i = 0; i < leftTargets.size(); ++i)
151 leftDesiredJointValues(i) = cfg->leftDesiredJointValues.at(i);
154 rightDesiredJointValues.resize(rightTargets.size());
157 for (
size_t i = 0; i < rightTargets.size(); ++i)
159 rightDesiredJointValues(i) = cfg->rightDesiredJointValues.at(i);
163 leftKpos << cfg->leftKpos[0], cfg->leftKpos[1], cfg->leftKpos[2];
164 leftDpos << cfg->leftDpos[0], cfg->leftDpos[1], cfg->leftDpos[2];
165 leftKori << cfg->leftKori[0], cfg->leftKori[1], cfg->leftKori[2];
166 leftDori << cfg->leftDori[0], cfg->leftDori[1], cfg->leftDori[2];
168 rightKpos << cfg->rightKpos[0], cfg->rightKpos[1], cfg->rightKpos[2];
169 rightDpos << cfg->rightDpos[0], cfg->rightDpos[1], cfg->rightDpos[2];
170 rightKori << cfg->rightKori[0], cfg->rightKori[1], cfg->rightKori[2];
171 rightDori << cfg->rightDori[0], cfg->rightDori[1], cfg->rightDori[2];
177 torqueLimit = cfg->torqueLimit;
180 maxLinearVel = cfg->maxLinearVel;
181 maxAngularVel = cfg->maxAngularVel;
184 startReduceTorque = cfg->startReduceTorque;
186 NJointBimanualCCDMPControllerInterfaceData initInterfaceData;
191 NJointBimanualCCDMPControllerSensorData initSensorData;
192 initSensorData.deltaT = 0;
193 initSensorData.currentTime = 0;
202 return "NJointBimanualCCDMPController";
229 Eigen::VectorXf leftTargetVel;
230 leftTargetVel.resize(6);
231 leftTargetVel.setZero();
232 Eigen::VectorXf rightTargetVel;
233 rightTargetVel.resize(6);
234 rightTargetVel.setZero();
236 std::vector<tsvmp::TaskSpaceDMPControllerPtr > currentControlGroup;
239 Eigen::VectorXf currentLeaderTwist;
240 Eigen::VectorXf currentFollowerTwist;
241 if (leaderName ==
"Left")
243 currentControlGroup = leftGroup;
244 currentLeaderPose = controllerSensorData.
getReadBuffer().currentLeftPose;
245 currentFollowerPose = controllerSensorData.
getReadBuffer().currentRightPose;
246 currentLeaderTwist = controllerSensorData.
getReadBuffer().currentLeftTwist;
247 currentFollowerTwist = controllerSensorData.
getReadBuffer().currentRightTwist;
249 else if (leaderName ==
"right")
251 currentControlGroup = rightGroup;
252 currentLeaderPose = controllerSensorData.
getReadBuffer().currentRightPose;
253 currentFollowerPose = controllerSensorData.
getReadBuffer().currentLeftPose;
254 currentLeaderTwist = controllerSensorData.
getReadBuffer().currentRightTwist;
255 currentFollowerTwist = controllerSensorData.
getReadBuffer().currentLeftTwist;
259 currentControlGroup = bothLeaderGroup;
263 leaderDMPleft->flow(deltaT, controllerSensorData.
getReadBuffer().currentLeftPose, controllerSensorData.
getReadBuffer().currentLeftTwist);
264 leaderDMPright->flow(deltaT, controllerSensorData.
getReadBuffer().currentRightPose, controllerSensorData.
getReadBuffer().currentRightTwist);
266 Eigen::VectorXf leftTargetVel = leaderDMPleft->getTargetVelocity();
268 Eigen::VectorXf rightTargetVel = leaderDMPright->getTargetVelocity();
271 virtualtimer = leaderDMPleft->canVal;
284 virtualtimer = leaderDMP->canVal;
286 if (virtualtimer < 1e-8)
292 leaderDMP->flow(deltaT, currentLeaderPose, currentLeaderTwist);
295 currentFollowerLocalPose.block<3, 3>(0, 0) = currentLeaderPose.block<3, 3>(0, 0).inverse() * currentFollowerPose.block<3, 3>(0, 0);
296 currentFollowerLocalPose.block<3, 1>(0, 3) = currentLeaderPose.block<3, 3>(0, 0).inverse() * (currentFollowerPose.block<3, 1>(0, 3) - currentLeaderPose.block<3, 1>(0, 3));
297 followerDMP->flow(deltaT, currentFollowerLocalPose, currentFollowerTwist);
299 Eigen::VectorXf leaderTargetVel = leaderDMP->getTargetVelocity();
301 Eigen::Matrix4f followerLocalTargetPose = followerDMP->getTargetPoseMat();
302 std::vector<double> followerLocalTargetPoseVec = followerDMP->getTargetPose();
305 followerTargetPose.block<3, 3>(0, 0) = currentLeaderPose.block<3, 3>(0, 0) * followerLocalTargetPose.block<3, 3>(0, 0);
306 followerTargetPose.block<3, 1>(0, 3) = currentLeaderPose.block<3, 3>(0, 0) * followerLocalTargetPose.block<3, 1>(0, 3) + currentLeaderPose.block<3, 1>(0, 3);
309 Eigen::VectorXf followerLocalTargetVel = followerDMP->getTargetVelocity();
310 Eigen::VectorXf followerTargetVel = followerLocalTargetVel;
311 followerTargetVel.setZero();
325 std::vector<double> leftDMPTarget;
326 std::vector<double> rightDMPTarget;
334 if (leaderName ==
"Left")
336 leftTargetVel = leaderTargetVel;
337 rightTargetVel = followerTargetVel;
339 leftDMPTarget = leaderDMP->getTargetPose();
340 rightDMPTarget = followerLocalTargetPoseVec;
343 leftTargetPose = leaderTargetPose;
344 rightTargetPose = followerTargetPose;
348 else if (leaderName ==
"right")
350 rightTargetVel = leaderTargetVel;
351 leftTargetVel = followerTargetVel;
353 rightDMPTarget = leaderDMP->getTargetPose();
354 leftDMPTarget = followerLocalTargetPoseVec;
356 rightTargetPose = leaderTargetPose;
357 leftTargetPose = followerTargetPose;
371 Eigen::VectorXf NJointBimanualCCDMPController::getControlWrench(
const Eigen::VectorXf& tcptwist,
const Eigen::Matrix4f& currentPose,
const Eigen::Matrix4f& targetPose)
392 return Eigen::Vector6f::Zero();
399 double deltaT = timeSinceLastIteration.toSecondsDouble();
403 interfaceData.
getWriteBuffer().currentLeftPose = tcpLeft->getPoseInRootFrame();
404 interfaceData.
getWriteBuffer().currentRightPose = tcpRight->getPoseInRootFrame();
407 controllerSensorData.
getWriteBuffer().currentLeftPose = tcpLeft->getPoseInRootFrame();
408 controllerSensorData.
getWriteBuffer().currentRightPose = tcpRight->getPoseInRootFrame();
415 Eigen::MatrixXf jacobiL = leftIK->getJacobianMatrix(tcpLeft, VirtualRobot::IKSolver::CartesianSelection::All);
417 Eigen::VectorXf leftqpos;
418 Eigen::VectorXf leftqvel;
419 leftqpos.resize(leftPositionSensors.size());
420 leftqvel.resize(leftVelocitySensors.size());
421 for (
size_t i = 0; i < leftVelocitySensors.size(); ++i)
423 leftqpos(i) = leftPositionSensors[i]->position;
424 leftqvel(i) = leftVelocitySensors[i]->velocity;
427 Eigen::MatrixXf jacobiR = rightIK->getJacobianMatrix(tcpRight, VirtualRobot::IKSolver::CartesianSelection::All);
430 Eigen::VectorXf rightqpos;
431 Eigen::VectorXf rightqvel;
432 rightqpos.resize(rightPositionSensors.size());
433 rightqvel.resize(rightVelocitySensors.size());
435 for (
size_t i = 0; i < rightVelocitySensors.size(); ++i)
437 rightqpos(i) = rightPositionSensors[i]->position;
438 rightqvel(i) = rightVelocitySensors[i]->velocity;
441 Eigen::VectorXf currentLeftTwist = jacobiL * leftqvel;
442 Eigen::VectorXf currentRightTwist = jacobiR * rightqvel;
444 controllerSensorData.
getWriteBuffer().currentLeftTwist = currentLeftTwist;
445 controllerSensorData.
getWriteBuffer().currentRightTwist = currentRightTwist;
449 jacobiL.block<3, 8>(0, 0) = 0.001 * jacobiL.block<3, 8>(0, 0);
450 jacobiR.block<3, 8>(0, 0) = 0.001 * jacobiR.block<3, 8>(0, 0);
460 float normLinearVelocity = leftTargetVel.block<3, 1>(0, 0).
norm();
461 if (normLinearVelocity > maxLinearVel)
463 leftTargetVel.block<3, 1>(0, 0) = maxLinearVel * leftTargetVel.block<3, 1>(0, 0) / normLinearVelocity;
465 float normAngularVelocity = leftTargetVel.block<3, 1>(3, 0).
norm();
466 if (normAngularVelocity > maxAngularVel)
468 leftTargetVel.block<3, 1>(3, 0) = maxAngularVel * leftTargetVel.block<3, 1>(3, 0) / normAngularVelocity;
472 normLinearVelocity = rightTargetVel.block<3, 1>(0, 0).
norm();
473 if (normLinearVelocity > maxLinearVel)
475 rightTargetVel.block<3, 1>(0, 0) = maxLinearVel * rightTargetVel.block<3, 1>(0, 0) / normLinearVelocity;
477 normAngularVelocity = leftTargetVel.block<3, 1>(3, 0).
norm();
478 if (normAngularVelocity > maxAngularVel)
480 rightTargetVel.block<3, 1>(3, 0) = maxAngularVel * rightTargetVel.block<3, 1>(3, 0) / normAngularVelocity;
490 Eigen::Vector3f targetTCPLinearVelocity;
491 targetTCPLinearVelocity << 0.001 * leftTargetVel(0), 0.001 * leftTargetVel(1), 0.001 * leftTargetVel(2);
493 Eigen::Vector3f currentTCPLinearVelocity;
494 currentTCPLinearVelocity << 0.001 * currentLeftTwist(0), 0.001 * currentLeftTwist(1), 0.001 * currentLeftTwist(2);
495 Eigen::Vector3f currentTCPAngularVelocity;
496 currentTCPAngularVelocity << currentLeftTwist(3), currentLeftTwist(4), currentLeftTwist(5);
497 Eigen::Vector3f currentTCPPosition = leftCurrentPose.block<3, 1>(0, 3);
498 Eigen::Vector3f desiredPosition = leftTargetPose.block<3, 1>(0, 3);
500 Eigen::Vector3f tcpDesiredForce = 0.001 * leftKpos.cwiseProduct(desiredPosition - currentTCPPosition) + leftDpos.cwiseProduct(targetTCPLinearVelocity - currentTCPLinearVelocity);
502 Eigen::Matrix3f diffMat = leftTargetPose.block<3, 3>(0, 0) * currentRotMat.inverse();
503 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
504 Eigen::Vector3f tcpDesiredTorque = leftKori.cwiseProduct(rpy) - leftDori.cwiseProduct(currentTCPAngularVelocity);
505 leftJointControlWrench << tcpDesiredForce, tcpDesiredTorque;
511 Eigen::Vector3f targetTCPLinearVelocity;
512 targetTCPLinearVelocity << 0.001 * rightTargetVel(0), 0.001 * rightTargetVel(1), 0.001 * rightTargetVel(2);
514 Eigen::Vector3f currentTCPLinearVelocity;
515 currentTCPLinearVelocity << 0.001 * currentRightTwist(0), 0.001 * currentRightTwist(1), 0.001 * currentRightTwist(2);
516 Eigen::Vector3f currentTCPAngularVelocity;
517 currentTCPAngularVelocity << currentRightTwist(3), currentRightTwist(4), currentRightTwist(5);
518 Eigen::Vector3f currentTCPPosition = rightCurrentPose.block<3, 1>(0, 3);
519 Eigen::Vector3f desiredPosition = rightTargetPose.block<3, 1>(0, 3);
521 Eigen::Vector3f tcpDesiredForce = 0.001 * rightKpos.cwiseProduct(desiredPosition - currentTCPPosition) + rightDpos.cwiseProduct(targetTCPLinearVelocity - currentTCPLinearVelocity);
523 Eigen::Matrix3f diffMat = rightTargetPose.block<3, 3>(0, 0) * currentRotMat.inverse();
524 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
525 Eigen::Vector3f tcpDesiredTorque = rightKori.cwiseProduct(rpy) - rightDori.cwiseProduct(currentTCPAngularVelocity);
526 rightJointControlWrench << tcpDesiredForce, tcpDesiredTorque;
563 Eigen::VectorXf leftNullspaceTorque = knull * (leftDesiredJointValues - leftqpos) - dnull * leftqvel;
564 Eigen::VectorXf rightNullspaceTorque = knull * (rightDesiredJointValues - rightqpos) - dnull * rightqvel;
568 Eigen::MatrixXf jtpinvL = leftIK->computePseudoInverseJacobianMatrix(jacobiL.transpose(), lambda);
569 Eigen::MatrixXf jtpinvR = rightIK->computePseudoInverseJacobianMatrix(jacobiR.transpose(), lambda);
570 Eigen::VectorXf leftJointDesiredTorques = jacobiL.transpose() * leftJointControlWrench + (I - jacobiL.transpose() * jtpinvL) * leftNullSpaceCoefs.cwiseProduct(leftNullspaceTorque);
571 Eigen::VectorXf rightJointDesiredTorques = jacobiR.transpose() * rightJointControlWrench + (I - jacobiR.transpose() * jtpinvR) * rightNullSpaceCoefs.cwiseProduct(rightNullspaceTorque);
576 for (
size_t i = 0; i < leftTargets.size(); ++i)
578 float desiredTorque = leftJointDesiredTorques(i);
580 if (isnan(desiredTorque))
585 desiredTorque = (desiredTorque > torqueLimit) ? torqueLimit : desiredTorque;
586 desiredTorque = (desiredTorque < -torqueLimit) ? -torqueLimit : desiredTorque;
588 debugDataInfo.
getWriteBuffer().desired_torques[leftJointNames[i]] = desiredTorque;
590 leftTargets.at(i)->torque = desiredTorque;
595 for (
size_t i = 0; i < rightTargets.size(); ++i)
597 float desiredTorque = rightJointDesiredTorques(i);
599 if (isnan(desiredTorque))
604 desiredTorque = (desiredTorque > torqueLimit) ? torqueLimit : desiredTorque;
605 desiredTorque = (desiredTorque < -torqueLimit) ? -torqueLimit : desiredTorque;
607 debugDataInfo.
getWriteBuffer().desired_torques[rightJointNames[i]] = desiredTorque;
609 rightTargets.at(i)->torque = desiredTorque;
611 debugDataInfo.
getWriteBuffer().leftControlSignal_x = leftJointControlWrench(0);
613 debugDataInfo.
getWriteBuffer().leftControlSignal_x = leftJointControlWrench(0);
614 debugDataInfo.
getWriteBuffer().leftControlSignal_y = leftJointControlWrench(1);
615 debugDataInfo.
getWriteBuffer().leftControlSignal_z = leftJointControlWrench(2);
616 debugDataInfo.
getWriteBuffer().leftControlSignal_ro = leftJointControlWrench(3);
617 debugDataInfo.
getWriteBuffer().leftControlSignal_pi = leftJointControlWrench(4);
618 debugDataInfo.
getWriteBuffer().leftControlSignal_ya = leftJointControlWrench(5);
620 debugDataInfo.
getWriteBuffer().rightControlSignal_x = rightJointControlWrench(0);
621 debugDataInfo.
getWriteBuffer().rightControlSignal_y = rightJointControlWrench(1);
622 debugDataInfo.
getWriteBuffer().rightControlSignal_z = rightJointControlWrench(2);
623 debugDataInfo.
getWriteBuffer().rightControlSignal_ro = rightJointControlWrench(3);
624 debugDataInfo.
getWriteBuffer().rightControlSignal_pi = rightJointControlWrench(4);
625 debugDataInfo.
getWriteBuffer().rightControlSignal_ya = rightJointControlWrench(5);
631 debugDataInfo.
getWriteBuffer().leftTargetPose_x = leftTargetPose(0, 3);
632 debugDataInfo.
getWriteBuffer().leftTargetPose_y = leftTargetPose(1, 3);
633 debugDataInfo.
getWriteBuffer().leftTargetPose_z = leftTargetPose(2, 3);
634 debugDataInfo.
getWriteBuffer().leftCurrentPose_x = leftCurrentPose(0, 3);
635 debugDataInfo.
getWriteBuffer().leftCurrentPose_y = leftCurrentPose(1, 3);
636 debugDataInfo.
getWriteBuffer().leftCurrentPose_z = leftCurrentPose(2, 3);
639 debugDataInfo.
getWriteBuffer().rightTargetPose_x = rightTargetPose(0, 3);
640 debugDataInfo.
getWriteBuffer().rightTargetPose_y = rightTargetPose(1, 3);
641 debugDataInfo.
getWriteBuffer().rightTargetPose_z = rightTargetPose(2, 3);
643 debugDataInfo.
getWriteBuffer().rightCurrentPose_x = rightCurrentPose(0, 3);
644 debugDataInfo.
getWriteBuffer().rightCurrentPose_y = rightCurrentPose(1, 3);
645 debugDataInfo.
getWriteBuffer().rightCurrentPose_z = rightCurrentPose(2, 3);
673 if (name ==
"LeftLeader")
675 leftGroup.at(0)->learnDMPFromFiles(fileNames);
677 else if (name ==
"LeftFollower")
679 rightGroup.at(1)->learnDMPFromFiles(fileNames);
681 else if (name ==
"RightLeader")
683 rightGroup.at(0)->learnDMPFromFiles(fileNames);
687 leftGroup.at(1)->learnDMPFromFiles(fileNames);
695 if (leaderName ==
"Left")
697 leftGroup.at(0)->setViaPose(u, viapoint);
701 rightGroup.at(0)->setViaPose(u, viapoint);
708 if (leaderName ==
"Left")
710 leftGroup.at(0)->setGoalPoseVec(goals);
714 rightGroup.at(0)->setGoalPoseVec(goals);
723 if (leaderName ==
"Left")
725 leaderName =
"Right";
726 rightGroup.at(0)->canVal = virtualtimer;
727 rightGroup.at(1)->canVal = virtualtimer;
732 leftGroup.at(0)->canVal = virtualtimer;
733 leftGroup.at(1)->canVal = virtualtimer;
755 virtualtimer = cfg->timeDuration;
757 leftGroup.at(0)->prepareExecution(leftGroup.at(0)->eigen4f2vec(leftPose), leftGoals);
758 rightGroup.at(0)->prepareExecution(rightGroup.at(0)->eigen4f2vec(rightPose), rightGoals);
761 ARMARX_INFO <<
"leftgroup goal local pose: " << getLocalPose(leftGoals, rightGoals);
763 leftGroup.at(1)->prepareExecution(getLocalPose(leftPose, rightPose), getLocalPose(leftGoals, rightGoals));
764 rightGroup.at(1)->prepareExecution(getLocalPose(rightPose, leftPose), getLocalPose(rightGoals, leftGoals));
767 controllerTask->start();
774 localPose.block<3, 3>(0, 0) = newCoordinate.block<3, 3>(0, 0).inverse() * globalTargetPose.block<3, 3>(0, 0);
775 localPose.block<3, 1>(0, 3) = newCoordinate.block<3, 3>(0, 0).inverse() * (globalTargetPose.block<3, 1>(0, 3) - newCoordinate.block<3, 1>(0, 3));
790 datafields[pair.first] =
new Variant(pair.second);
794 for (
auto& pair : constrained_force)
796 datafields[pair.first] =
new Variant(pair.second);
833 debugObs->setDebugChannel(
"DMPController", datafields);
844 controllerTask->stop();