Rigid Body Dynamics Library
rbdl_mathutils.cc
Go to the documentation of this file.
1/*
2 * RBDL - Rigid Body Dynamics Library
3 * Copyright (c) 2011-2018 Martin Felis <martin@fysx.org>
4 *
5 * Licensed under the zlib license. See LICENSE for more details.
6 */
7
8#include <cmath>
9#include <limits>
10
11#include <iostream>
12#include <assert.h>
13
14#include <rbdl/rbdl_mathutils.h>
15#include <rbdl/Model.h>
16
17#include "rbdl/Logging.h"
18
19namespace RigidBodyDynamics {
20namespace Math {
21
22RBDL_DLLAPI Vector3d Vector3dZero (0., 0., 0.);
24 1., 0., 0.,
25 0., 1., 0.,
26 0., 0., 1
27 );
29 0., 0., 0.,
30 0., 0., 0.,
31 0., 0., 0.
32 );
33
34RBDL_DLLAPI SpatialVector SpatialVectorZero ( 0., 0., 0., 0., 0., 0.);
35
36#ifndef RBDL_USE_CASADI_MATH
37RBDL_DLLAPI bool LinSolveGaussElimPivot (MatrixNd A, VectorNd b, VectorNd &x) {
38 x = VectorNd::Zero(x.size());
39
40 // We can only solve quadratic systems
41 assert (A.rows() == A.cols());
42
43 unsigned int n = A.rows();
44 unsigned int pi;
45
46 // the pivots
47 size_t *pivot = new size_t[n];
48
49 // temporary result vector which contains the pivoted result
50 VectorNd px(x);
51
52 unsigned int i,j,k;
53
54 for (i = 0; i < n; i++)
55 pivot[i] = i;
56
57 for (j = 0; j < n; j++) {
58 pi = j;
59 Scalar pv = fabs (A(j,pivot[j]));
60
61 // LOG << "j = " << j << " pv = " << pv << std::endl;
62 // find the pivot
63 for (k = j; k < n; k++) {
64 Scalar pt = fabs (A(j,pivot[k]));
65 if (pt > pv) {
66 pv = pt;
67 pi = k;
68 unsigned int p_swap = pivot[j];
69 pivot[j] = pivot[pi];
70 pivot[pi] = p_swap;
71 // LOG << "swap " << j << " with " << pi << std::endl;
72 // LOG << "j = " << j << " pv = " << pv << std::endl;
73 }
74 }
75
76 for (i = j + 1; i < n; i++) {
77 if (Scalar(fabs(A(j,pivot[j]))) <= Scalar(std::numeric_limits<double>::epsilon())) {
78 std::cerr << "Error: pivoting failed for matrix A = " << std::endl;
79 std::cerr << "A = " << std::endl << A << std::endl;
80 std::cerr << "b = " << b << std::endl;
81 }
82 // assert (fabs(A(j,pivot[j])) > std::numeric_limits<double>::epsilon());
83 Scalar d = A(i,pivot[j])/A(j,pivot[j]);
84
85 b[i] -= b[j] * d;
86
87 for (k = j; k < n; k++) {
88 A(i,pivot[k]) -= A(j,pivot[k]) * d;
89 }
90 }
91 }
92
93 // warning: i is an unsigned int, therefore a for loop of the
94 // form "for (i = n - 1; i >= 0; i--)" might end up in getting an invalid
95 // value for i!
96 i = n;
97 do {
98 i--;
99
100 for (j = i + 1; j < n; j++) {
101 px[i] += A(i,pivot[j]) * px[j];
102 }
103 px[i] = (b[i] - px[i]) / A(i,pivot[i]);
104
105 } while (i > 0);
106
107 // Unswapping
108 for (i = 0; i < n; i++) {
109 x[pivot[i]] = px[i];
110 }
111
112 /*
113 LOG << "A = " << std::endl << A << std::endl;
114 LOG << "b = " << b << std::endl;
115 LOG << "x = " << x << std::endl;
116 LOG << "pivot = " << pivot[0] << " " << pivot[1] << " " << pivot[2] << std::endl;
117 std::cout << LogOutput.str() << std::endl;
118 */
119
120 delete[] pivot;
121
122 return true;
123}
124#endif
125
127 SpatialMatrix &dest,
128 unsigned int row,
129 unsigned int col,
130 const Matrix3d &matrix) {
131 assert (row < 2 && col < 2);
132
133 dest(row*3,col*3) = matrix(0,0);
134 dest(row*3,col*3 + 1) = matrix(0,1);
135 dest(row*3,col*3 + 2) = matrix(0,2);
136
137 dest(row*3 + 1,col*3) = matrix(1,0);
138 dest(row*3 + 1,col*3 + 1) = matrix(1,1);
139 dest(row*3 + 1,col*3 + 2) = matrix(1,2);
140
141 dest(row*3 + 2,col*3) = matrix(2,0);
142 dest(row*3 + 2,col*3 + 1) = matrix(2,1);
143 dest(row*3 + 2,col*3 + 2) = matrix(2,2);
144}
145
146#ifndef RBDL_USE_CASADI_MATH
148 const SpatialMatrix &matrix_a,
149 const SpatialMatrix &matrix_b,
150 Scalar epsilon) {
151 assert (epsilon >= Scalar(0.));
152 unsigned int i, j;
153
154 for (i = 0; i < 6; i++) {
155 for (j = 0; j < 6; j++) {
156 if (Scalar(fabs(matrix_a(i,j) - matrix_b(i,j))) >= Scalar(epsilon)) {
157 std::cerr << "Expected:"
158 << std::endl << matrix_a << std::endl
159 << "but was" << std::endl
160 << matrix_b << std::endl;
161 return false;
162 }
163 }
164 }
165
166 return true;
167}
168
170 const SpatialVector &vector_a,
171 const SpatialVector &vector_b,
172 Scalar epsilon) {
173 assert (epsilon >= Scalar(0.));
174 unsigned int i;
175
176 for (i = 0; i < 6; i++) {
177 if (Scalar(fabs(vector_a[i] - vector_b[i])) >= Scalar(epsilon)) {
178 std::cerr << "Expected:"
179 << std::endl << vector_a << std::endl
180 << "but was" << std::endl
181 << vector_b << std::endl;
182 return false;
183 }
184 }
185
186 return true;
187}
188#endif
189
191 const Matrix3d &inertia,
192 Scalar mass,
193 const Vector3d &com) {
194 Matrix3d com_cross = VectorCrossMatrix (com);
195
196 return inertia + mass * com_cross * com_cross.transpose();
197}
198
199RBDL_DLLAPI SpatialMatrix Xtrans_mat (const Vector3d &r) {
200 return SpatialMatrix (
201 1., 0., 0., 0., 0., 0.,
202 0., 1., 0., 0., 0., 0.,
203 0., 0., 1., 0., 0., 0.,
204 0., r[2], -r[1], 1., 0., 0.,
205 -r[2], 0., r[0], 0., 1., 0.,
206 r[1], -r[0], 0., 0., 0., 1.
207 );
208}
209
210RBDL_DLLAPI SpatialMatrix Xrotx_mat (const Scalar &xrot) {
211 Scalar s, c;
212 s = sin (xrot);
213 c = cos (xrot);
214
215 return SpatialMatrix(
216 1., 0., 0., 0., 0., 0.,
217 0., c, s, 0., 0., 0.,
218 0., -s, c, 0., 0., 0.,
219 0., 0., 0., 1., 0., 0.,
220 0., 0., 0., 0., c, s,
221 0., 0., 0., 0., -s, c
222 );
223}
224
225RBDL_DLLAPI SpatialMatrix Xroty_mat (const Scalar &yrot) {
226 Scalar s, c;
227 s = sin (yrot);
228 c = cos (yrot);
229
230 return SpatialMatrix(
231 c, 0., -s, 0., 0., 0.,
232 0., 1., 0., 0., 0., 0.,
233 s, 0., c, 0., 0., 0.,
234 0., 0., 0., c, 0., -s,
235 0., 0., 0., 0., 1., 0.,
236 0., 0., 0., s, 0., c
237 );
238}
239
240RBDL_DLLAPI SpatialMatrix Xrotz_mat (const Scalar &zrot) {
241 Scalar s, c;
242 s = sin (zrot);
243 c = cos (zrot);
244
245 return SpatialMatrix(
246 c, s, 0., 0., 0., 0.,
247 -s, c, 0., 0., 0., 0.,
248 0., 0., 1., 0., 0., 0.,
249 0., 0., 0., c, s, 0.,
250 0., 0., 0., -s, c, 0.,
251 0., 0., 0., 0., 0., 1.
252 );
253}
254
256 const Vector3d &displacement,
257 const Vector3d &zyx_euler) {
258 return Xrotz_mat(zyx_euler[0]) * Xroty_mat(zyx_euler[1]) * Xrotx_mat(zyx_euler[2]) * Xtrans_mat(displacement);
259}
260
261RBDL_DLLAPI void SparseFactorizeLTL (Model &model, Math::MatrixNd &H) {
262 for (unsigned int i = 0; i < model.qdot_size; i++) {
263 for (unsigned int j = i + 1; j < model.qdot_size; j++) {
264 H(i,j) = 0.;
265 }
266 }
267
268 for (unsigned int k = model.qdot_size; k > 0; k--) {
269 H(k - 1,k - 1) = sqrt (H(k - 1,k - 1));
270 unsigned int i = model.lambda_q[k];
271 while (i != 0) {
272 H(k - 1,i - 1) = H(k - 1,i - 1) / H(k - 1,k - 1);
273 i = model.lambda_q[i];
274 }
275
276 i = model.lambda_q[k];
277 while (i != 0) {
278 unsigned int j = i;
279 while (j != 0) {
280 H(i - 1,j - 1) = H(i - 1,j - 1) - H(k - 1,i - 1) * H(k - 1, j - 1);
281 j = model.lambda_q[j];
282 }
283 i = model.lambda_q[i];
284 }
285 }
286}
287
288RBDL_DLLAPI void SparseMultiplyHx (Model &model, Math::MatrixNd &L) {
289 assert (0 && !"Not yet implemented!");
290}
291
292RBDL_DLLAPI void SparseMultiplyLx (Model &model, Math::MatrixNd &L) {
293 assert (0 && !"Not yet implemented!");
294}
295
296RBDL_DLLAPI void SparseMultiplyLTx (Model &model, Math::MatrixNd &L) {
297 assert (0 && !"Not yet implemented!");
298}
299
300RBDL_DLLAPI void SparseSolveLx (Model &model, Math::MatrixNd &L, Math::VectorNd &x) {
301 for (unsigned int i = 1; i <= model.qdot_size; i++) {
302 unsigned int j = model.lambda_q[i];
303 while (j != 0) {
304 x[i - 1] = x[i - 1] - L(i - 1,j - 1) * x[j - 1];
305 j = model.lambda_q[j];
306 }
307 x[i - 1] = x[i - 1] / L(i - 1,i - 1);
308 }
309}
310
311RBDL_DLLAPI void SparseSolveLTx (Model &model, Math::MatrixNd &L, Math::VectorNd &x) {
312 for (unsigned int i = model.qdot_size; i > 0; i--) {
313 x[i - 1] = x[i - 1] / L(i - 1,i - 1);
314 unsigned int j = model.lambda_q[i];
315 while (j != 0) {
316 x[j - 1] = x[j - 1] - L(i - 1,j - 1) * x[i - 1];
317 j = model.lambda_q[j];
318 }
319 }
320}
321
322} /* Math */
323} /* RigidBodyDynamics */
unsigned int rows() const
Definition: MX_Xd_dynamic.h:95
unsigned int cols() const
Definition: MX_Xd_dynamic.h:99
unsigned int size() const
static MX_Xd_dynamic Zero(unsigned int nrows, unsigned int ncols=1)
Definition: MX_Xd_dynamic.h:52
SpatialMatrix_t SpatialMatrix
Definition: rbdl_math.h:62
RBDL_DLLAPI SpatialMatrix XtransRotZYXEuler(const Vector3d &displacement, const Vector3d &zyx_euler)
Creates a spatial transformation for given parameters.
RBDL_DLLAPI SpatialMatrix Xrotx_mat(const Scalar &xrot)
Creates a rotational transformation around the X-axis.
RBDL_DLLAPI void SpatialMatrixSetSubmatrix(SpatialMatrix &dest, unsigned int row, unsigned int col, const Matrix3d &matrix)
RBDL_DLLAPI void SparseMultiplyLx(Model &model, Math::MatrixNd &L)
RBDL_DLLAPI void SparseFactorizeLTL(Model &model, Math::MatrixNd &H)
RBDL_DLLAPI void SparseSolveLx(Model &model, Math::MatrixNd &L, Math::VectorNd &x)
RBDL_DLLAPI bool LinSolveGaussElimPivot(MatrixNd A, VectorNd b, VectorNd &x)
Solves a linear system using gaussian elimination with pivoting.
Matrix3d VectorCrossMatrix(const Vector3d &vector)
RBDL_DLLAPI bool SpatialVectorCompareEpsilon(const SpatialVector &vector_a, const SpatialVector &vector_b, Scalar epsilon)
RBDL_DLLAPI void SparseMultiplyHx(Model &model, Math::MatrixNd &L)
RBDL_DLLAPI void SparseSolveLTx(Model &model, Math::MatrixNd &L, Math::VectorNd &x)
RBDL_DLLAPI SpatialMatrix Xroty_mat(const Scalar &yrot)
Creates a rotational transformation around the Y-axis.
RBDL_DLLAPI void SparseMultiplyLTx(Model &model, Math::MatrixNd &L)
RBDL_DLLAPI Matrix3d parallel_axis(const Matrix3d &inertia, Scalar mass, const Vector3d &com)
Translates the inertia matrix to a new center.
RBDL_DLLAPI SpatialMatrix Xrotz_mat(const Scalar &zrot)
Creates a rotational transformation around the Z-axis.
RBDL_DLLAPI SpatialMatrix Xtrans_mat(const Vector3d &r)
Creates a transformation of a linear displacement.
RBDL_DLLAPI Matrix3d Matrix3dZero
RBDL_DLLAPI SpatialVector SpatialVectorZero(0., 0., 0., 0., 0., 0.)
RBDL_DLLAPI Matrix3d Matrix3dIdentity
RBDL_DLLAPI Vector3d Vector3dZero
RBDL_DLLAPI bool SpatialMatrixCompareEpsilon(const SpatialMatrix &matrix_a, const SpatialMatrix &matrix_b, Scalar epsilon)
MX_Xd_dynamic fabs(const MX_Xd_dynamic &m)
Definition: MX_Xd_utils.h:371
MX_Xd_scalar sqrt(const MX_Xd_scalar &x)
Definition: MX_Xd_utils.h:342
MX_Xd_scalar cos(const MX_Xd_scalar &x)
Definition: MX_Xd_utils.h:351
MX_Xd_scalar sin(const MX_Xd_scalar &x)
Definition: MX_Xd_utils.h:345