3 #include <VirtualRobot/MathTools.h>
4 #include <VirtualRobot/VirtualRobot.h>
10 #include <VirtualRobot/IK/DifferentialIK.h>
11 #include <VirtualRobot/Nodes/RobotNode.h>
12 #include <VirtualRobot/Robot.h>
13 #include <VirtualRobot/RobotNodeSet.h>
27 NJointControllerRegistration<NJointBimanualObjLevelVelController>
29 "NJointBimanualObjLevelVelController");
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;
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);
181 rt2ControlData initSensorData;
182 initSensorData.deltaT = 0;
183 initSensorData.currentTime = 0;
184 initSensorData.currentPose = leftRNS->getTCP()->getPoseInRootFrame();
185 initSensorData.currentTwist.setZero();
189 ControlInterfaceData initInterfaceData;
190 initInterfaceData.currentLeftPose = tcpLeft->getPoseInRootFrame();
191 initInterfaceData.currentRightPose = tcpRight->getPoseInRootFrame();
192 initInterfaceData.currentObjPose = leftRNS->getTCP()->getPoseInRootFrame();
193 initInterfaceData.currentObjVel.setZero();
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);
206 VirtualRobot::MathTools::quat2eigen4f(0.5, -0.5, -0.5, -0.5);
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();
237 objectDMP->setWeights(weights);
243 DMP::DVec2d res = objectDMP->getWeights();
245 for (
size_t i = 0; i < res.size(); ++i)
247 std::vector<double> cvec;
248 for (
size_t j = 0; j < res[i].size(); ++j)
250 cvec.push_back(res[i][j]);
252 resvec.push_back(cvec);
262 objectDMP->setRotWeights(weights);
268 DMP::DVec2d res = objectDMP->getRotWeights();
270 for (
size_t i = 0; i < res.size(); ++i)
272 std::vector<double> cvec;
273 for (
size_t j = 0; j < res[i].size(); ++j)
275 cvec.push_back(res[i][j]);
277 resvec.push_back(cvec);
289 leftPose.block<3, 1>(0, 3) = leftPose.block<3, 1>(0, 3);
290 rightPose.block<3, 1>(0, 3) = rightPose.block<3, 1>(0, 3);
291 boxInitPose.block<3, 1>(0, 3) =
292 0.5 * (leftPose.block<3, 1>(0, 3) + rightPose.block<3, 1>(0, 3));
293 boxInitPose.block<3, 3>(0, 0) = leftPose.block<3, 3>(0, 0);
296 initData.
boxPose = boxInitPose;
303 return "NJointBimanualObjLevelVelController";
316 Eigen::VectorXf currentTwist = rt2ControlBuffer.
getReadBuffer().currentTwist;
318 if (objectDMP->canVal < 0)
328 objectDMP->flow(deltaT, currentPose, currentTwist);
338 const Eigen::MatrixXf& jacobi,
339 const Eigen::VectorXf& cartesianVel,
340 const Eigen::VectorXf& nullspaceVel)
342 Eigen::FullPivLU<Eigen::MatrixXf> lu_decomp(jacobi);
344 Eigen::MatrixXf nullspace = lu_decomp.kernel();
345 Eigen::VectorXf nsv = Eigen::VectorXf::Zero(nullspace.rows());
346 for (
int i = 0; i < nullspace.cols(); i++)
348 float squaredNorm = nullspace.col(i).squaredNorm();
350 if (squaredNorm > 1.0e-32f)
352 nsv += nullspace.col(i) * nullspace.col(i).dot(nullspaceVel) /
353 nullspace.col(i).squaredNorm();
357 Eigen::MatrixXf inv = ik->computePseudoInverseJacobianMatrix(
358 jacobi, ik->getJacobiRegularization(VirtualRobot::IKSolver::CartesianSelection::All));
359 Eigen::VectorXf jointVel = inv * cartesianVel;
370 double deltaT = timeSinceLastIteration.toSecondsDouble();
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;
403 Eigen::MatrixXf graspMatrix;
404 graspMatrix.setZero(6, 12);
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);
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);
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;
469 controlInterfaceBuffer.
getWriteBuffer().currentObjPose = boxCurrentPose;
470 controlInterfaceBuffer.
getWriteBuffer().currentObjVel = boxCurrentTwist.head<3>();
471 controlInterfaceBuffer.
getWriteBuffer().currentLeftPose = currentLeftPose;
472 controlInterfaceBuffer.
getWriteBuffer().currentRightPose = currentRightPose;
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;
494 tcpTargetPoseLeft.block<3, 3>(0, 0) * currentLeftPose.block<3, 3>(0, 0).inverse();
495 Eigen::Vector3f errorRPYLeft = VirtualRobot::MathTools::eigen3f2rpy(diffMatLeft);
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);
566 VirtualRobot::MathTools::eigen4f2quat(currentLeftPose);
572 debugOutputData.
getWriteBuffer().currentPoseRight_x = currentRightPose(0, 3);
573 debugOutputData.
getWriteBuffer().currentPoseRight_y = currentRightPose(1, 3);
574 debugOutputData.
getWriteBuffer().currentPoseRight_z = currentRightPose(2, 3);
577 VirtualRobot::MathTools::eigen4f2quat(currentRightPose);
584 debugOutputData.
getWriteBuffer().dmpBoxPose_x = virtualPose(0, 3);
585 debugOutputData.
getWriteBuffer().dmpBoxPose_y = virtualPose(1, 3);
586 debugOutputData.
getWriteBuffer().dmpBoxPose_z = virtualPose(2, 3);
589 VirtualRobot::MathTools::eigen4f2quat(virtualPose);
601 objectDMP->learnDMPFromFiles(fileNames);
606 const Ice::Current& ice)
609 objectDMP->setGoalPoseVec(goals);
610 dmpGoal = VirtualRobot::MathTools::quat2eigen4f(goals[4], goals[5], goals[6], goals[3]);
611 dmpGoal(0, 3) = goals[0];
612 dmpGoal(1, 3) = goals[1];
613 dmpGoal(2, 3) = goals[2];
630 VirtualRobot::MathTools::eigen4f2quat(leftPose);
631 Eigen::Vector3f boxPosi = (leftPose.block<3, 1>(0, 3) + rightPose.block<3, 1>(0, 3)) / 2;
634 std::vector<double> boxInitialPose;
635 for (
size_t i = 0; i < 3; ++i)
637 boxInitialPose.push_back(boxPosi(i));
639 boxInitialPose.push_back(boxOri.w);
640 boxInitialPose.push_back(boxOri.x);
641 boxInitialPose.push_back(boxOri.y);
642 boxInitialPose.push_back(boxOri.z);
644 dmpGoal = VirtualRobot::MathTools::quat2eigen4f(goals[4], goals[5], goals[6], goals[3]);
645 dmpGoal(0, 3) = goals[0];
646 dmpGoal(1, 3) = goals[1];
647 dmpGoal(2, 3) = goals[2];
649 objectDMP->prepareExecution(boxInitialPose, goals);
650 objectDMP->canVal = timeDuration;
651 objectDMP->config.motionTimeDuration = timeDuration;
660 const Ice::DoubleSeq& goals,
670 dmpGoal = VirtualRobot::MathTools::quat2eigen4f(goals[4], goals[5], goals[6], goals[3]);
671 dmpGoal(0, 3) = goals[0];
672 dmpGoal(1, 3) = goals[1];
673 dmpGoal(2, 3) = goals[2];
675 objectDMP->prepareExecution(starts, goals);
676 objectDMP->canVal = timeDuration;
677 objectDMP->config.motionTimeDuration = timeDuration;
687 const Ice::DoubleSeq& viapoint,
692 objectDMP->setViaPose(u, viapoint);
698 objectDMP->removeAllViaPoints();
706 Eigen::VectorXf setpoint;
707 setpoint.setZero(
value.size());
710 for (
size_t i = 0; i <
value.size(); ++i)
712 setpoint(i) =
value.at(i);
724 Eigen::VectorXf setpoint;
725 setpoint.setZero(
value.size());
728 for (
size_t i = 0; i <
value.size(); ++i)
730 setpoint(i) =
value.at(i);
742 std::vector<float> tvelvec = {tvel(0), tvel(1), tvel(2)};
756 datafields[pair.first] =
new Variant(pair.second);
760 datafields[
"virtualPose_x"] =
762 datafields[
"virtualPose_y"] =
764 datafields[
"virtualPose_z"] =
767 datafields[
"currentPoseLeft_x"] =
769 datafields[
"currentPoseLeft_y"] =
771 datafields[
"currentPoseLeft_z"] =
780 datafields[
"currentPoseRight_x"] =
782 datafields[
"currentPoseRight_y"] =
784 datafields[
"currentPoseRight_z"] =
786 datafields[
"rightQuat_w"] =
788 datafields[
"rightQuat_x"] =
790 datafields[
"rightQuat_y"] =
792 datafields[
"rightQuat_z"] =
795 datafields[
"dmpBoxPose_x"] =
797 datafields[
"dmpBoxPose_y"] =
799 datafields[
"dmpBoxPose_z"] =
802 datafields[
"dmpBoxPose_qx"] =
804 datafields[
"dmpBoxPose_qy"] =
806 datafields[
"dmpBoxPose_qz"] =
808 datafields[
"dmpBoxPose_qw"] =
811 debugObs->setDebugChannel(
"BimanualForceController", datafields);
820 runTask(
"NJointBimanualObjLevelVelController",
825 while (
getState() == eManagedIceObjectStarted)
831 c.waitForCycleDuration();