33 const armarx::NJointControllerConfigPtr& config,
40 cfg = NJointBimanualObjLevelVelControllerConfigPtr::dynamicCast(config);
44 leftRNS =
rtGetRobot()->getRobotNodeSet(
"LeftArm");
46 for (
size_t i = 0; i < leftRNS->getSize(); ++i)
48 std::string jointName = leftRNS->getNode(i)->getName();
49 leftJointNames.push_back(jointName);
52 leftTargets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
53 const SensorValue1DoFActuatorVelocity* velocitySensor =
54 sv->
asA<SensorValue1DoFActuatorVelocity>();
55 const SensorValue1DoFActuatorPosition* positionSensor =
56 sv->
asA<SensorValue1DoFActuatorPosition>();
68 leftVelocitySensors.push_back(velocitySensor);
69 leftPositionSensors.push_back(positionSensor);
72 rightRNS =
rtGetRobot()->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);
80 rightTargets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
82 const SensorValue1DoFActuatorVelocity* velocitySensor =
83 sv->
asA<SensorValue1DoFActuatorVelocity>();
84 const SensorValue1DoFActuatorPosition* positionSensor =
85 sv->
asA<SensorValue1DoFActuatorPosition>();
96 rightVelocitySensors.push_back(velocitySensor);
97 rightPositionSensors.push_back(positionSensor);
100 leftIK.reset(
new VirtualRobot::DifferentialIK(
101 leftRNS, leftRNS->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
102 rightIK.reset(
new VirtualRobot::DifferentialIK(rightRNS,
103 rightRNS->getRobot()->getRootNode(),
104 VirtualRobot::JacobiProvider::eSVDDamped));
112 double phaseDist0 = 50;
113 double phaseDist1 = 10;
114 double phaseKpPos = 1;
115 double phaseKpOri = 0.1;
116 double posToOriRatio = 10;
120 taskSpaceDMPConfig.
DMPMode = cfg->dmpMode;
121 taskSpaceDMPConfig.
DMPStyle = cfg->dmpType;
137 tcpLeft = leftRNS->getTCP();
138 tcpRight = rightRNS->getTCP();
141 KpImpedance.setZero(cfg->KpImpedance.size());
144 for (
int i = 0; i < KpImpedance.size(); ++i)
146 KpImpedance(i) = cfg->KpImpedance.at(i);
149 KdImpedance.setZero(cfg->KdImpedance.size());
152 for (
int i = 0; i < KdImpedance.size(); ++i)
154 KdImpedance(i) = cfg->KdImpedance.at(i);
157 Inferface2rtData initInt2rtData;
158 initInt2rtData.KpImpedance = KpImpedance;
159 initInt2rtData.KdImpedance = KdImpedance;
160 interface2rtBuffer.reinitAllBuffers(initInt2rtData);
162 leftDesiredJointValues.resize(leftTargets.size());
165 for (
size_t i = 0; i < leftTargets.size(); ++i)
167 leftDesiredJointValues(i) = cfg->leftDesiredJointValues.at(i);
170 rightDesiredJointValues.resize(rightTargets.size());
173 for (
size_t i = 0; i < rightTargets.size(); ++i)
175 rightDesiredJointValues(i) = cfg->rightDesiredJointValues.at(i);
178 virtualPose = Eigen::Matrix4f::Identity();
181 rt2ControlData initSensorData;
182 initSensorData.deltaT = 0;
183 initSensorData.currentTime = 0;
184 initSensorData.currentPose = leftRNS->getTCP()->getPoseInRootFrame();
185 initSensorData.currentTwist.setZero();
186 rt2ControlBuffer.reinitAllBuffers(initSensorData);
189 ControlInterfaceData initInterfaceData;
190 initInterfaceData.currentLeftPose = tcpLeft->getPoseInRootFrame();
191 initInterfaceData.currentRightPose = tcpRight->getPoseInRootFrame();
192 initInterfaceData.currentObjPose = leftRNS->getTCP()->getPoseInRootFrame();
193 initInterfaceData.currentObjVel.setZero();
194 controlInterfaceBuffer.reinitAllBuffers(initInterfaceData);
197 leftInitialPose = tcpLeft->getPoseInRootFrame();
198 rightInitialPose = tcpRight->getPoseInRootFrame();
199 leftInitialPose.block<3, 1>(0, 3) = leftInitialPose.block<3, 1>(0, 3);
200 rightInitialPose.block<3, 1>(0, 3) = rightInitialPose.block<3, 1>(0, 3);
203 fixedLeftRightRotOffset = Eigen::Matrix3f::Identity();
205 Eigen::Matrix4f rightLeveledRotation =
206 VirtualRobot::MathTools::quat2eigen4f(0.5, -0.5, -0.5, -0.5);
207 Eigen::Matrix4f leftLeveledRotation =
208 VirtualRobot::MathTools::quat2eigen4f(0.5, 0.5, 0.5, -0.5);
209 fixedLeftRightRotOffset = leftLeveledRotation.block<3, 3>(0, 0).
transpose() *
210 rightLeveledRotation.block<3, 3>(0, 0);
213 boxInitialPose = leftInitialPose;
214 boxInitialPose(0, 3) = (leftInitialPose(0, 3) + rightInitialPose(0, 3)) / 2;
215 boxInitialPose(1, 3) = (leftInitialPose(1, 3) + rightInitialPose(1, 3)) / 2;
216 boxInitialPose(2, 3) = (leftInitialPose(2, 3) + rightInitialPose(2, 3)) / 2;
219 initData.
boxPose = boxInitialPose;
222 dmpGoal = boxInitialPose;
226 << leftInitialPose <<
"\n right initial pose: \n"
229 objCom2TCPLeftInObjFrame.setZero();
230 objCom2TCPRightInObjFrame.setZero();
365 const IceUtil::Time& timeSinceLastIteration)
367 Eigen::Matrix4f currentLeftPose = tcpLeft->getPoseInRootFrame();
368 Eigen::Matrix4f currentRightPose = tcpRight->getPoseInRootFrame();
370 double deltaT = timeSinceLastIteration.toSecondsDouble();
374 Eigen::Matrix4f leftPose = tcpLeft->getPoseInRootFrame();
375 Eigen::Matrix4f rightPose = tcpRight->getPoseInRootFrame();
377 leftPose.block<3, 1>(0, 3) = leftPose.block<3, 1>(0, 3);
378 rightPose.block<3, 1>(0, 3) = rightPose.block<3, 1>(0, 3);
380 virtualPose.block<3, 1>(0, 3) =
381 0.5 * (leftPose.block<3, 1>(0, 3) + rightPose.block<3, 1>(0, 3));
382 virtualPose.block<3, 3>(0, 0) = leftPose.block<3, 3>(0, 0);
385 Eigen::Vector3f objCom2TCPLeftInGlobal =
386 leftPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
387 Eigen::Vector3f objCom2TCPRightInGlobal =
388 rightPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
390 objCom2TCPLeftInObjFrame =
391 virtualPose.block<3, 3>(0, 0).
transpose() * objCom2TCPLeftInGlobal;
392 objCom2TCPRightInObjFrame =
393 virtualPose.block<3, 3>(0, 0).
transpose() * objCom2TCPRightInGlobal;
398 KpImpedance = interface2rtBuffer.getUpToDateReadBuffer().KpImpedance;
399 KdImpedance = interface2rtBuffer.getUpToDateReadBuffer().KdImpedance;
403 Eigen::MatrixXf graspMatrix;
404 graspMatrix.setZero(6, 12);
405 graspMatrix.block<3, 3>(0, 0) = Eigen::MatrixXf::Identity(3, 3);
406 graspMatrix.block<3, 3>(0, 6) = Eigen::MatrixXf::Identity(3, 3);
407 Eigen::Vector3f rvec = virtualPose.block<3, 3>(0, 0) * objCom2TCPLeftInObjFrame;
408 graspMatrix.block<3, 3>(3, 0) =
skew(rvec);
410 rvec = virtualPose.block<3, 3>(0, 0) * objCom2TCPRightInObjFrame;
411 graspMatrix.block<3, 3>(3, 6) =
skew(rvec);
414 Eigen::MatrixXf pinvGraspMatrixT =
415 leftIK->computePseudoInverseJacobianMatrix(graspMatrix.transpose(), lambda);
418 Eigen::Matrix4f boxCurrentPose = currentLeftPose;
419 boxCurrentPose.block<3, 1>(0, 3) =
420 0.5 * (currentLeftPose.block<3, 1>(0, 3) + currentRightPose.block<3, 1>(0, 3));
421 Eigen::VectorXf boxCurrentTwist;
422 boxCurrentTwist.setZero(6);
425 Eigen::MatrixXf I = Eigen::MatrixXf::Identity(leftTargets.size(), leftTargets.size());
427 Eigen::MatrixXf jacobiL =
428 leftIK->getJacobianMatrix(tcpLeft, VirtualRobot::IKSolver::CartesianSelection::All);
429 Eigen::MatrixXf jacobiR =
430 rightIK->getJacobianMatrix(tcpRight, VirtualRobot::IKSolver::CartesianSelection::All);
433 Eigen::VectorXf leftqpos;
434 Eigen::VectorXf leftqvel;
435 leftqpos.resize(leftPositionSensors.size());
436 leftqvel.resize(leftVelocitySensors.size());
437 for (
size_t i = 0; i < leftVelocitySensors.size(); ++i)
439 leftqpos(i) = leftPositionSensors[i]->position;
440 leftqvel(i) = leftVelocitySensors[i]->velocity;
443 Eigen::VectorXf rightqpos;
444 Eigen::VectorXf rightqvel;
445 rightqpos.resize(rightPositionSensors.size());
446 rightqvel.resize(rightVelocitySensors.size());
448 for (
size_t i = 0; i < rightVelocitySensors.size(); ++i)
450 rightqpos(i) = rightPositionSensors[i]->position;
451 rightqvel(i) = rightVelocitySensors[i]->velocity;
455 Eigen::VectorXf currentLeftTwist = jacobiL * leftqvel;
456 Eigen::VectorXf currentRightTwist = jacobiR * rightqvel;
458 Eigen::VectorXf currentTwist(12);
459 currentTwist << currentLeftTwist, currentRightTwist;
460 boxCurrentTwist = pinvGraspMatrixT * currentTwist;
462 rt2ControlBuffer.getWriteBuffer().currentPose = boxCurrentPose;
463 rt2ControlBuffer.getWriteBuffer().currentTwist = boxCurrentTwist;
464 rt2ControlBuffer.getWriteBuffer().deltaT = deltaT;
465 rt2ControlBuffer.getWriteBuffer().currentTime += deltaT;
466 rt2ControlBuffer.commitWrite();
469 controlInterfaceBuffer.getWriteBuffer().currentObjPose = boxCurrentPose;
470 controlInterfaceBuffer.getWriteBuffer().currentObjVel = boxCurrentTwist.head<3>();
471 controlInterfaceBuffer.getWriteBuffer().currentLeftPose = currentLeftPose;
472 controlInterfaceBuffer.getWriteBuffer().currentRightPose = currentRightPose;
473 controlInterfaceBuffer.commitWrite();
481 Eigen::Matrix4f tcpTargetPoseLeft = virtualPose;
482 Eigen::Matrix4f tcpTargetPoseRight = virtualPose;
484 tcpTargetPoseRight.block<3, 3>(0, 0) =
485 virtualPose.block<3, 3>(0, 0) * fixedLeftRightRotOffset;
486 tcpTargetPoseLeft.block<3, 1>(0, 3) +=
487 virtualPose.block<3, 3>(0, 0) * objCom2TCPLeftInObjFrame;
488 tcpTargetPoseRight.block<3, 1>(0, 3) +=
489 virtualPose.block<3, 3>(0, 0) * objCom2TCPRightInObjFrame;
493 Eigen::Matrix3f diffMatLeft =
494 tcpTargetPoseLeft.block<3, 3>(0, 0) * currentLeftPose.block<3, 3>(0, 0).inverse();
495 Eigen::Vector3f errorRPYLeft = VirtualRobot::MathTools::eigen3f2rpy(diffMatLeft);
496 Eigen::Matrix3f diffMatRight =
497 tcpTargetPoseRight.block<3, 3>(0, 0) * currentRightPose.block<3, 3>(0, 0).inverse();
498 Eigen::Vector3f errorRPYRight = VirtualRobot::MathTools::eigen3f2rpy(diffMatRight);
501 for (
size_t i = 0; i < 3; ++i)
503 leftTargetVel(i) = KpImpedance(i) * (tcpTargetPoseLeft(i, 3) - currentLeftPose(i, 3)) +
504 KdImpedance(i) * (-currentLeftTwist(i));
505 leftTargetVel(i + 3) = KpImpedance(i + 3) * errorRPYLeft(i) +
506 KdImpedance(i + 3) * (-currentLeftTwist(i + 3));
508 KpImpedance(i) * (tcpTargetPoseRight(i, 3) - currentRightPose(i, 3)) +
509 KdImpedance(i) * (-currentRightTwist(i));
510 rightTargetVel(i + 3) = KpImpedance(i + 3) * errorRPYRight(i) +
511 KdImpedance(i + 3) * (-currentRightTwist(i + 3));
515 Eigen::VectorXf leftJointNullSpaceVel =
516 cfg->knull * (leftDesiredJointValues - leftqpos) - cfg->dnull * leftqvel +
517 cfg->jointLimitAvoidanceKp * leftTCPController->calculateJointLimitAvoidance();
518 Eigen::VectorXf leftJointTargetVel =
519 calcIK(leftIK, jacobiL, leftTargetVel, leftJointNullSpaceVel);
522 Eigen::VectorXf rightJointNullSpaceVel =
523 cfg->knull * (rightDesiredJointValues - rightqpos) - cfg->dnull * rightqvel +
524 cfg->jointLimitAvoidanceKp * rightTCPController->calculateJointLimitAvoidance();
525 Eigen::VectorXf rightJointTargetVel =
526 calcIK(rightIK, jacobiR, rightTargetVel, rightJointNullSpaceVel);
528 for (
size_t i = 0; i < leftTargets.size(); ++i)
530 float desiredVel = leftJointTargetVel(i);
531 debugOutputData.getWriteBuffer().desired_vels[leftJointNames[i]] = desiredVel;
533 if (fabs(desiredVel) > cfg->jointVelLimit || isnan(desiredVel))
538 leftTargets.at(i)->velocity = desiredVel;
541 for (
size_t i = 0; i < rightTargets.size(); ++i)
543 float desiredVel = rightJointTargetVel(i);
544 debugOutputData.getWriteBuffer().desired_vels[rightJointNames[i]] = desiredVel;
546 if (fabs(desiredVel) > cfg->jointVelLimit || isnan(desiredVel))
551 rightTargets.at(i)->velocity = desiredVel;
556 debugOutputData.getWriteBuffer().virtualPose_x = virtualPose(0, 3);
557 debugOutputData.getWriteBuffer().virtualPose_y = virtualPose(1, 3);
558 debugOutputData.getWriteBuffer().virtualPose_z = virtualPose(2, 3);
560 debugOutputData.getWriteBuffer().currentPoseLeft_x = currentLeftPose(0, 3);
561 debugOutputData.getWriteBuffer().currentPoseLeft_y = currentLeftPose(1, 3);
562 debugOutputData.getWriteBuffer().currentPoseLeft_z = currentLeftPose(2, 3);
565 VirtualRobot::MathTools::Quaternion leftQuat =
566 VirtualRobot::MathTools::eigen4f2quat(currentLeftPose);
567 debugOutputData.getWriteBuffer().leftQuat_w = leftQuat.w;
568 debugOutputData.getWriteBuffer().leftQuat_x = leftQuat.x;
569 debugOutputData.getWriteBuffer().leftQuat_y = leftQuat.y;
570 debugOutputData.getWriteBuffer().leftQuat_z = leftQuat.y;
572 debugOutputData.getWriteBuffer().currentPoseRight_x = currentRightPose(0, 3);
573 debugOutputData.getWriteBuffer().currentPoseRight_y = currentRightPose(1, 3);
574 debugOutputData.getWriteBuffer().currentPoseRight_z = currentRightPose(2, 3);
576 VirtualRobot::MathTools::Quaternion rightQuat =
577 VirtualRobot::MathTools::eigen4f2quat(currentRightPose);
578 debugOutputData.getWriteBuffer().rightQuat_w = rightQuat.w;
579 debugOutputData.getWriteBuffer().rightQuat_x = rightQuat.x;
580 debugOutputData.getWriteBuffer().rightQuat_y = rightQuat.y;
581 debugOutputData.getWriteBuffer().rightQuat_z = rightQuat.y;
584 debugOutputData.getWriteBuffer().dmpBoxPose_x = virtualPose(0, 3);
585 debugOutputData.getWriteBuffer().dmpBoxPose_y = virtualPose(1, 3);
586 debugOutputData.getWriteBuffer().dmpBoxPose_z = virtualPose(2, 3);
588 VirtualRobot::MathTools::Quaternion dmpQuat =
589 VirtualRobot::MathTools::eigen4f2quat(virtualPose);
590 debugOutputData.getWriteBuffer().dmpBoxPose_qx = dmpQuat.x;
591 debugOutputData.getWriteBuffer().dmpBoxPose_qy = dmpQuat.y;
592 debugOutputData.getWriteBuffer().dmpBoxPose_qz = dmpQuat.z;
593 debugOutputData.getWriteBuffer().dmpBoxPose_qw = dmpQuat.w;
594 debugOutputData.commitWrite();