1 |
|
|
// |
2 |
|
|
// Copyright (c) 2017 CNRS |
3 |
|
|
// |
4 |
|
|
// This file is part of tsid |
5 |
|
|
// tsid is free software: you can redistribute it |
6 |
|
|
// and/or modify it under the terms of the GNU Lesser General Public |
7 |
|
|
// License as published by the Free Software Foundation, either version |
8 |
|
|
// 3 of the License, or (at your option) any later version. |
9 |
|
|
// tsid is distributed in the hope that it will be |
10 |
|
|
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty |
11 |
|
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 |
|
|
// General Lesser Public License for more details. You should have |
13 |
|
|
// received a copy of the GNU Lesser General Public License along with |
14 |
|
|
// tsid If not, see |
15 |
|
|
// <http://www.gnu.org/licenses/>. |
16 |
|
|
// |
17 |
|
|
|
18 |
|
|
#ifndef __invdyn_math_utils_hpp__ |
19 |
|
|
#define __invdyn_math_utils_hpp__ |
20 |
|
|
|
21 |
|
|
#include "tsid/math/fwd.hpp" |
22 |
|
|
|
23 |
|
|
#include <pinocchio/spatial/se3.hpp> |
24 |
|
|
#include <pinocchio/spatial/explog.hpp> |
25 |
|
|
|
26 |
|
|
#include <iostream> |
27 |
|
|
#include <fstream> |
28 |
|
|
#include <vector> |
29 |
|
|
|
30 |
|
|
#define PRINT_VECTOR(a) \ |
31 |
|
|
std::cout << #a << "(" << a.rows() << "x" << a.cols() \ |
32 |
|
|
<< "): " << a.transpose().format(math::CleanFmt) << std::endl |
33 |
|
|
#define PRINT_MATRIX(a) \ |
34 |
|
|
std::cout << #a << "(" << a.rows() << "x" << a.cols() << "):\n" \ |
35 |
|
|
<< a.format(math::CleanFmt) << std::endl |
36 |
|
|
|
37 |
|
|
namespace tsid { |
38 |
|
|
template <typename T> |
39 |
|
460 |
std::string toString(const T& v) { |
40 |
✓✗ |
920 |
std::stringstream ss; |
41 |
✓✗ |
460 |
ss << v; |
42 |
✓✗ |
920 |
return ss.str(); |
43 |
|
|
} |
44 |
|
|
|
45 |
|
|
template <typename T> |
46 |
|
|
std::string toString(const std::vector<T>& v, |
47 |
|
|
const std::string separator = ", ") { |
48 |
|
|
std::stringstream ss; |
49 |
|
|
for (int i = 0; i < v.size() - 1; i++) ss << v[i] << separator; |
50 |
|
|
ss << v[v.size() - 1]; |
51 |
|
|
return ss.str(); |
52 |
|
|
} |
53 |
|
|
|
54 |
|
|
template <typename T, int n> |
55 |
|
|
std::string toString(const Eigen::MatrixBase<T>& v, |
56 |
|
|
const std::string separator = ", ") { |
57 |
|
|
if (v.rows() > v.cols()) return toString(v.transpose(), separator); |
58 |
|
|
std::stringstream ss; |
59 |
|
|
ss << v; |
60 |
|
|
return ss.str(); |
61 |
|
|
} |
62 |
|
|
} // namespace tsid |
63 |
|
|
|
64 |
|
|
namespace tsid { |
65 |
|
|
namespace math { |
66 |
|
|
static const Eigen::IOFormat CleanFmt(1, 0, ", ", "\n", "[", "]"); |
67 |
|
|
|
68 |
|
|
/** List of available parameters of IOFormat constructor: |
69 |
|
|
precision number of digits for floating point values, or one of the |
70 |
|
|
special constants StreamPrecision and FullPrecision. flags either |
71 |
|
|
0, or DontAlignCols, which allows to disable the alignment of columns, |
72 |
|
|
resulting in faster code. coeffSeparator string printed between two |
73 |
|
|
coefficients of the same row rowSeparator string printed between two rows |
74 |
|
|
rowPrefix string printed at the beginning of each row |
75 |
|
|
rowSuffix string printed at the end of each row |
76 |
|
|
matPrefix string printed at the beginning of the matrix |
77 |
|
|
matSuffix string printed at the end of the matrix */ |
78 |
|
|
static const Eigen::IOFormat matlabPrintFormat(Eigen::FullPrecision, |
79 |
|
|
Eigen::DontAlignCols, " ", ";\n", |
80 |
|
|
"", "", "[", "];"); |
81 |
|
|
|
82 |
|
|
/** |
83 |
|
|
* Convert the input SE3 object to a 7D vector of floats [X,Y,Z,Q1,Q2,Q3,Q4]. |
84 |
|
|
*/ |
85 |
|
|
void SE3ToXYZQUAT(const pinocchio::SE3& M, RefVector xyzQuat); |
86 |
|
|
|
87 |
|
|
/** |
88 |
|
|
* Convert the input SE3 object to a 12D vector of floats |
89 |
|
|
* [X,Y,Z,R11,R12,R13,R14,...]. |
90 |
|
|
*/ |
91 |
|
|
void SE3ToVector(const pinocchio::SE3& M, RefVector vec); |
92 |
|
|
|
93 |
|
|
void vectorToSE3(RefVector vec, pinocchio::SE3& M); |
94 |
|
|
|
95 |
|
|
void errorInSE3(const pinocchio::SE3& M, const pinocchio::SE3& Mdes, |
96 |
|
|
pinocchio::Motion& error); |
97 |
|
|
|
98 |
|
|
void solveWithDampingFromSvd(Eigen::JacobiSVD<Eigen::MatrixXd>& svd, |
99 |
|
|
ConstRefVector b, RefVector sol, |
100 |
|
|
double damping = 0.0); |
101 |
|
|
|
102 |
|
|
void svdSolveWithDamping(ConstRefMatrix A, ConstRefVector b, RefVector sol, |
103 |
|
|
double damping = 0.0); |
104 |
|
|
|
105 |
|
|
void pseudoInverse(ConstRefMatrix A, RefMatrix Apinv, double tolerance, |
106 |
|
|
unsigned int computationOptions = Eigen::ComputeThinU | |
107 |
|
|
Eigen::ComputeThinV); |
108 |
|
|
|
109 |
|
|
void pseudoInverse(ConstRefMatrix A, |
110 |
|
|
Eigen::JacobiSVD<Eigen::MatrixXd>& svdDecomposition, |
111 |
|
|
RefMatrix Apinv, double tolerance, |
112 |
|
|
unsigned int computationOptions); |
113 |
|
|
|
114 |
|
|
void pseudoInverse(ConstRefMatrix A, |
115 |
|
|
Eigen::JacobiSVD<Eigen::MatrixXd>& svdDecomposition, |
116 |
|
|
RefMatrix Apinv, double tolerance, double* nullSpaceBasisOfA, |
117 |
|
|
int& nullSpaceRows, int& nullSpaceCols, |
118 |
|
|
unsigned int computationOptions); |
119 |
|
|
|
120 |
|
|
void dampedPseudoInverse(ConstRefMatrix A, |
121 |
|
|
Eigen::JacobiSVD<Eigen::MatrixXd>& svdDecomposition, |
122 |
|
|
RefMatrix Apinv, double tolerance, |
123 |
|
|
double dampingFactor, |
124 |
|
|
unsigned int computationOptions = Eigen::ComputeThinU | |
125 |
|
|
Eigen::ComputeThinV, |
126 |
|
|
double* nullSpaceBasisOfA = 0, int* nullSpaceRows = 0, |
127 |
|
|
int* nullSpaceCols = 0); |
128 |
|
|
|
129 |
|
|
void nullSpaceBasisFromDecomposition( |
130 |
|
|
const Eigen::JacobiSVD<Eigen::MatrixXd>& svdDecomposition, double tolerance, |
131 |
|
|
double* nullSpaceBasisMatrix, int& rows, int& cols); |
132 |
|
|
|
133 |
|
|
void nullSpaceBasisFromDecomposition( |
134 |
|
|
const Eigen::JacobiSVD<Eigen::MatrixXd>& svdDecomposition, int rank, |
135 |
|
|
double* nullSpaceBasisMatrix, int& rows, int& cols); |
136 |
|
|
|
137 |
|
|
template <typename Derived> |
138 |
|
3780 |
inline bool isFinite(const Eigen::MatrixBase<Derived>& x) { |
139 |
|
3780 |
return ((x - x).array() == (x - x).array()).all(); |
140 |
|
|
} |
141 |
|
|
|
142 |
|
|
template <typename Derived> |
143 |
|
|
inline bool is_nan(const Eigen::MatrixBase<Derived>& x) { |
144 |
|
|
return ((x.array() == x.array())).all(); |
145 |
|
|
} |
146 |
|
|
|
147 |
|
|
/** |
148 |
|
|
* Write the specified matrix to a binary file with the specified name. |
149 |
|
|
*/ |
150 |
|
|
template <class Matrix> |
151 |
|
|
bool writeMatrixToFile(const std::string& filename, |
152 |
|
|
const Eigen::MatrixBase<Matrix>& matrix) { |
153 |
|
|
typedef typename Matrix::Index Index; |
154 |
|
|
typedef typename Matrix::Scalar Scalar; |
155 |
|
|
|
156 |
|
|
std::ofstream out(filename.c_str(), |
157 |
|
|
std::ios::out | std::ios::binary | std::ios::trunc); |
158 |
|
|
if (!out.is_open()) return false; |
159 |
|
|
Index rows = matrix.rows(), cols = matrix.cols(); |
160 |
|
|
out.write((char*)(&rows), sizeof(Index)); |
161 |
|
|
out.write((char*)(&cols), sizeof(Index)); |
162 |
|
|
out.write((char*)matrix.data(), rows * cols * sizeof(Scalar)); |
163 |
|
|
out.close(); |
164 |
|
|
return true; |
165 |
|
|
} |
166 |
|
|
|
167 |
|
|
/** |
168 |
|
|
* Read a matrix from the specified input binary file. |
169 |
|
|
*/ |
170 |
|
|
template <class Matrix> |
171 |
|
|
bool readMatrixFromFile(const std::string& filename, |
172 |
|
|
const Eigen::MatrixBase<Matrix>& matrix) { |
173 |
|
|
typedef typename Matrix::Index Index; |
174 |
|
|
typedef typename Matrix::Scalar Scalar; |
175 |
|
|
|
176 |
|
|
std::ifstream in(filename.c_str(), std::ios::in | std::ios::binary); |
177 |
|
|
if (!in.is_open()) return false; |
178 |
|
|
Index rows = 0, cols = 0; |
179 |
|
|
in.read((char*)(&rows), sizeof(Index)); |
180 |
|
|
in.read((char*)(&cols), sizeof(Index)); |
181 |
|
|
|
182 |
|
|
Eigen::MatrixBase<Matrix>& matrix_ = |
183 |
|
|
const_cast<Eigen::MatrixBase<Matrix>&>(matrix); |
184 |
|
|
|
185 |
|
|
matrix_.resize(rows, cols); |
186 |
|
|
in.read((char*)matrix_.data(), rows * cols * sizeof(Scalar)); |
187 |
|
|
in.close(); |
188 |
|
|
return true; |
189 |
|
|
} |
190 |
|
|
|
191 |
|
|
} // namespace math |
192 |
|
|
} // namespace tsid |
193 |
|
|
|
194 |
|
|
#endif // ifndef __invdyn_math_utils_hpp__ |