25 #include <VirtualRobot/Robot.h>
27 #include <VirtualRobot/math/Helpers.h>
28 #include <VirtualRobot/RobotNodeSet.h>
29 #include <VirtualRobot/Nodes/RobotNode.h>
37 ik.reset(
new VirtualRobot::DifferentialIK(rns, rns->getRobot()->getRootNode(), VirtualRobot::JacobiProvider::eSVDDamped));
42 targets.emplace_back(
target);
54 nullspaceGradients.emplace_back(gradient);
73 for (VirtualRobot::RobotNodePtr rn : rns->getAllRobotNodes())
75 if (rn->isLimitless())
81 rn->setJointValue((rn->getJointLimitHi() + rn->getJointLimitLo()) / 2);
90 s.cols = rns->getSize();
97 s.jointRegularization = Eigen::VectorXf::Zero(
s.cols);
98 for (
size_t i = 0; i < rns->getSize(); i++)
103 s.cartesianRegularization = Eigen::VectorXf::Zero(
s.rows);
110 target->jacobi = Eigen::MatrixXf::Zero(h,
s.cols);
118 s.jointValues = rns->getJointValuesEigen();
120 for (
size_t i = 0; i <= params.
steps; i++)
125 bool allReached =
true;
141 for (
size_t i = 0; i < rns->getSize(); i++)
143 VirtualRobot::RobotNodePtr rn = rns->getNode(i);
144 if (rn->isLimitless())
150 result.
jointLimitMargins(i) =
std::min(rn->getJointValue() - rn->getJointLimitLo(), rn->getJointLimitHi() - rn->getJointValue());
160 Eigen::FullPivLU<Eigen::MatrixXf> lu_decomp(jacobi);
161 Eigen::MatrixXf nullspaceLU = lu_decomp.kernel();
168 int rows = jacobi.rows();
169 int cols = jacobi.cols();
170 Eigen::JacobiSVD<Eigen::MatrixXf> svd(jacobi, Eigen::ComputeFullU | Eigen::ComputeFullV);
177 Eigen::MatrixXf V = svd.matrixV();
178 Eigen::MatrixXf nullspaceSVD = V.block(0, rows, cols, cols - rows);
185 s.jacobi = Eigen::MatrixXf::Zero(
s.rows,
s.cols);
186 s.invJac = Eigen::MatrixXf::Zero(
s.cols,
s.rows);
188 Eigen::VectorXf cartesianVel = Eigen::VectorXf::Zero(
s.rows);
195 s.jacobi.block(row, 0, h,
s.cols) =
target->jacobi;
198 cartesianVel.block(row, 0, h, 1) =
cv;
203 step.tcpPose =
target->tcp->getPoseInRootFrame();
217 for (
int row = 0; row <
s.rows; row++)
219 s.jacobi.block(row, 0, 1,
s.cols) =
s.jacobi.block(row, 0, 1,
s.cols).cwiseProduct(
s.jointRegularization.transpose());
226 ik->updatePseudoInverseJacobianMatrix(
s.invJac,
s.jacobi, 0,
s.cartesianRegularization);
228 Eigen::VectorXf nullspaceVel = Eigen::VectorXf::Zero(
s.cols);
232 Eigen::VectorXf nsgrad = nsGradient->kP * nsGradient->getGradient(params);
234 nullspaceVel += nsgrad;
244 Eigen::JacobiSVD<Eigen::MatrixXf> svd(
s.jacobi, Eigen::ComputeFullU | Eigen::ComputeFullV);
245 Eigen::MatrixXf V = svd.matrixV();
246 Eigen::MatrixXf nullspaceSVD = V.block(0,
s.rows,
s.cols,
s.cols -
s.rows);
248 s.nullspace = nullspaceSVD;
250 Eigen::VectorXf nsv = Eigen::VectorXf::Zero(
s.cols);
251 for (
int i = 0; i <
s.nullspace.cols(); i++)
253 float squaredNorm =
s.nullspace.col(i).squaredNorm();
255 if (squaredNorm > 1.0e-32f)
257 nsv +=
s.nullspace.col(i) *
s.nullspace.col(i).dot(nullspaceVel) /
s.nullspace.col(i).squaredNorm();
261 Eigen::VectorXf jv =
s.invJac * cartesianVel;
267 jv = jv.cwiseProduct(
s.jointRegularization);
271 Eigen::VectorXf newJointValues =
s.jointValues + jv;
280 rns->setJointValues(newJointValues);
281 s.jointValues = newJointValues;
292 case VirtualRobot::IKSolver::CartesianSelection::All:
295 throw LocalException(
"mode not supported: ") << mode;
303 jacobi = Eigen::MatrixXf::Zero(0, 0);
307 : tcp(tcp),
target(
target), mode(mode), pCtrl(tcp), vCtrl(rns, tcp)
319 Eigen::VectorXf
cv = pCtrl.calculate(
target, mode);
320 Eigen::VectorXf jv = vCtrl.calculate(
cv, mode);
324 step.tcpPose = tcp->getPoseInRootFrame();
326 step.oriDiff = pCtrl.getOrientationDiff(
target);
329 ikSteps.emplace_back(
step);
336 float infNorm = vec.lpNorm<Eigen::Infinity>();
337 if (infNorm > maxValue)
339 vec = vec / infNorm * maxValue;
345 : rns(rns),
target(rns->getJointValuesEigen()), weight(
Eigen::VectorXf::Zero(rns->getSize()))
359 this->weight(
index) = weight;
364 int index = rns->getRobotNodeIndex(jointName);
367 throw LocalException(
"RobotNodeSet has no joint ") << jointName;
374 int index = rns->getRobotNodeIndex(rn);
377 throw LocalException(
"RobotNodeSet has no joint ") << rn->getName();
389 return (
target - rns->getJointValuesEigen()).cwiseProduct(weight);
393 : rns(rns), weight(
Eigen::VectorXf::Constant(rns->getSize(), 1))
399 : rns(rns), weight(weight)
406 this->weight(
index) = weight;
411 int index = rns->getRobotNodeIndex(jointName);
414 throw LocalException(
"RobotNodeSet has no joint ") << jointName;
416 setWeight(
index, weight);
421 int index = rns->getRobotNodeIndex(rn);
424 throw LocalException(
"RobotNodeSet has no joint ") << rn->getName();
426 setWeight(
index, weight);
431 for (
const VirtualRobot::RobotNodePtr& rn : rns->getAllRobotNodes())
433 setWeight(rn, weight);
444 Eigen::VectorXf r(rns->getSize());
445 for (
size_t i = 0; i < rns->getSize(); i++)
447 VirtualRobot::RobotNodePtr rn = rns->getNode(i);
448 if (rn->isLimitless())
454 float f = math::Helpers::ILerp(rn->getJointLimitLo(), rn->getJointLimitHi(), rn->getJointValue());
455 r(i) = cos(f *
M_PI);
459 return r.cwiseProduct(weight);