37 const armarx::NJointControllerConfigPtr& config,
41 cfg = NJointBimanualCCDMPVelocityControllerConfigPtr::dynamicCast(config);
46 leftRNS =
rtGetRobot()->getRobotNodeSet(
"LeftArm");
47 leftNullSpaceCoefs.resize(leftRNS->getSize());
48 leftNullSpaceCoefs.setOnes();
50 for (
size_t i = 0; i < leftRNS->getSize(); ++i)
52 std::string jointName = leftRNS->getNode(i)->getName();
54 if (leftRNS->getNode(i)->isLimitless())
56 leftNullSpaceCoefs(i) = 1;
59 leftJointNames.push_back(jointName);
62 leftTargets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
63 const SensorValue1DoFActuatorVelocity* velocitySensor =
64 sv->
asA<SensorValue1DoFActuatorVelocity>();
65 const SensorValue1DoFActuatorPosition* positionSensor =
66 sv->
asA<SensorValue1DoFActuatorPosition>();
67 const SensorValue1DoFActuatorAcceleration* accelerationSensor =
68 sv->
asA<SensorValue1DoFActuatorAcceleration>();
79 if (!accelerationSensor)
81 ARMARX_WARNING <<
"No accelerationSensor available for " << jointName;
85 leftVelocitySensors.push_back(velocitySensor);
86 leftPositionSensors.push_back(positionSensor);
87 leftAccelerationSensors.push_back(accelerationSensor);
89 rightRNS =
rtGetRobot()->getRobotNodeSet(
"RightArm");
91 rightNullSpaceCoefs.resize(rightRNS->getSize());
92 rightNullSpaceCoefs.setOnes();
93 for (
size_t i = 0; i < rightRNS->getSize(); ++i)
95 std::string jointName = rightRNS->getNode(i)->getName();
97 if (rightRNS->getNode(i)->isLimitless())
99 rightNullSpaceCoefs(i) = 1;
102 rightJointNames.push_back(jointName);
105 rightTargets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
106 const SensorValue1DoFActuatorVelocity* velocitySensor =
107 sv->
asA<SensorValue1DoFActuatorVelocity>();
108 const SensorValue1DoFActuatorPosition* positionSensor =
109 sv->
asA<SensorValue1DoFActuatorPosition>();
110 const SensorValue1DoFActuatorAcceleration* accelerationSensor =
111 sv->
asA<SensorValue1DoFActuatorAcceleration>();
116 ARMARX_WARNING <<
"No velocitySensor available for " << jointName;
120 ARMARX_WARNING <<
"No positionSensor available for " << jointName;
122 if (!accelerationSensor)
124 ARMARX_WARNING <<
"No accelerationSensor available for " << jointName;
127 rightVelocitySensors.push_back(velocitySensor);
128 rightPositionSensors.push_back(positionSensor);
129 rightAccelerationSensors.push_back(accelerationSensor);
138 leftIK.reset(
new VirtualRobot::DifferentialIK(
139 leftRNS,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
140 rightIK.reset(
new VirtualRobot::DifferentialIK(
141 rightRNS,
rtGetRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
150 taskSpaceDMPConfig.
DMPMode = cfg->dmpMode;
151 taskSpaceDMPConfig.
DMPStyle = cfg->dmpType;
163 leftJointDMP.reset(
new DMP::UMIDMP(10));
164 rightJointDMP.reset(
new DMP::UMIDMP(10));
165 isLeftJointLearned =
false;
166 isRightJointLearned =
false;
171 leftGroup.push_back(leftLeader);
172 leftGroup.push_back(rightFollower);
174 rightGroup.push_back(rightLeader);
175 rightGroup.push_back(leftFollower);
177 bothLeaderGroup.push_back(leftLeader);
178 bothLeaderGroup.push_back(rightLeader);
181 tcpLeft = leftRNS->getTCP();
182 tcpRight = rightRNS->getTCP();
185 leaderName = cfg->defautLeader;
188 leftDesiredJointValues.resize(leftTargets.size());
191 for (
size_t i = 0; i < leftTargets.size(); ++i)
193 leftDesiredJointValues(i) = cfg->leftDesiredJointValues.at(i);
196 rightDesiredJointValues.resize(rightTargets.size());
199 for (
size_t i = 0; i < rightTargets.size(); ++i)
201 rightDesiredJointValues(i) = cfg->rightDesiredJointValues.at(i);
205 leftKpos << cfg->leftKpos[0], cfg->leftKpos[1], cfg->leftKpos[2];
206 leftDpos << cfg->leftDpos[0], cfg->leftDpos[1], cfg->leftDpos[2];
207 leftKori << cfg->leftKori[0], cfg->leftKori[1], cfg->leftKori[2];
208 leftDori << cfg->leftDori[0], cfg->leftDori[1], cfg->leftDori[2];
210 rightKpos << cfg->rightKpos[0], cfg->rightKpos[1], cfg->rightKpos[2];
211 rightDpos << cfg->rightDpos[0], cfg->rightDpos[1], cfg->rightDpos[2];
212 rightKori << cfg->rightKori[0], cfg->rightKori[1], cfg->rightKori[2];
213 rightDori << cfg->rightDori[0], cfg->rightDori[1], cfg->rightDori[2];
219 timeDuration = cfg->timeDuration;
221 maxLinearVel = cfg->maxLinearVel;
222 maxAngularVel = cfg->maxAngularVel;
224 NJointBimanualCCDMPVelocityControllerInterfaceData initInterfaceData;
225 initInterfaceData.currentLeftPose = Eigen::Matrix4f::Identity();
226 initInterfaceData.currentRightPose = Eigen::Matrix4f::Identity();
227 initInterfaceData.currentLeftJointVals.setZero(leftTargets.size());
228 initInterfaceData.currentRightJointVals.setZero(rightTargets.size());
229 interfaceData.reinitAllBuffers(initInterfaceData);
231 NJointBimanualCCDMPVelocityControllerSensorData initSensorData;
232 initSensorData.deltaT = 0;
233 initSensorData.currentTime = 0;
234 initSensorData.currentLeftPose = Eigen::Matrix4f::Identity();
235 initSensorData.currentRightPose = Eigen::Matrix4f::Identity();
236 controllerSensorData.reinitAllBuffers(initSensorData);
267 if (!controllerSensorData.updateReadBuffer())
271 double deltaT = controllerSensorData.getReadBuffer().deltaT;
274 Eigen::VectorXf leftTargetVel;
275 leftTargetVel.resize(6);
276 leftTargetVel.setZero();
277 Eigen::VectorXf rightTargetVel;
278 rightTargetVel.resize(6);
279 rightTargetVel.setZero();
280 Eigen::Matrix4f leftTargetPose;
281 Eigen::Matrix4f rightTargetPose;
283 std::vector<tsvmp::TaskSpaceDMPControllerPtr> currentControlGroup;
284 Eigen::Matrix4f currentLeaderPose;
285 Eigen::Matrix4f currentFollowerPose;
286 Eigen::VectorXf currentLeaderTwist;
287 Eigen::VectorXf currentFollowerTwist;
291 if (leaderName ==
"Both")
293 currentControlGroup = bothLeaderGroup;
297 leaderDMPleft->flow(deltaT,
298 controllerSensorData.getReadBuffer().currentLeftPose,
299 controllerSensorData.getReadBuffer().currentLeftTwist);
300 leaderDMPright->flow(deltaT,
301 controllerSensorData.getReadBuffer().currentRightPose,
302 controllerSensorData.getReadBuffer().currentRightTwist);
304 leftTargetVel = leaderDMPleft->getTargetVelocity();
305 leftTargetPose = leaderDMPleft->getTargetPoseMat();
306 rightTargetVel = leaderDMPright->getTargetVelocity();
307 rightTargetPose = leaderDMPright->getTargetPoseMat();
309 virtualtimer = leaderDMPleft->canVal;
313 if (leaderName ==
"Left")
315 currentControlGroup = leftGroup;
316 currentLeaderPose = controllerSensorData.getReadBuffer().currentLeftPose;
317 currentFollowerPose = controllerSensorData.getReadBuffer().currentRightPose;
318 currentLeaderTwist = controllerSensorData.getReadBuffer().currentLeftTwist;
319 currentFollowerTwist = controllerSensorData.getReadBuffer().currentRightTwist;
321 else if (leaderName ==
"Right")
323 currentControlGroup = rightGroup;
324 currentLeaderPose = controllerSensorData.getReadBuffer().currentRightPose;
325 currentFollowerPose = controllerSensorData.getReadBuffer().currentLeftPose;
326 currentLeaderTwist = controllerSensorData.getReadBuffer().currentRightTwist;
327 currentFollowerTwist = controllerSensorData.getReadBuffer().currentLeftTwist;
332 virtualtimer = leaderDMP->canVal;
334 if (virtualtimer < 1e-8)
342 leaderDMP->flow(deltaT, currentLeaderPose, currentLeaderTwist);
344 Eigen::Matrix4f currentFollowerLocalPose;
345 currentFollowerLocalPose.block<3, 3>(0, 0) =
346 currentLeaderPose.block<3, 3>(0, 0).inverse() *
347 currentFollowerPose.block<3, 3>(0, 0);
348 currentFollowerLocalPose.block<3, 1>(0, 3) =
349 currentLeaderPose.block<3, 3>(0, 0).inverse() *
350 (currentFollowerPose.block<3, 1>(0, 3) - currentLeaderPose.block<3, 1>(0, 3));
351 followerDMP->flow(deltaT, currentFollowerLocalPose, currentFollowerTwist);
353 Eigen::VectorXf leaderTargetVel = leaderDMP->getTargetVelocity();
354 Eigen::Matrix4f leaderTargetPose = leaderDMP->getTargetPoseMat();
355 Eigen::Matrix4f followerLocalTargetPose = followerDMP->getTargetPoseMat();
356 std::vector<double> followerLocalTargetPoseVec = followerDMP->getTargetPose();
358 Eigen::Matrix4f followerTargetPose;
359 followerTargetPose.block<3, 3>(0, 0) =
360 currentLeaderPose.block<3, 3>(0, 0) * followerLocalTargetPose.block<3, 3>(0, 0);
361 followerTargetPose.block<3, 1>(0, 3) =
362 currentLeaderPose.block<3, 3>(0, 0) * followerLocalTargetPose.block<3, 1>(0, 3) +
363 currentLeaderPose.block<3, 1>(0, 3);
366 Eigen::VectorXf followerLocalTargetVel = followerDMP->getTargetVelocity();
367 Eigen::VectorXf followerTargetVel = followerLocalTargetVel;
368 followerTargetVel.setZero();
370 std::vector<double> leftDMPTarget;
371 std::vector<double> rightDMPTarget;
373 if (leaderName ==
"Left")
375 leftTargetVel = leaderTargetVel;
376 rightTargetVel = followerTargetVel;
377 leftDMPTarget = leaderDMP->getTargetPose();
378 rightDMPTarget = followerLocalTargetPoseVec;
379 leftTargetPose = leaderTargetPose;
380 rightTargetPose = followerTargetPose;
382 else if (leaderName ==
"Right")
384 rightTargetVel = leaderTargetVel;
385 leftTargetVel = followerTargetVel;
386 rightDMPTarget = leaderDMP->getTargetPose();
387 leftDMPTarget = followerLocalTargetPoseVec;
388 rightTargetPose = leaderTargetPose;
389 leftTargetPose = followerTargetPose;
394 Eigen::VectorXf leftDesiredJoint = leftDesiredJointValues;
395 Eigen::VectorXf rightDesiredJoint = rightDesiredJointValues;
396 if (isLeftJointLearned)
398 DMP::DVec targetJointState;
399 currentLeftJointState =
400 leftJointDMP->calculateDirectlyVelocity(currentLeftJointState,
401 virtualtimer / timeDuration,
402 deltaT / timeDuration,
404 for (
size_t i = 0; i < targetJointState.size(); ++i)
406 leftDesiredJoint(i) = targetJointState[i];
410 if (isRightJointLearned)
412 DMP::DVec targetJointState;
413 currentRightJointState =
414 rightJointDMP->calculateDirectlyVelocity(currentRightJointState,
415 virtualtimer / timeDuration,
416 deltaT / timeDuration,
418 for (
size_t i = 0; i < targetJointState.size(); ++i)
420 rightDesiredJoint(i) = targetJointState[i];
446 const IceUtil::Time& timeSinceLastIteration)
448 double deltaT = timeSinceLastIteration.toSecondsDouble();
450 controllerSensorData.getWriteBuffer().currentLeftPose = tcpLeft->getPoseInRootFrame();
451 controllerSensorData.getWriteBuffer().currentRightPose = tcpRight->getPoseInRootFrame();
452 controllerSensorData.getWriteBuffer().deltaT = deltaT;
453 controllerSensorData.getWriteBuffer().currentTime += deltaT;
456 Eigen::MatrixXf I = Eigen::MatrixXf::Identity(leftTargets.size(), leftTargets.size());
458 Eigen::MatrixXf jacobiL =
459 leftIK->getJacobianMatrix(tcpLeft, VirtualRobot::IKSolver::CartesianSelection::All);
461 Eigen::VectorXf leftqpos;
462 Eigen::VectorXf leftqvel;
463 leftqpos.resize(leftPositionSensors.size());
464 leftqvel.resize(leftVelocitySensors.size());
465 for (
size_t i = 0; i < leftVelocitySensors.size(); ++i)
467 leftqpos(i) = leftPositionSensors[i]->position;
468 leftqvel(i) = leftVelocitySensors[i]->velocity;
471 Eigen::MatrixXf jacobiR =
472 rightIK->getJacobianMatrix(tcpRight, VirtualRobot::IKSolver::CartesianSelection::All);
473 Eigen::VectorXf rightqpos;
474 Eigen::VectorXf rightqvel;
475 rightqpos.resize(rightPositionSensors.size());
476 rightqvel.resize(rightVelocitySensors.size());
478 for (
size_t i = 0; i < rightVelocitySensors.size(); ++i)
480 rightqpos(i) = rightPositionSensors[i]->position;
481 rightqvel(i) = rightVelocitySensors[i]->velocity;
484 Eigen::VectorXf currentLeftTwist = jacobiL * leftqvel;
485 Eigen::VectorXf currentRightTwist = jacobiR * rightqvel;
487 controllerSensorData.getWriteBuffer().currentLeftTwist = currentLeftTwist;
488 controllerSensorData.getWriteBuffer().currentRightTwist = currentRightTwist;
489 controllerSensorData.commitWrite();
492 interfaceData.getWriteBuffer().currentLeftPose = tcpLeft->getPoseInRootFrame();
493 interfaceData.getWriteBuffer().currentRightPose = tcpRight->getPoseInRootFrame();
494 interfaceData.getWriteBuffer().currentLeftJointVals = leftqpos;
495 interfaceData.getWriteBuffer().currentRightJointVals = rightqpos;
496 interfaceData.commitWrite();
500 for (
size_t i = 0; i < leftTargets.size(); ++i)
502 leftTargets.at(i)->velocity = 0;
504 for (
size_t i = 0; i < rightTargets.size(); ++i)
506 rightTargets.at(i)->velocity = 0;
514 Eigen::Matrix4f leftCurrentPose = tcpLeft->getPoseInRootFrame();
515 Eigen::Matrix4f rightCurrentPose = tcpRight->getPoseInRootFrame();
522 Eigen::VectorXf leftCartesianTarget(6);
524 Eigen::Vector3f targetTCPLinearVelocity;
525 targetTCPLinearVelocity << leftTargetVel(0), leftTargetVel(1), leftTargetVel(2);
526 Eigen::Vector3f currentTCPLinearVelocity;
527 currentTCPLinearVelocity << currentLeftTwist(0), currentLeftTwist(1),
529 Eigen::Vector3f currentTCPPosition = leftCurrentPose.block<3, 1>(0, 3);
530 Eigen::Vector3f desiredPosition = leftTargetPose.block<3, 1>(0, 3);
531 Eigen::Vector3f posVel =
532 leftKpos.cwiseProduct(desiredPosition - currentTCPPosition) +
533 leftDpos.cwiseProduct(targetTCPLinearVelocity - currentTCPLinearVelocity);
536 Eigen::Vector3f currentTCPAngularVelocity;
537 currentTCPAngularVelocity << currentLeftTwist(3), currentLeftTwist(4),
539 Eigen::Matrix3f currentRotMat = leftCurrentPose.block<3, 3>(0, 0);
540 Eigen::Matrix3f diffMat =
541 leftTargetPose.block<3, 3>(0, 0) * currentRotMat.inverse();
542 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
543 Eigen::Vector3f oriVel =
544 leftKori.cwiseProduct(rpy) - leftDori.cwiseProduct(currentTCPAngularVelocity);
546 float normLinearVelocity = posVel.norm();
547 if (normLinearVelocity > maxLinearVel)
549 posVel = maxLinearVel * posVel / normLinearVelocity;
551 float normAngularVelocity = oriVel.norm();
552 if (normAngularVelocity > maxAngularVel)
554 oriVel = maxAngularVel * oriVel / normAngularVelocity;
557 leftCartesianTarget << posVel, oriVel;
560 Eigen::VectorXf rightCartesianTarget(6);
562 Eigen::Vector3f targetTCPLinearVelocity;
563 targetTCPLinearVelocity << rightTargetVel(0), rightTargetVel(1), rightTargetVel(2);
564 Eigen::Vector3f currentTCPLinearVelocity;
565 currentTCPLinearVelocity << currentRightTwist(0), currentRightTwist(1),
566 currentRightTwist(2);
567 Eigen::Vector3f currentTCPPosition = rightCurrentPose.block<3, 1>(0, 3);
568 Eigen::Vector3f desiredPosition = rightTargetPose.block<3, 1>(0, 3);
569 Eigen::Vector3f posVel =
570 rightKpos.cwiseProduct(desiredPosition - currentTCPPosition) +
571 rightDpos.cwiseProduct(targetTCPLinearVelocity - currentTCPLinearVelocity);
574 Eigen::Vector3f currentTCPAngularVelocity;
575 currentTCPAngularVelocity << currentRightTwist(3), currentRightTwist(4),
576 currentRightTwist(5);
577 Eigen::Matrix3f currentRotMat = rightCurrentPose.block<3, 3>(0, 0);
578 Eigen::Matrix3f diffMat =
579 rightTargetPose.block<3, 3>(0, 0) * currentRotMat.inverse();
580 Eigen::Vector3f rpy = VirtualRobot::MathTools::eigen3f2rpy(diffMat);
581 Eigen::Vector3f oriVel =
582 rightKori.cwiseProduct(rpy) - rightDori.cwiseProduct(currentTCPAngularVelocity);
584 float normLinearVelocity = posVel.norm();
585 if (normLinearVelocity > maxLinearVel)
587 posVel = maxLinearVel * posVel / normLinearVelocity;
589 float normAngularVelocity = oriVel.norm();
590 if (normAngularVelocity > maxAngularVel)
592 oriVel = maxAngularVel * oriVel / normAngularVelocity;
595 rightCartesianTarget << posVel, oriVel;
598 Eigen::VectorXf leftNullspaceVel =
599 knull * (leftDesiredJoint - leftqpos) - dnull * leftqvel;
600 Eigen::VectorXf rightNullspaceVel =
601 knull * (rightDesiredJoint - rightqpos) - dnull * rightqvel;
602 Eigen::VectorXf desiredLeftVels =
603 leftCtrl->calculate(leftCartesianTarget,
605 VirtualRobot::IKSolver::CartesianSelection::All);
606 Eigen::VectorXf desiredRightVels =
607 rightCtrl->calculate(rightCartesianTarget,
609 VirtualRobot::IKSolver::CartesianSelection::All);
612 for (
size_t i = 0; i < leftTargets.size(); ++i)
615 float desiredVel = desiredLeftVels[i];
617 if (fabs(desiredVel) > cfg->maxJointVel)
619 desiredVel = cfg->maxJointVel * desiredVel / fabs(desiredVel);
622 leftTargets.at(i)->velocity = desiredVel;
623 debugDataInfo.getWriteBuffer().desired_velocities[leftJointNames[i]] = desiredVel;
626 for (
size_t i = 0; i < rightTargets.size(); ++i)
628 float desiredVel = desiredRightVels[i];
630 if (fabs(desiredVel) > cfg->maxJointVel)
632 desiredVel = cfg->maxJointVel * desiredVel / fabs(desiredVel);
635 rightTargets.at(i)->velocity = desiredVel;
636 debugDataInfo.getWriteBuffer().desired_velocities[rightJointNames[i]] = desiredVel;
640 debugDataInfo.getWriteBuffer().leftControlSignal_x = leftCartesianTarget(0);
641 debugDataInfo.getWriteBuffer().leftControlSignal_y = leftCartesianTarget(1);
642 debugDataInfo.getWriteBuffer().leftControlSignal_z = leftCartesianTarget(2);
643 debugDataInfo.getWriteBuffer().leftControlSignal_ro = leftCartesianTarget(3);
644 debugDataInfo.getWriteBuffer().leftControlSignal_pi = leftCartesianTarget(4);
645 debugDataInfo.getWriteBuffer().leftControlSignal_ya = leftCartesianTarget(5);
647 debugDataInfo.getWriteBuffer().rightControlSignal_x = rightCartesianTarget(0);
648 debugDataInfo.getWriteBuffer().rightControlSignal_y = rightCartesianTarget(1);
649 debugDataInfo.getWriteBuffer().rightControlSignal_z = rightCartesianTarget(2);
650 debugDataInfo.getWriteBuffer().rightControlSignal_ro = rightCartesianTarget(3);
651 debugDataInfo.getWriteBuffer().rightControlSignal_pi = rightCartesianTarget(4);
652 debugDataInfo.getWriteBuffer().rightControlSignal_ya = rightCartesianTarget(5);
654 debugDataInfo.getWriteBuffer().leftTargetPose_x = leftTargetPose(0, 3);
655 debugDataInfo.getWriteBuffer().leftTargetPose_y = leftTargetPose(1, 3);
656 debugDataInfo.getWriteBuffer().leftTargetPose_z = leftTargetPose(2, 3);
657 debugDataInfo.getWriteBuffer().leftCurrentPose_x = leftCurrentPose(0, 3);
658 debugDataInfo.getWriteBuffer().leftCurrentPose_y = leftCurrentPose(1, 3);
659 debugDataInfo.getWriteBuffer().leftCurrentPose_z = leftCurrentPose(2, 3);
662 debugDataInfo.getWriteBuffer().rightTargetPose_x = rightTargetPose(0, 3);
663 debugDataInfo.getWriteBuffer().rightTargetPose_y = rightTargetPose(1, 3);
664 debugDataInfo.getWriteBuffer().rightTargetPose_z = rightTargetPose(2, 3);
666 debugDataInfo.getWriteBuffer().rightCurrentPose_x = rightCurrentPose(0, 3);
667 debugDataInfo.getWriteBuffer().rightCurrentPose_y = rightCurrentPose(1, 3);
668 debugDataInfo.getWriteBuffer().rightCurrentPose_z = rightCurrentPose(2, 3);
669 debugDataInfo.getWriteBuffer().virtualTime = virtualtime;
671 debugDataInfo.commitWrite();