31 #include <VirtualRobot/math/Helpers.h>
32 #include <VirtualRobot/Robot.h>
40 _considerJointLimits(considerJointLimits)
43 ik.reset(
new VirtualRobot::DifferentialIK(
rns,
rns->getRobot()->getRootNode(), invJacMethod));
44 _tcp = tcp ? tcp :
rns->getTCP();
46 _cartesianMMRegularization = 100;
47 _cartesianRadianRegularization = 1;
48 _jointCosts = Eigen::VectorXf::Constant(
rns->getSize(), 1);
55 _jacobiWithCosts = Eigen::MatrixXf(
jacobi.rows(),
jacobi.cols());
56 for (
int r = 0; r <
jacobi.rows(); r++)
60 _jacobiWithCosts(r,
c) =
jacobi(r,
c) / _jointCosts(
c);
63 auto svd = Eigen::JacobiSVD(_jacobiWithCosts, Eigen::ComputeThinU | Eigen::ComputeThinV);
64 auto sv = svd.singularValues();
65 double minSigVal = sv(sv.rows() - 1, sv.cols() - 1);
66 double damping = minSigVal < 1e-2 ? 1e-2 : 1e-8;
67 ik->setDampedSvdLambda(damping);
68 _inv =
ik->computePseudoInverseJacobianMatrix(_jacobiWithCosts,
ik->getJacobiRegularization(mode));
73 return calculate(cartesianVel, Eigen::VectorXf::Zero(0), mode);
99 return calculate(cartesianVel, nullspaceVel, mode);
105 calculateJacobis(mode);
108 Eigen::VectorXf nsv = Eigen::VectorXf::Zero(
rns->getSize());
110 if (nullspaceVel.rows() > 0)
114 Eigen::FullPivLU<Eigen::MatrixXf> lu_decomp(_jacobiWithCosts);
117 Eigen::MatrixXf nullspace = lu_decomp.kernel();
119 for (
int i = 0; i < nullspace.cols(); i++)
121 float squaredNorm = nullspace.col(i).squaredNorm();
123 if (squaredNorm > 1.0e-32f)
125 nsv += nullspace.col(i) * nullspace.col(i).dot(nullspaceVel) / nullspace.col(i).squaredNorm();
131 if (_considerJointLimits)
133 clampJacobiAtJointLimits(mode, cartesianVel, _jacobiWithCosts, _inv);
137 Eigen::VectorXf jointVel = _inv * cartesianVel;
139 for (
int r = 0; r < jointVel.rows(); r++)
141 jointVel(r) = jointVel(r) / _jointCosts(r);
154 Eigen::VectorXf r(
rns->getSize());
155 for (
size_t i = 0; i <
rns->getSize(); i++)
157 VirtualRobot::RobotNodePtr rn =
rns->getNode(i);
158 if (rn->isLimitless())
165 r(i) = cos(f *
M_PI);
179 Eigen::VectorXf r(
rns->getSize());
180 for (
size_t i = 0; i <
rns->getSize(); i++)
182 VirtualRobot::RobotNodePtr rn =
rns->getNode(i);
184 if (rn->isLimitless() || margins(i) <= 0)
190 float lo = rn->getJointLimitLo();
191 float hi = rn->getJointLimitHi();
192 float range =
hi -
lo;
207 Eigen::VectorXf vel = cartesianVel.cwiseProduct(regularization);
215 _cartesianMMRegularization = cartesianMMRegularization;
216 _cartesianRadianRegularization = cartesianRadianRegularization;
221 Eigen::VectorXf regularization(6);
225 if (mode & VirtualRobot::IKSolver::X)
227 regularization(i++) = 1 / _cartesianMMRegularization;
230 if (mode & VirtualRobot::IKSolver::Y)
232 regularization(i++) = 1 / _cartesianMMRegularization;
235 if (mode & VirtualRobot::IKSolver::Z)
237 regularization(i++) = 1 / _cartesianMMRegularization;
242 regularization(i++) = 1 / _cartesianRadianRegularization;
243 regularization(i++) = 1 / _cartesianRadianRegularization;
244 regularization(i++) = 1 / _cartesianRadianRegularization;
246 return regularization.topRows(i);
249 bool CartesianVelocityController::clampJacobiAtJointLimits(
VirtualRobot::IKSolver::CartesianSelection mode,
const Eigen::VectorXf& cartesianVel, Eigen::MatrixXf& jacobi, Eigen::MatrixXf& inv,
float jointLimitCheckAccuracy)
251 bool modifiedJacobi =
false;
253 Eigen::VectorXf jointVel = inv * cartesianVel;
254 size_t size =
rns->getSize();
256 for (
size_t i = 0; i < size; ++i)
258 auto& node =
rns->getNode(
static_cast<int>(i));
260 if (node->isLimitless() ||
267 if ((node->getJointValue() >= node->getJointLimitHigh() - jointLimitCheckAccuracy && jointVel(i) > 0)
268 || (node->getJointValue() <= node->getJointLimitLow() + jointLimitCheckAccuracy && jointVel(i) < 0))
270 for (
int k = 0; k <
jacobi.rows(); ++k)
274 modifiedJacobi =
true;
279 auto svd = Eigen::JacobiSVD(
jacobi, Eigen::ComputeThinU | Eigen::ComputeThinV);
280 auto sv = svd.singularValues();
281 double minSigVal = sv(sv.rows() - 1, sv.cols() - 1);
282 double damping = minSigVal < 1e-2 ? 1e-2 : 1e-8;
283 ik->setDampedSvdLambda(damping);
284 inv =
ik->computePseudoInverseJacobianMatrix(
jacobi,
ik->getJacobiRegularization(mode));
288 return modifiedJacobi;
293 return _considerJointLimits;
298 _considerJointLimits =
value;
303 ARMARX_CHECK((
int)jointCosts.size() == _jointCosts.rows());
304 for (
size_t i = 0; i < jointCosts.size(); i++)
306 _jointCosts(i) = jointCosts.at(i);