28 #include <VirtualRobot/IK/DifferentialIK.h>
29 #include <VirtualRobot/Nodes/RobotNode.h>
30 #include <VirtualRobot/Robot.h>
31 #include <VirtualRobot/RobotNodeSet.h>
32 #include <VirtualRobot/math/Helpers.h>
40 ik.reset(
new VirtualRobot::DifferentialIK(
41 rns, rns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
47 targets.emplace_back(
target);
63 nullspaceGradients.emplace_back(gradient);
68 const Eigen::Vector3f&
target)
86 for (VirtualRobot::RobotNodePtr rn : rns->getAllRobotNodes())
88 if (rn->isLimitless())
94 rn->setJointValue((rn->getJointLimitHi() + rn->getJointLimitLo()) / 2);
103 s.cols = rns->getSize();
110 s.jointRegularization = Eigen::VectorXf::Zero(
s.cols);
111 for (
size_t i = 0; i < rns->getSize(); i++)
113 s.jointRegularization(i) = rns->getNode(i)->isTranslationalJoint()
118 s.cartesianRegularization = Eigen::VectorXf::Zero(
s.rows);
125 target->jacobi = Eigen::MatrixXf::Zero(h,
s.cols);
126 s.cartesianRegularization.block(row, 0, h, 1) =
134 s.jointValues = rns->getJointValuesEigen();
136 for (
size_t i = 0; i <= params.
steps; i++)
141 bool allReached =
true;
144 allReached = allReached &&
159 for (
size_t i = 0; i < rns->getSize(); i++)
161 VirtualRobot::RobotNodePtr rn = rns->getNode(i);
162 if (rn->isLimitless())
169 rn->getJointLimitHi() - rn->getJointValue());
181 Eigen::FullPivLU<Eigen::MatrixXf> lu_decomp(jacobi);
182 Eigen::MatrixXf nullspaceLU = lu_decomp.kernel();
190 int rows = jacobi.rows();
191 int cols = jacobi.cols();
192 Eigen::JacobiSVD<Eigen::MatrixXf> svd(jacobi, Eigen::ComputeFullU | Eigen::ComputeFullV);
199 Eigen::MatrixXf V = svd.matrixV();
200 Eigen::MatrixXf nullspaceSVD = V.block(0, rows, cols, cols - rows);
208 s.jacobi = Eigen::MatrixXf::Zero(
s.rows,
s.cols);
209 s.invJac = Eigen::MatrixXf::Zero(
s.cols,
s.rows);
211 Eigen::VectorXf cartesianVel = Eigen::VectorXf::Zero(
s.rows);
218 s.jacobi.block(row, 0, h,
s.cols) =
target->jacobi;
221 cartesianVel.block(row, 0, h, 1) =
cv;
226 step.tcpPose =
target->tcp->getPoseInRootFrame();
240 for (
int row = 0; row <
s.rows; row++)
242 s.jacobi.block(row, 0, 1,
s.cols) =
243 s.jacobi.block(row, 0, 1,
s.cols).cwiseProduct(
s.jointRegularization.transpose());
250 ik->updatePseudoInverseJacobianMatrix(
s.invJac,
s.jacobi, 0,
s.cartesianRegularization);
252 Eigen::VectorXf nullspaceVel = Eigen::VectorXf::Zero(
s.cols);
256 Eigen::VectorXf nsgrad = nsGradient->kP * nsGradient->getGradient(params);
258 nullspaceVel += nsgrad;
267 Eigen::JacobiSVD<Eigen::MatrixXf> svd(
s.jacobi, Eigen::ComputeFullU | Eigen::ComputeFullV);
268 Eigen::MatrixXf V = svd.matrixV();
269 Eigen::MatrixXf nullspaceSVD = V.block(0,
s.rows,
s.cols,
s.cols -
s.rows);
271 s.nullspace = nullspaceSVD;
273 Eigen::VectorXf nsv = Eigen::VectorXf::Zero(
s.cols);
274 for (
int i = 0; i <
s.nullspace.cols(); i++)
276 float squaredNorm =
s.nullspace.col(i).squaredNorm();
278 if (squaredNorm > 1.0e-32f)
280 nsv +=
s.nullspace.col(i) *
s.nullspace.col(i).dot(nullspaceVel) /
281 s.nullspace.col(i).squaredNorm();
285 Eigen::VectorXf jv =
s.invJac * cartesianVel;
291 jv = jv.cwiseProduct(
s.jointRegularization);
295 Eigen::VectorXf newJointValues =
s.jointValues + jv;
304 rns->setJointValues(newJointValues);
305 s.jointValues = newJointValues;
317 case VirtualRobot::IKSolver::CartesianSelection::All:
320 throw LocalException(
"mode not supported: ") << mode;
325 const VirtualRobot::RobotNodePtr& tcp,
330 jacobi = Eigen::MatrixXf::Zero(0, 0);
334 const VirtualRobot::RobotNodePtr& tcp,
337 tcp(tcp),
target(
target), mode(mode), pCtrl(tcp), vCtrl(rns, tcp)
350 Eigen::VectorXf
cv = pCtrl.calculate(
target, mode);
351 Eigen::VectorXf jv = vCtrl.calculate(
cv, mode);
355 step.tcpPose = tcp->getPoseInRootFrame();
357 step.oriDiff = pCtrl.getOrientationDiff(
target);
360 ikSteps.emplace_back(
step);
368 float infNorm = vec.lpNorm<Eigen::Infinity>();
369 if (infNorm > maxValue)
371 vec = vec / infNorm * maxValue;
377 const VirtualRobot::RobotNodeSetPtr& rns) :
378 rns(rns),
target(rns->getJointValuesEigen()), weight(
Eigen::VectorXf::Zero(rns->getSize()))
383 const VirtualRobot::RobotNodeSetPtr& rns,
384 const Eigen::VectorXf&
target,
385 const Eigen::VectorXf& weight) :
394 this->weight(
index) = weight;
400 int index = rns->getRobotNodeIndex(jointName);
403 throw LocalException(
"RobotNodeSet has no joint ") << jointName;
413 int index = rns->getRobotNodeIndex(rn);
416 throw LocalException(
"RobotNodeSet has no joint ") << rn->getName();
429 return (
target - rns->getJointValuesEigen()).cwiseProduct(weight);
433 const VirtualRobot::RobotNodeSetPtr& rns) :
434 rns(rns), weight(
Eigen::VectorXf::Constant(rns->getSize(), 1))
439 const VirtualRobot::RobotNodeSetPtr& rns,
440 const Eigen::VectorXf& weight) :
441 rns(rns), weight(weight)
448 this->weight(
index) = weight;
454 int index = rns->getRobotNodeIndex(jointName);
457 throw LocalException(
"RobotNodeSet has no joint ") << jointName;
459 setWeight(
index, weight);
466 int index = rns->getRobotNodeIndex(rn);
469 throw LocalException(
"RobotNodeSet has no joint ") << rn->getName();
471 setWeight(
index, weight);
478 for (
const VirtualRobot::RobotNodePtr& rn : rns->getAllRobotNodes())
480 setWeight(rn, weight);
492 Eigen::VectorXf r(rns->getSize());
493 for (
size_t i = 0; i < rns->getSize(); i++)
495 VirtualRobot::RobotNodePtr rn = rns->getNode(i);
496 if (rn->isLimitless())
502 float f = math::Helpers::ILerp(
503 rn->getJointLimitLo(), rn->getJointLimitHi(), rn->getJointValue());
504 r(i) = cos(f *
M_PI);
508 return r.cwiseProduct(weight);
514 return tcp->getPoseInRootFrame().inverse() *
target;
520 return (tcp->getPoseInRootFrame().inverse() *
target).topRightCorner<3, 1>();
526 return simox::math::delta_angle(tcp->getPoseInRootFrame(),
target);