Drake
drakeUtil.h
Go to the documentation of this file.
1 #pragma once
2 
3 /*
4  * drakeUtil.h
5  *
6  * Created on: Jun 19, 2013
7  * Author: russt
8  */
9 
10 #include <stdexcept>
11 #include <vector>
12 #include <utility>
13 #include <Eigen/Core>
14 #include <Eigen/Dense>
15 #include <unordered_map>
16 
18 #include "drake/drakeUtil_export.h"
19 
20 template <typename Key, typename T>
22  std::unordered_map<Key, T, std::hash<Key>, std::equal_to<Key>,
23  Eigen::aligned_allocator<std::pair<Key const, T> > >;
24 
25 template <typename Derived>
26 inline void sizecheck(const Eigen::MatrixBase<Derived>& mat, size_t rows,
27  size_t cols) {
28  if ((mat.rows() != rows) || (mat.cols() != cols))
29  throw std::runtime_error(
30  "Wrong-sized matrix: Expected " + std::to_string(rows) + "-by-" +
31  std::to_string(cols) + " but got " + std::to_string(mat.rows()) +
32  "-by-" + std::to_string(mat.cols()));
33 }
34 
35 // note for if/when we split off all Matlab related stuff into a different file:
36 // this function is not Matlab related
37 // can only be used when the dimension information of the array is known at
38 // compile time
39 template <size_t Rows, size_t Cols, typename Derived>
40 void eigenToCArrayOfArrays(const Eigen::MatrixBase<Derived>& source,
41  double(&destination)[Rows][Cols]) {
42  if (Rows != source.rows())
43  throw std::runtime_error(
44  "Number of rows of source doesn't match destination");
45  if (Cols != source.cols())
46  throw std::runtime_error(
47  "Number of columns of source doesn't match destination");
48  for (size_t row = 0; row < Rows; ++row) {
49  for (size_t col = 0; col < Cols; ++col) {
50  destination[row][col] = source(row, col);
51  }
52  }
53 }
54 
55 // note for if/when we split off all Matlab related stuff into a different file:
56 // this function is not Matlab related
57 // can only be used when the dimension information of the array is known at
58 // compile time
59 template <size_t Size, typename Derived>
60 void eigenVectorToCArray(const Eigen::MatrixBase<Derived>& source,
61  double(&destination)[Size]) {
62  if (Size != source.size())
63  throw std::runtime_error("Size of source doesn't match destination");
64  for (size_t i = 0; i < Size; ++i) {
65  destination[i] = source(i);
66  }
67 }
68 
69 // note for if/when we split off all Matlab related stuff into a different file:
70 // this function is not Matlab related
71 template <typename Derived>
73  const Eigen::MatrixBase<Derived>& source,
74  std::vector<typename Derived::Scalar>& destination) {
75  DRAKE_ASSERT(source.rows() == 1 || source.cols() == 1);
76  destination.resize(static_cast<size_t>(source.size()));
77  for (Eigen::Index i = 0; i < source.size(); i++) {
78  destination[static_cast<size_t>(i)] = source(i);
79  }
80 }
81 
82 // note for if/when we split off all Matlab related stuff into a different file:
83 // this function is not Matlab related
84 template <typename Derived>
86  const Eigen::MatrixBase<Derived>& source,
87  std::vector<std::vector<typename Derived::Scalar> >& destination) {
88  destination.resize(source.rows());
89  for (Eigen::Index row = 0; row < source.rows(); ++row) {
90  auto& destination_row = destination[row];
91  destination_row.resize(source.cols());
92  for (Eigen::Index col = 0; col < source.cols(); ++col) {
93  destination_row[col] = source(row, col);
94  }
95  }
96 }
97 
98 template <typename T>
99 void addOffset(std::vector<T>& v, const T& offset) {
100  std::transform(v.begin(), v.end(), v.begin(),
101  std::bind2nd(std::plus<double>(), offset));
102 }
103 
104 DRAKEUTIL_EXPORT void baseZeroToBaseOne(std::vector<int>& vec);
105 
106 DRAKEUTIL_EXPORT double angleAverage(double theta1, double theta2);
107 
108 template <typename DerivedTorque, typename DerivedForce, typename DerivedNormal,
109  typename DerivedPoint>
110 DRAKEUTIL_EXPORT std::pair<Eigen::Vector3d, double> resolveCenterOfPressure(
111  const Eigen::MatrixBase<DerivedTorque>& torque,
112  const Eigen::MatrixBase<DerivedForce>& force,
113  const Eigen::MatrixBase<DerivedNormal>& normal,
114  const Eigen::MatrixBase<DerivedPoint>& point_on_contact_plane);
115 
116 // Based on the Matrix Sign Function method outlined in this paper:
117 // http://www.engr.iupui.edu/~skoskie/ECE684/Riccati_algorithms.pdf
118 template <typename DerivedA, typename DerivedB, typename DerivedQ,
119  typename DerivedR, typename DerivedX>
120 void care(Eigen::MatrixBase<DerivedA> const& A,
121  Eigen::MatrixBase<DerivedB> const& B,
122  Eigen::MatrixBase<DerivedQ> const& Q,
123  Eigen::MatrixBase<DerivedR> const& R,
124  Eigen::MatrixBase<DerivedX>& X) {
125  using namespace std;
126  using namespace Eigen;
127  const size_t n = A.rows();
128 
129  LLT<MatrixXd> R_cholesky(R);
130 
131  MatrixXd H(2 * n, 2 * n);
132  H << A, B* R_cholesky.solve(B.transpose()), Q, -A.transpose();
133 
134  MatrixXd Z = H;
135  MatrixXd Z_old;
136 
137  // these could be options
138  const double tolerance = 1e-9;
139  const double max_iterations = 100;
140 
141  double relative_norm;
142  size_t iteration = 0;
143 
144  const double p = static_cast<double>(Z.rows());
145 
146  do {
147  Z_old = Z;
148  // R. Byers. Solving the algebraic Riccati equation with the matrix sign
149  // function. Linear Algebra Appl., 85:267–279, 1987
150  // Added determinant scaling to improve convergence (converges in rough half
151  // the iterations with this)
152  double ck = pow(abs(Z.determinant()), -1.0 / p);
153  Z *= ck;
154  Z = Z - 0.5 * (Z - Z.inverse());
155  relative_norm = (Z - Z_old).norm();
156  iteration++;
157  } while (iteration < max_iterations && relative_norm > tolerance);
158 
159  MatrixXd W11 = Z.block(0, 0, n, n);
160  MatrixXd W12 = Z.block(0, n, n, n);
161  MatrixXd W21 = Z.block(n, 0, n, n);
162  MatrixXd W22 = Z.block(n, n, n, n);
163 
164  MatrixXd lhs(2 * n, n);
165  MatrixXd rhs(2 * n, n);
166  MatrixXd eye = MatrixXd::Identity(n, n);
167  lhs << W12, W22 + eye;
168  rhs << W11 + eye, W21;
169 
170  JacobiSVD<MatrixXd> svd(lhs, ComputeThinU | ComputeThinV);
171 
172  X = svd.solve(rhs);
173 }
174 
175 template <typename DerivedA, typename DerivedB, typename DerivedQ,
176  typename DerivedR, typename DerivedK, typename DerivedS>
177 void lqr(Eigen::MatrixBase<DerivedA> const& A,
178  Eigen::MatrixBase<DerivedB> const& B,
179  Eigen::MatrixBase<DerivedQ> const& Q,
180  Eigen::MatrixBase<DerivedR> const& R, Eigen::MatrixBase<DerivedK>& K,
181  Eigen::MatrixBase<DerivedS>& S) {
182  Eigen::LLT<Eigen::MatrixXd> R_cholesky(R);
183  care(A, B, Q, R, S);
184  K = R_cholesky.solve(B.transpose() * S);
185 }
DRAKEUTIL_EXPORT void baseZeroToBaseOne(std::vector< int > &vec)
Definition: drakeUtil.cpp:15
void eigenVectorToCArray(const Eigen::MatrixBase< Derived > &source, double(&destination)[Size])
Definition: drakeUtil.h:60
void sizecheck(const Eigen::MatrixBase< Derived > &mat, size_t rows, size_t cols)
Definition: drakeUtil.h:26
DRAKEUTIL_EXPORT std::pair< Eigen::Vector3d, double > resolveCenterOfPressure(const Eigen::MatrixBase< DerivedTorque > &torque, const Eigen::MatrixBase< DerivedForce > &force, const Eigen::MatrixBase< DerivedNormal > &normal, const Eigen::MatrixBase< DerivedPoint > &point_on_contact_plane)
Definition: drakeUtil.cpp:37
DRAKEUTIL_EXPORT double angleAverage(double theta1, double theta2)
Definition: drakeUtil.cpp:20
void eigenToStdVectorOfStdVectors(const Eigen::MatrixBase< Derived > &source, std::vector< std::vector< typename Derived::Scalar > > &destination)
Definition: drakeUtil.h:85
STL namespace.
FunctionalForm abs(FunctionalForm const &x)
Definition: functional_form.cc:183
Eigen::Matrix< FunctionalForm, 3, 2 > A
Definition: functional_form_test.cc:619
void eigenVectorToStdVector(const Eigen::MatrixBase< Derived > &source, std::vector< typename Derived::Scalar > &destination)
Definition: drakeUtil.h:72
double force
Definition: system_identification_test.cpp:212
std::unordered_map< Key, T, std::hash< Key >, std::equal_to< Key >, Eigen::aligned_allocator< std::pair< Key const, T > > > eigen_aligned_unordered_map
Definition: drakeUtil.h:23
#define DRAKE_ASSERT(condition)
DRAKE_ASSERT(condition) is similar to the built-in assert(condition) from the C++ system header <cas...
Definition: drake_assert.h:35
Provides Drake&#39;s assertion implementation.
std::string to_string(const Eigen::MatrixBase< Derived > &a)
Definition: testUtil.h:29
Eigen::Matrix< FunctionalForm, 2, 3 > B
Definition: functional_form_test.cc:620
void care(Eigen::MatrixBase< DerivedA > const &A, Eigen::MatrixBase< DerivedB > const &B, Eigen::MatrixBase< DerivedQ > const &Q, Eigen::MatrixBase< DerivedR > const &R, Eigen::MatrixBase< DerivedX > &X)
Definition: drakeUtil.h:120
void eigenToCArrayOfArrays(const Eigen::MatrixBase< Derived > &source, double(&destination)[Rows][Cols])
Definition: drakeUtil.h:40
void lqr(Eigen::MatrixBase< DerivedA > const &A, Eigen::MatrixBase< DerivedB > const &B, Eigen::MatrixBase< DerivedQ > const &Q, Eigen::MatrixBase< DerivedR > const &R, Eigen::MatrixBase< DerivedK > &K, Eigen::MatrixBase< DerivedS > &S)
Definition: drakeUtil.h:177
static MatrixXd Q
Definition: inverseKinSnoptBackend.cpp:50
void addOffset(std::vector< T > &v, const T &offset)
Definition: drakeUtil.h:99