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>
42 const VirtualRobot::RobotNodeSetPtr& rns,
43 const VirtualRobot::RobotNodePtr& tcp,
44 const VirtualRobot::JacobiProvider::InverseJacobiMethod invJacMethod,
45 bool considerJointLimits) :
46 rns(rns), _considerJointLimits(considerJointLimits)
49 ik.reset(
new VirtualRobot::DifferentialIK(
rns,
rns->getRobot()->getRootNode(), invJacMethod));
50 _tcp = tcp ? tcp :
rns->getTCP();
52 _cartesianMMRegularization = 100;
53 _cartesianRadianRegularization = 1;
54 _jointCosts = Eigen::VectorXf::Constant(
rns->getSize(), 1);
62 _jacobiWithCosts = Eigen::MatrixXf(
jacobi.rows(),
jacobi.cols());
63 for (
int r = 0; r <
jacobi.rows(); r++)
67 _jacobiWithCosts(r,
c) =
jacobi(r,
c) / _jointCosts(
c);
70 auto svd = Eigen::JacobiSVD(_jacobiWithCosts, Eigen::ComputeThinU | Eigen::ComputeThinV);
71 auto sv = svd.singularValues();
72 double minSigVal = sv(sv.rows() - 1, sv.cols() - 1);
73 double damping = minSigVal < 1e-2 ? 1e-2 : 1e-8;
74 ik->setDampedSvdLambda(damping);
76 ik->computePseudoInverseJacobianMatrix(_jacobiWithCosts,
ik->getJacobiRegularization(mode));
83 return calculate(cartesianVel, Eigen::VectorXf::Zero(0), mode);
108 float KpJointLimitAvoidanceScale,
111 Eigen::VectorXf nullspaceVel =
113 return calculate(cartesianVel, nullspaceVel, mode);
118 const Eigen::VectorXf& nullspaceVel,
122 calculateJacobis(mode);
125 Eigen::VectorXf nsv = Eigen::VectorXf::Zero(
rns->getSize());
127 if (nullspaceVel.rows() > 0)
131 Eigen::FullPivLU<Eigen::MatrixXf> lu_decomp(_jacobiWithCosts);
134 Eigen::MatrixXf nullspace = lu_decomp.kernel();
136 for (
int i = 0; i < nullspace.cols(); i++)
138 float squaredNorm = nullspace.col(i).squaredNorm();
140 if (squaredNorm > 1.0e-32f)
142 nsv += nullspace.col(i) * nullspace.col(i).dot(nullspaceVel) /
143 nullspace.col(i).squaredNorm();
149 if (_considerJointLimits)
151 clampJacobiAtJointLimits(mode, cartesianVel, _jacobiWithCosts, _inv);
155 Eigen::VectorXf jointVel = _inv * cartesianVel;
157 for (
int r = 0; r < jointVel.rows(); r++)
159 jointVel(r) = jointVel(r) / _jointCosts(r);
173 Eigen::VectorXf r(
rns->getSize());
174 for (
size_t i = 0; i <
rns->getSize(); i++)
176 VirtualRobot::RobotNodePtr rn =
rns->getNode(i);
177 if (rn->isLimitless())
184 rn->getJointLimitLo(), rn->getJointLimitHi(), rn->getJointValue());
185 r(i) = cos(f *
M_PI);
200 Eigen::VectorXf r(
rns->getSize());
201 for (
size_t i = 0; i <
rns->getSize(); i++)
203 VirtualRobot::RobotNodePtr rn =
rns->getNode(i);
205 if (rn->isLimitless() || margins(i) <= 0)
211 float lo = rn->getJointLimitLo();
212 float hi = rn->getJointLimitHi();
213 float range =
hi -
lo;
224 const Eigen::VectorXf& cartesianVel,
232 Eigen::VectorXf vel = cartesianVel.cwiseProduct(regularization);
239 float cartesianRadianRegularization)
241 _cartesianMMRegularization = cartesianMMRegularization;
242 _cartesianRadianRegularization = cartesianRadianRegularization;
249 Eigen::VectorXf regularization(6);
253 if (mode & VirtualRobot::IKSolver::X)
255 regularization(i++) = 1 / _cartesianMMRegularization;
258 if (mode & VirtualRobot::IKSolver::Y)
260 regularization(i++) = 1 / _cartesianMMRegularization;
263 if (mode & VirtualRobot::IKSolver::Z)
265 regularization(i++) = 1 / _cartesianMMRegularization;
270 regularization(i++) = 1 / _cartesianRadianRegularization;
271 regularization(i++) = 1 / _cartesianRadianRegularization;
272 regularization(i++) = 1 / _cartesianRadianRegularization;
274 return regularization.topRows(i);
278 CartesianVelocityController::clampJacobiAtJointLimits(
280 const Eigen::VectorXf& cartesianVel,
281 Eigen::MatrixXf& jacobi,
282 Eigen::MatrixXf& inv,
283 float jointLimitCheckAccuracy)
285 bool modifiedJacobi =
false;
287 Eigen::VectorXf jointVel = inv * cartesianVel;
288 size_t size =
rns->getSize();
290 for (
size_t i = 0; i < size; ++i)
292 auto& node =
rns->getNode(
static_cast<int>(i));
294 if (node->isLimitless() ||
302 if ((node->getJointValue() >= node->getJointLimitHigh() - jointLimitCheckAccuracy &&
304 (node->getJointValue() <= node->getJointLimitLow() + jointLimitCheckAccuracy &&
307 for (
int k = 0; k <
jacobi.rows(); ++k)
311 modifiedJacobi =
true;
316 auto svd = Eigen::JacobiSVD(
jacobi, Eigen::ComputeThinU | Eigen::ComputeThinV);
317 auto sv = svd.singularValues();
318 double minSigVal = sv(sv.rows() - 1, sv.cols() - 1);
319 double damping = minSigVal < 1e-2 ? 1e-2 : 1e-8;
320 ik->setDampedSvdLambda(damping);
321 inv =
ik->computePseudoInverseJacobianMatrix(
jacobi,
ik->getJacobiRegularization(mode));
325 return modifiedJacobi;
331 return _considerJointLimits;
337 _considerJointLimits =
value;
343 ARMARX_CHECK((
int)jointCosts.size() == _jointCosts.rows());
344 for (
size_t i = 0; i < jointCosts.size(); i++)
346 _jointCosts(i) = jointCosts.at(i);