3 #include <VirtualRobot/MathTools.h>
4 #include <VirtualRobot/VirtualRobot.h>
12 NJointControllerRegistration<NJointBimanualObjLevelVelController>
14 "NJointBimanualObjLevelVelController");
17 const RobotUnitPtr& robUnit,
18 const armarx::NJointControllerConfigPtr& config,
25 cfg = NJointBimanualObjLevelVelControllerConfigPtr::dynamicCast(config);
29 leftRNS =
rtGetRobot()->getRobotNodeSet(
"LeftArm");
31 for (
size_t i = 0; i < leftRNS->getSize(); ++i)
33 std::string jointName = leftRNS->getNode(i)->getName();
34 leftJointNames.push_back(jointName);
37 leftTargets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
38 const SensorValue1DoFActuatorVelocity* velocitySensor =
39 sv->
asA<SensorValue1DoFActuatorVelocity>();
40 const SensorValue1DoFActuatorPosition* positionSensor =
41 sv->
asA<SensorValue1DoFActuatorPosition>();
53 leftVelocitySensors.push_back(velocitySensor);
54 leftPositionSensors.push_back(positionSensor);
57 rightRNS =
rtGetRobot()->getRobotNodeSet(
"RightArm");
59 for (
size_t i = 0; i < rightRNS->getSize(); ++i)
61 std::string jointName = rightRNS->getNode(i)->getName();
62 rightJointNames.push_back(jointName);
65 rightTargets.push_back(ct->
asA<ControlTarget1DoFActuatorVelocity>());
67 const SensorValue1DoFActuatorVelocity* velocitySensor =
68 sv->
asA<SensorValue1DoFActuatorVelocity>();
69 const SensorValue1DoFActuatorPosition* positionSensor =
70 sv->
asA<SensorValue1DoFActuatorPosition>();
81 rightVelocitySensors.push_back(velocitySensor);
82 rightPositionSensors.push_back(positionSensor);
85 leftIK.reset(
new VirtualRobot::DifferentialIK(
86 leftRNS, leftRNS->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
87 rightIK.reset(
new VirtualRobot::DifferentialIK(rightRNS,
88 rightRNS->getRobot()->getRootNode(),
89 VirtualRobot::JacobiProvider::eSVDDamped));
97 double phaseDist0 = 50;
98 double phaseDist1 = 10;
99 double phaseKpPos = 1;
100 double phaseKpOri = 0.1;
101 double posToOriRatio = 10;
105 taskSpaceDMPConfig.
DMPMode = cfg->dmpMode;
106 taskSpaceDMPConfig.
DMPStyle = cfg->dmpType;
122 tcpLeft = leftRNS->getTCP();
123 tcpRight = rightRNS->getTCP();
126 KpImpedance.setZero(cfg->KpImpedance.size());
129 for (
int i = 0; i < KpImpedance.size(); ++i)
131 KpImpedance(i) = cfg->KpImpedance.at(i);
134 KdImpedance.setZero(cfg->KdImpedance.size());
137 for (
int i = 0; i < KdImpedance.size(); ++i)
139 KdImpedance(i) = cfg->KdImpedance.at(i);
142 Inferface2rtData initInt2rtData;
143 initInt2rtData.KpImpedance = KpImpedance;
144 initInt2rtData.KdImpedance = KdImpedance;
147 leftDesiredJointValues.resize(leftTargets.size());
150 for (
size_t i = 0; i < leftTargets.size(); ++i)
152 leftDesiredJointValues(i) = cfg->leftDesiredJointValues.at(i);
155 rightDesiredJointValues.resize(rightTargets.size());
158 for (
size_t i = 0; i < rightTargets.size(); ++i)
160 rightDesiredJointValues(i) = cfg->rightDesiredJointValues.at(i);
166 rt2ControlData initSensorData;
167 initSensorData.deltaT = 0;
168 initSensorData.currentTime = 0;
169 initSensorData.currentPose = leftRNS->getTCP()->getPoseInRootFrame();
170 initSensorData.currentTwist.setZero();
174 ControlInterfaceData initInterfaceData;
175 initInterfaceData.currentLeftPose = tcpLeft->getPoseInRootFrame();
176 initInterfaceData.currentRightPose = tcpRight->getPoseInRootFrame();
177 initInterfaceData.currentObjPose = leftRNS->getTCP()->getPoseInRootFrame();
178 initInterfaceData.currentObjVel.setZero();
182 leftInitialPose = tcpLeft->getPoseInRootFrame();
183 rightInitialPose = tcpRight->getPoseInRootFrame();
184 leftInitialPose.block<3, 1>(0, 3) = leftInitialPose.block<3, 1>(0, 3);
185 rightInitialPose.block<3, 1>(0, 3) = rightInitialPose.block<3, 1>(0, 3);
191 VirtualRobot::MathTools::quat2eigen4f(0.5, -0.5, -0.5, -0.5);
193 VirtualRobot::MathTools::quat2eigen4f(0.5, 0.5, 0.5, -0.5);
194 fixedLeftRightRotOffset = leftLeveledRotation.block<3, 3>(0, 0).
transpose() *
195 rightLeveledRotation.block<3, 3>(0, 0);
198 boxInitialPose = leftInitialPose;
199 boxInitialPose(0, 3) = (leftInitialPose(0, 3) + rightInitialPose(0, 3)) / 2;
200 boxInitialPose(1, 3) = (leftInitialPose(1, 3) + rightInitialPose(1, 3)) / 2;
201 boxInitialPose(2, 3) = (leftInitialPose(2, 3) + rightInitialPose(2, 3)) / 2;
204 initData.
boxPose = boxInitialPose;
207 dmpGoal = boxInitialPose;
211 << leftInitialPose <<
"\n right initial pose: \n"
214 objCom2TCPLeftInObjFrame.setZero();
215 objCom2TCPRightInObjFrame.setZero();
222 objectDMP->setWeights(weights);
228 DMP::DVec2d res = objectDMP->getWeights();
230 for (
size_t i = 0; i < res.size(); ++i)
232 std::vector<double> cvec;
233 for (
size_t j = 0; j < res[i].size(); ++j)
235 cvec.push_back(res[i][j]);
237 resvec.push_back(cvec);
247 objectDMP->setRotWeights(weights);
253 DMP::DVec2d res = objectDMP->getRotWeights();
255 for (
size_t i = 0; i < res.size(); ++i)
257 std::vector<double> cvec;
258 for (
size_t j = 0; j < res[i].size(); ++j)
260 cvec.push_back(res[i][j]);
262 resvec.push_back(cvec);
274 leftPose.block<3, 1>(0, 3) = leftPose.block<3, 1>(0, 3);
275 rightPose.block<3, 1>(0, 3) = rightPose.block<3, 1>(0, 3);
276 boxInitPose.block<3, 1>(0, 3) =
277 0.5 * (leftPose.block<3, 1>(0, 3) + rightPose.block<3, 1>(0, 3));
278 boxInitPose.block<3, 3>(0, 0) = leftPose.block<3, 3>(0, 0);
281 initData.
boxPose = boxInitPose;
288 return "NJointBimanualObjLevelVelController";
301 Eigen::VectorXf currentTwist = rt2ControlBuffer.
getReadBuffer().currentTwist;
303 if (objectDMP->canVal < 0)
313 objectDMP->flow(deltaT, currentPose, currentTwist);
324 const Eigen::MatrixXf& jacobi,
325 const Eigen::VectorXf& cartesianVel,
326 const Eigen::VectorXf& nullspaceVel)
328 Eigen::FullPivLU<Eigen::MatrixXf> lu_decomp(jacobi);
330 Eigen::MatrixXf nullspace = lu_decomp.kernel();
331 Eigen::VectorXf nsv = Eigen::VectorXf::Zero(nullspace.rows());
332 for (
int i = 0; i < nullspace.cols(); i++)
334 float squaredNorm = nullspace.col(i).squaredNorm();
336 if (squaredNorm > 1.0e-32f)
338 nsv += nullspace.col(i) * nullspace.col(i).dot(nullspaceVel) /
339 nullspace.col(i).squaredNorm();
343 Eigen::MatrixXf inv = ik->computePseudoInverseJacobianMatrix(
344 jacobi, ik->getJacobiRegularization(VirtualRobot::IKSolver::CartesianSelection::All));
345 Eigen::VectorXf jointVel = inv * cartesianVel;
356 double deltaT = timeSinceLastIteration.toSecondsDouble();
363 leftPose.block<3, 1>(0, 3) = leftPose.block<3, 1>(0, 3);
364 rightPose.block<3, 1>(0, 3) = rightPose.block<3, 1>(0, 3);
366 virtualPose.block<3, 1>(0, 3) =
367 0.5 * (leftPose.block<3, 1>(0, 3) + rightPose.block<3, 1>(0, 3));
368 virtualPose.block<3, 3>(0, 0) = leftPose.block<3, 3>(0, 0);
371 Eigen::Vector3f objCom2TCPLeftInGlobal =
372 leftPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
373 Eigen::Vector3f objCom2TCPRightInGlobal =
374 rightPose.block<3, 1>(0, 3) - virtualPose.block<3, 1>(0, 3);
376 objCom2TCPLeftInObjFrame =
377 virtualPose.block<3, 3>(0, 0).
transpose() * objCom2TCPLeftInGlobal;
378 objCom2TCPRightInObjFrame =
379 virtualPose.block<3, 3>(0, 0).
transpose() * objCom2TCPRightInGlobal;
389 Eigen::MatrixXf graspMatrix;
390 graspMatrix.setZero(6, 12);
393 Eigen::Vector3f rvec = virtualPose.block<3, 3>(0, 0) * objCom2TCPLeftInObjFrame;
394 graspMatrix.block<3, 3>(3, 0) =
skew(rvec);
396 rvec = virtualPose.block<3, 3>(0, 0) * objCom2TCPRightInObjFrame;
397 graspMatrix.block<3, 3>(3, 6) =
skew(rvec);
400 Eigen::MatrixXf pinvGraspMatrixT =
401 leftIK->computePseudoInverseJacobianMatrix(graspMatrix.transpose(), lambda);
405 boxCurrentPose.block<3, 1>(0, 3) =
406 0.5 * (currentLeftPose.block<3, 1>(0, 3) + currentRightPose.block<3, 1>(0, 3));
407 Eigen::VectorXf boxCurrentTwist;
408 boxCurrentTwist.setZero(6);
413 Eigen::MatrixXf jacobiL =
414 leftIK->getJacobianMatrix(tcpLeft, VirtualRobot::IKSolver::CartesianSelection::All);
415 Eigen::MatrixXf jacobiR =
416 rightIK->getJacobianMatrix(tcpRight, VirtualRobot::IKSolver::CartesianSelection::All);
419 Eigen::VectorXf leftqpos;
420 Eigen::VectorXf leftqvel;
421 leftqpos.resize(leftPositionSensors.size());
422 leftqvel.resize(leftVelocitySensors.size());
423 for (
size_t i = 0; i < leftVelocitySensors.size(); ++i)
425 leftqpos(i) = leftPositionSensors[i]->position;
426 leftqvel(i) = leftVelocitySensors[i]->velocity;
429 Eigen::VectorXf rightqpos;
430 Eigen::VectorXf rightqvel;
431 rightqpos.resize(rightPositionSensors.size());
432 rightqvel.resize(rightVelocitySensors.size());
434 for (
size_t i = 0; i < rightVelocitySensors.size(); ++i)
436 rightqpos(i) = rightPositionSensors[i]->position;
437 rightqvel(i) = rightVelocitySensors[i]->velocity;
441 Eigen::VectorXf currentLeftTwist = jacobiL * leftqvel;
442 Eigen::VectorXf currentRightTwist = jacobiR * rightqvel;
444 Eigen::VectorXf currentTwist(12);
445 currentTwist << currentLeftTwist, currentRightTwist;
446 boxCurrentTwist = pinvGraspMatrixT * currentTwist;
455 controlInterfaceBuffer.
getWriteBuffer().currentObjPose = boxCurrentPose;
456 controlInterfaceBuffer.
getWriteBuffer().currentObjVel = boxCurrentTwist.head(3);
457 controlInterfaceBuffer.
getWriteBuffer().currentLeftPose = currentLeftPose;
458 controlInterfaceBuffer.
getWriteBuffer().currentRightPose = currentRightPose;
470 tcpTargetPoseRight.block<3, 3>(0, 0) =
471 virtualPose.block<3, 3>(0, 0) * fixedLeftRightRotOffset;
472 tcpTargetPoseLeft.block<3, 1>(0, 3) +=
473 virtualPose.block<3, 3>(0, 0) * objCom2TCPLeftInObjFrame;
474 tcpTargetPoseRight.block<3, 1>(0, 3) +=
475 virtualPose.block<3, 3>(0, 0) * objCom2TCPRightInObjFrame;
480 tcpTargetPoseLeft.block<3, 3>(0, 0) * currentLeftPose.block<3, 3>(0, 0).inverse();
481 Eigen::Vector3f errorRPYLeft = VirtualRobot::MathTools::eigen3f2rpy(diffMatLeft);
483 tcpTargetPoseRight.block<3, 3>(0, 0) * currentRightPose.block<3, 3>(0, 0).inverse();
484 Eigen::Vector3f errorRPYRight = VirtualRobot::MathTools::eigen3f2rpy(diffMatRight);
487 for (
size_t i = 0; i < 3; ++i)
489 leftTargetVel(i) = KpImpedance(i) * (tcpTargetPoseLeft(i, 3) - currentLeftPose(i, 3)) +
490 KdImpedance(i) * (-currentLeftTwist(i));
491 leftTargetVel(i + 3) = KpImpedance(i + 3) * errorRPYLeft(i) +
492 KdImpedance(i + 3) * (-currentLeftTwist(i + 3));
494 KpImpedance(i) * (tcpTargetPoseRight(i, 3) - currentRightPose(i, 3)) +
495 KdImpedance(i) * (-currentRightTwist(i));
496 rightTargetVel(i + 3) = KpImpedance(i + 3) * errorRPYRight(i) +
497 KdImpedance(i + 3) * (-currentRightTwist(i + 3));
501 Eigen::VectorXf leftJointNullSpaceVel =
502 cfg->knull * (leftDesiredJointValues - leftqpos) - cfg->dnull * leftqvel +
503 cfg->jointLimitAvoidanceKp * leftTCPController->calculateJointLimitAvoidance();
504 Eigen::VectorXf leftJointTargetVel =
505 calcIK(leftIK, jacobiL, leftTargetVel, leftJointNullSpaceVel);
508 Eigen::VectorXf rightJointNullSpaceVel =
509 cfg->knull * (rightDesiredJointValues - rightqpos) - cfg->dnull * rightqvel +
510 cfg->jointLimitAvoidanceKp * rightTCPController->calculateJointLimitAvoidance();
511 Eigen::VectorXf rightJointTargetVel =
512 calcIK(rightIK, jacobiR, rightTargetVel, rightJointNullSpaceVel);
514 for (
size_t i = 0; i < leftTargets.size(); ++i)
516 float desiredVel = leftJointTargetVel(i);
517 debugOutputData.
getWriteBuffer().desired_vels[leftJointNames[i]] = desiredVel;
519 if (fabs(desiredVel) > cfg->jointVelLimit || isnan(desiredVel))
524 leftTargets.at(i)->velocity = desiredVel;
527 for (
size_t i = 0; i < rightTargets.size(); ++i)
529 float desiredVel = rightJointTargetVel(i);
530 debugOutputData.
getWriteBuffer().desired_vels[rightJointNames[i]] = desiredVel;
532 if (fabs(desiredVel) > cfg->jointVelLimit || isnan(desiredVel))
537 rightTargets.at(i)->velocity = desiredVel;
542 debugOutputData.
getWriteBuffer().virtualPose_x = virtualPose(0, 3);
543 debugOutputData.
getWriteBuffer().virtualPose_y = virtualPose(1, 3);
544 debugOutputData.
getWriteBuffer().virtualPose_z = virtualPose(2, 3);
546 debugOutputData.
getWriteBuffer().currentPoseLeft_x = currentLeftPose(0, 3);
547 debugOutputData.
getWriteBuffer().currentPoseLeft_y = currentLeftPose(1, 3);
548 debugOutputData.
getWriteBuffer().currentPoseLeft_z = currentLeftPose(2, 3);
552 VirtualRobot::MathTools::eigen4f2quat(currentLeftPose);
558 debugOutputData.
getWriteBuffer().currentPoseRight_x = currentRightPose(0, 3);
559 debugOutputData.
getWriteBuffer().currentPoseRight_y = currentRightPose(1, 3);
560 debugOutputData.
getWriteBuffer().currentPoseRight_z = currentRightPose(2, 3);
563 VirtualRobot::MathTools::eigen4f2quat(currentRightPose);
570 debugOutputData.
getWriteBuffer().dmpBoxPose_x = virtualPose(0, 3);
571 debugOutputData.
getWriteBuffer().dmpBoxPose_y = virtualPose(1, 3);
572 debugOutputData.
getWriteBuffer().dmpBoxPose_z = virtualPose(2, 3);
575 VirtualRobot::MathTools::eigen4f2quat(virtualPose);
587 objectDMP->learnDMPFromFiles(fileNames);
593 const Ice::Current& ice)
596 objectDMP->setGoalPoseVec(goals);
597 dmpGoal = VirtualRobot::MathTools::quat2eigen4f(goals[4], goals[5], goals[6], goals[3]);
598 dmpGoal(0, 3) = goals[0];
599 dmpGoal(1, 3) = goals[1];
600 dmpGoal(2, 3) = goals[2];
618 VirtualRobot::MathTools::eigen4f2quat(leftPose);
619 Eigen::Vector3f boxPosi = (leftPose.block<3, 1>(0, 3) + rightPose.block<3, 1>(0, 3)) / 2;
622 std::vector<double> boxInitialPose;
623 for (
size_t i = 0; i < 3; ++i)
625 boxInitialPose.push_back(boxPosi(i));
627 boxInitialPose.push_back(boxOri.w);
628 boxInitialPose.push_back(boxOri.x);
629 boxInitialPose.push_back(boxOri.y);
630 boxInitialPose.push_back(boxOri.z);
632 dmpGoal = VirtualRobot::MathTools::quat2eigen4f(goals[4], goals[5], goals[6], goals[3]);
633 dmpGoal(0, 3) = goals[0];
634 dmpGoal(1, 3) = goals[1];
635 dmpGoal(2, 3) = goals[2];
637 objectDMP->prepareExecution(boxInitialPose, goals);
638 objectDMP->canVal = timeDuration;
639 objectDMP->config.motionTimeDuration = timeDuration;
648 const Ice::DoubleSeq& goals,
658 dmpGoal = VirtualRobot::MathTools::quat2eigen4f(goals[4], goals[5], goals[6], goals[3]);
659 dmpGoal(0, 3) = goals[0];
660 dmpGoal(1, 3) = goals[1];
661 dmpGoal(2, 3) = goals[2];
663 objectDMP->prepareExecution(starts, goals);
664 objectDMP->canVal = timeDuration;
665 objectDMP->config.motionTimeDuration = timeDuration;
675 const Ice::DoubleSeq& viapoint,
680 objectDMP->setViaPose(u, viapoint);
686 objectDMP->removeAllViaPoints();
694 Eigen::VectorXf setpoint;
695 setpoint.setZero(
value.size());
698 for (
size_t i = 0; i <
value.size(); ++i)
700 setpoint(i) =
value.at(i);
712 Eigen::VectorXf setpoint;
713 setpoint.setZero(
value.size());
716 for (
size_t i = 0; i <
value.size(); ++i)
718 setpoint(i) =
value.at(i);
731 std::vector<float> tvelvec = {tvel(0), tvel(1), tvel(2)};
746 datafields[pair.first] =
new Variant(pair.second);
750 datafields[
"virtualPose_x"] =
752 datafields[
"virtualPose_y"] =
754 datafields[
"virtualPose_z"] =
757 datafields[
"currentPoseLeft_x"] =
759 datafields[
"currentPoseLeft_y"] =
761 datafields[
"currentPoseLeft_z"] =
770 datafields[
"currentPoseRight_x"] =
772 datafields[
"currentPoseRight_y"] =
774 datafields[
"currentPoseRight_z"] =
776 datafields[
"rightQuat_w"] =
778 datafields[
"rightQuat_x"] =
780 datafields[
"rightQuat_y"] =
782 datafields[
"rightQuat_z"] =
785 datafields[
"dmpBoxPose_x"] =
787 datafields[
"dmpBoxPose_y"] =
789 datafields[
"dmpBoxPose_z"] =
792 datafields[
"dmpBoxPose_qx"] =
794 datafields[
"dmpBoxPose_qy"] =
796 datafields[
"dmpBoxPose_qz"] =
798 datafields[
"dmpBoxPose_qw"] =
801 debugObs->setDebugChannel(
"BimanualForceController", datafields);
810 runTask(
"NJointBimanualObjLevelVelController",
815 while (
getState() == eManagedIceObjectStarted)
821 c.waitForCycleDuration();