25 xyzQuat.size() == 7,
"The size of the xyzQuat vector needs to equal 7");
26 xyzQuat.head<3>() = M.translation();
27 xyzQuat.tail<4>() = Eigen::Quaterniond(M.rotation()).coeffs();
32 vec.size() == 12,
"The size of the vec vector needs to equal 12");
33 vec.head<3>() = M.translation();
34 typedef Eigen::Matrix<double, 9, 1> Vector9;
35 vec.tail<9>() = Eigen::Map<const Vector9>(&M.rotation()(0), 9);
40 "vec needs to contain 12 rows");
41 M.translation(vec.head<3>());
42 typedef Eigen::Matrix<double, 3, 3> Matrix3;
43 M.rotation(Eigen::Map<const Matrix3>(&vec(3), 3, 3));
51 error.
linear() = M_err.translation();
57 assert(svd.rows() == b.size());
58 const double d2 = damping *
damping;
59 const long int nzsv = svd.nonzeroSingularValues();
60 Eigen::VectorXd tmp(svd.cols());
61 tmp.noalias() = svd.matrixU().leftCols(nzsv).adjoint() *
b;
63 for (
long int i = 0;
i < nzsv;
i++) {
64 sv = svd.singularValues()(
i);
65 tmp(
i) *= sv / (sv * sv + d2);
67 sol = svd.matrixV().leftCols(nzsv) * tmp;
75 assert(A.rows() == b.size());
76 Eigen::JacobiSVD<Eigen::MatrixXd> svd(A.rows(), A.cols());
77 svd.compute(A, Eigen::ComputeThinU | Eigen::ComputeThinV);
83 unsigned int computationOptions)
86 Eigen::JacobiSVD<Eigen::MatrixXd> svdDecomposition(A.rows(), A.cols());
87 pseudoInverse(A, svdDecomposition, Apinv, tolerance, computationOptions);
91 Eigen::JacobiSVD<Eigen::MatrixXd> &svdDecomposition,
93 unsigned int computationOptions) {
94 using namespace Eigen;
95 int nullSpaceRows = -1, nullSpaceCols = -1;
96 pseudoInverse(A, svdDecomposition, Apinv, tolerance, (
double *)0,
97 nullSpaceRows, nullSpaceCols, computationOptions);
101 Eigen::JacobiSVD<Eigen::MatrixXd> &svdDecomposition,
102 RefMatrix Apinv,
double tolerance,
double *nullSpaceBasisOfA,
103 int &nullSpaceRows,
int &nullSpaceCols,
104 unsigned int computationOptions) {
105 using namespace Eigen;
107 if (computationOptions == 0)
109 svdDecomposition.compute(A, computationOptions);
111 JacobiSVD<MatrixXd>::SingularValuesType singularValues =
112 svdDecomposition.singularValues();
113 long int singularValuesSize = singularValues.size();
115 for (
long int idx = 0; idx < singularValuesSize; idx++) {
116 if (tolerance > 0 && singularValues(idx) > tolerance) {
117 singularValues(idx) = 1.0 / singularValues(idx);
120 singularValues(idx) = 0.0;
125 Apinv = svdDecomposition.matrixV().leftCols(singularValuesSize) *
126 singularValues.asDiagonal() *
127 svdDecomposition.matrixU().leftCols(singularValuesSize).adjoint();
129 if (nullSpaceBasisOfA && (computationOptions & ComputeFullV)) {
132 nullSpaceRows, nullSpaceCols);
137 Eigen::JacobiSVD<Eigen::MatrixXd> &svdDecomposition,
139 double dampingFactor,
unsigned int computationOptions,
140 double *nullSpaceBasisOfA,
int *nullSpaceRows,
141 int *nullSpaceCols) {
142 using namespace Eigen;
144 if (computationOptions == 0)
146 svdDecomposition.compute(A, computationOptions);
148 JacobiSVD<MatrixXd>::SingularValuesType singularValues =
149 svdDecomposition.singularValues();
153 const long int singularValuesSize = singularValues.size();
154 const double d2 = dampingFactor * dampingFactor;
156 for (
int idx = 0; idx < singularValuesSize; idx++) {
157 if (singularValues(idx) > tolerance) rank++;
158 singularValues(idx) = singularValues(idx) /
159 ((singularValues(idx) * singularValues(idx)) + d2);
163 Apinv = svdDecomposition.matrixV().leftCols(singularValuesSize) *
164 singularValues.asDiagonal() *
165 svdDecomposition.matrixU().leftCols(singularValuesSize).adjoint();
167 if (nullSpaceBasisOfA && nullSpaceRows && nullSpaceCols &&
168 (computationOptions & ComputeFullV)) {
171 *nullSpaceRows, *nullSpaceCols);
176 const Eigen::JacobiSVD<Eigen::MatrixXd> &svdDecomposition,
double tolerance,
177 double *nullSpaceBasisMatrix,
int &rows,
int &cols) {
178 using namespace Eigen;
179 JacobiSVD<MatrixXd>::SingularValuesType singularValues =
180 svdDecomposition.singularValues();
182 for (
int idx = 0; idx < singularValues.size(); idx++) {
183 if (tolerance > 0 && singularValues(idx) > tolerance) {
192 const Eigen::JacobiSVD<Eigen::MatrixXd> &svdDecomposition,
int rank,
193 double *nullSpaceBasisMatrix,
int &rows,
int &cols) {
194 using namespace Eigen;
195 const MatrixXd &vMatrix = svdDecomposition.matrixV();
197 rows = (int)vMatrix.cols();
198 cols = (int)vMatrix.cols() - rank;
199 Map<MatrixXd> map(nullSpaceBasisMatrix, rows, cols);
200 map = vMatrix.rightCols(vMatrix.cols() - rank);
Eigen::Matrix< typename Matrix3Like::Scalar, 3, 1, PINOCCHIO_EIGEN_PLAIN_TYPE(Matrix3Like)::Options > log3(const Eigen::MatrixBase< Matrix3Like > &R, typename Matrix3Like::Scalar &theta)
Eigen::Ref< Vector > RefVector
const Eigen::Ref< const Matrix > ConstRefMatrix
void SE3ToVector(const pinocchio::SE3 &M, RefVector vec)
void solveWithDampingFromSvd(Eigen::JacobiSVD< Eigen::MatrixXd > &svd, ConstRefVector b, RefVector sol, double damping=0.0)
void svdSolveWithDamping(ConstRefMatrix A, ConstRefVector b, RefVector sol, double damping=0.0)
ConstLinearType linear() const
void SE3ToXYZQUAT(const pinocchio::SE3 &M, RefVector xyzQuat)
ConstAngularType angular() const
void nullSpaceBasisFromDecomposition(const Eigen::JacobiSVD< Eigen::MatrixXd > &svdDecomposition, double tolerance, double *nullSpaceBasisMatrix, int &rows, int &cols)
void errorInSE3(const pinocchio::SE3 &M, const pinocchio::SE3 &Mdes, pinocchio::Motion &error)
const Eigen::Ref< const Vector > ConstRefVector
void dampedPseudoInverse(ConstRefMatrix A, Eigen::JacobiSVD< Eigen::MatrixXd > &svdDecomposition, RefMatrix Apinv, double tolerance, double dampingFactor, unsigned int computationOptions=Eigen::ComputeThinU|Eigen::ComputeThinV, double *nullSpaceBasisOfA=0, int *nullSpaceRows=0, int *nullSpaceCols=0)
void vectorToSE3(RefVector vec, pinocchio::SE3 &M)
void pseudoInverse(ConstRefMatrix A, RefMatrix Apinv, double tolerance, unsigned int computationOptions=Eigen::ComputeThinU|Eigen::ComputeThinV)
Eigen::Ref< Matrix > RefMatrix
#define PINOCCHIO_CHECK_INPUT_ARGUMENT(...)