GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: include/dynacom/dyna_com.hpp Lines: 10 26 38.5 %
Date: 2022-12-19 14:14:12 Branches: 0 14 0.0 %

Line Branch Exec Source
1
/**
2
 * @file
3
 * @authors Nahuel Villa, Maximilien Naveau
4
 * @copyright Copyright (c) 2022 LAAS-CNRS, TOWARD, PAL_ROBOTICS
5
 *            License BSD-2
6
 *
7
 * @brief Class to perform inverse geometry on a biped robot.
8
 */
9
10
#ifndef DYNACOM_DYNACOM
11
#define DYNACOM_DYNACOM
12
13
// clang-format off
14
#include <Eigen/Dense>
15
#include "pinocchio/fwd.hpp"
16
#include "pinocchio/multibody/data.hpp"
17
#include "pinocchio/multibody/model.hpp"
18
#include "pinocchio/spatial/se3.hpp"
19
#include <map>
20
#include <memory>
21
#include "dynacom/contact6d.hpp"
22
// clang-format on
23
24
// @TODO: add abstract class contact and new implementation of it contactPoint.
25
// @TODO: implement method copy of contacts to be able to duplicate them easily.
26
// @TODO: In the getters uni_A, fria_A, uni_b, fri_b return only the active
27
// block.
28
// @TODO: change internaly the system of names by ids.
29
30
namespace dynacom {
31
32
struct DynaCoMSettings {
33
 public:
34
  /**
35
   * @brief This must contain either a valid path to the urdf file or the
36
   * content of this file in a string.
37
   */
38
  std::string urdf = "";
39
40
  friend std::ostream &operator<<(std::ostream &out,
41
                                  const DynaCoMSettings &obj) {
42
    out << "DynaCoMSettings:\n";
43
    out << "    urdf: " << obj.urdf << std::endl;
44
    return out;
45
  }
46
47
  friend bool operator==(const DynaCoMSettings &lhs,
48
                         const DynaCoMSettings &rhs) {
49
    bool test = true;
50
    test &= lhs.urdf == rhs.urdf;
51
    return test;
52
  }
53
};
54
55
class DynaCoM {
56
 public:
57
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
58
 private:
59
  DynaCoMSettings settings_;
60
  Eigen::Matrix2d S_;
61
  pinocchio::Model model_;
62
  pinocchio::Data data_;
63
  double mass_;
64
  double inf_ = std::numeric_limits<double>::infinity();
65
66
  // Lists of contacts
67
  // std::vector< std::shared_ptr<Contact6D> > known_contact6ds_;
68
  std::map<std::string, std::shared_ptr<Contact6D>> known_contact6ds_;
69
  std::vector<std::string> active_contact6ds_;
70
71
  // QP Matrices
72
  Eigen::MatrixXd unilaterality_A_;
73
  Eigen::VectorXd unilaterality_b_;
74
  Eigen::MatrixXd friction_A_;
75
  Eigen::VectorXd friction_b_;
76
  Eigen::VectorXd regularization_A_;
77
  Eigen::VectorXd regularization_b_;
78
  Eigen::Matrix<double, 6, -1> newton_euler_A_;
79
  Eigen::Matrix<double, 6, 1> newton_euler_b_;
80
81
  // variables for QP problem with proxsuite formulation
82
  //  Eigen::MatrixXd H_, , A_;
83
  //  Eigen::VectorXd g_, u_, l_;
84
  //  Eigen::Matrix<double, 6, 1> b_;
85
86
  // variables for QP problem with eiquadprog formulation
87
  Eigen::MatrixXd G_;            // matrix for quadratic cost
88
  Eigen::VectorXd g0_;           // linear part of the cost function
89
  Eigen::MatrixXd CE_, CI_, C_;  // constraints matrix
90
  Eigen::VectorXd ce0_, ci0_;    // constraints vector
91
92
  // variables for QP problem
93
  Eigen::VectorXd F_;
94
  Eigen::VectorXi activeSet_;
95
  size_t activeSetSize_;
96
97
  size_t cols_, uni_rows_, fri_rows_;
98
  // active sizes:
99
  size_t uni_i_, fri_i_, j_;
100
101
  // Internal variables:
102
  Eigen::Vector3d groundCoMForce_, groundCoMTorque_, CoPTorque_, weight_;
103
  Eigen::Vector3d acom_;
104
  Eigen::Vector2d cop_;
105
  Eigen::Vector3d dL_;
106
  Eigen::Vector3d L_;
107
  Eigen::Vector2d n_;
108
  std::vector<std::string>::iterator activeID_;
109
  std::map<std::string, std::shared_ptr<Contact6D>>::iterator knownID_;
110
111
  // for the CoP wrench
112
  pinocchio::SE3 oMso_, soMs_;
113
  Eigen::Matrix<double, 6, 6> Sz_, oXso_, soXs_;
114
115
  void addSizes(const std::shared_ptr<Contact6D> &contact);
116
  void removeSizes(const std::shared_ptr<Contact6D> &contact);
117
  void resizeMatrices();
118
  void buildMatrices(const Eigen::Vector3d &groundCoMForce,
119
                     const Eigen::Vector3d &groundCoMTorque,
120
                     const Eigen::Vector3d &CoM);
121
  void solveQP();
122
  void distribute();
123
124
  const Eigen::Matrix<double, 6, 6> toWorldCoPWrench(pinocchio::SE3 pose);
125
126
 public:
127
  DynaCoM();
128
  DynaCoM(const DynaCoMSettings settings);
129
  void initialize(const DynaCoMSettings settings);
130
131
  void computeDynamics(const Eigen::VectorXd &posture,
132
                       const Eigen::VectorXd &velocity,
133
                       const Eigen::VectorXd &acceleration,
134
                       const Eigen::Matrix<double, 6, 1> &externalWrench =
135
                           Eigen::Matrix<double, 6, 1>::Zero(),
136
                       bool flatHorizontalGround = true);
137
138
  void computeNL(const double &w, const Eigen::VectorXd &posture,
139
                 const Eigen::VectorXd &velocity,
140
                 const Eigen::VectorXd &acceleration,
141
                 const Eigen::Matrix<double, 6, 1> &externalWrench =
142
                     Eigen::Matrix<double, 6, 1>::Zero(),
143
                 bool flatHorizontalGround = true);
144
145
  void computeNL(const double &w);
146
147
  void addContact6d(const std::shared_ptr<Contact6D> &contact,
148
                    const std::string &name, const bool active = true);
149
  void removeContact6d(const std::string &name);
150
151
  void activateContact6d(const std::string &name);
152
  void deactivateContact6d(const std::string &name);
153
154
  void distributeForce(const Eigen::Vector3d &groundCoMForce,
155
                       const Eigen::Vector3d &groundCoMTorque,
156
                       const Eigen::Vector3d &CoM);
157
158
  // GETTERS
159
  /// @brief Please call computeDynamics first.
160
  const Eigen::Vector3d &getAMVariation() { return dL_; }
161
2
  const Eigen::Vector3d &getCoM() { return data_.com[0]; }
162
  const Eigen::Vector3d &getVCoM() { return data_.vcom[0]; }
163
  const Eigen::Vector3d &getACoM() { return acom_; }
164
  const Eigen::Vector3d &getAM() { return L_; }
165
502
  const Eigen::Vector2d &getCoP() { return cop_; }
166
  const Eigen::Vector2d &getNL() { return n_; }
167
1500
  const Eigen::Vector3d &getGroundCoMForce() { return groundCoMForce_; }
168
1000
  const Eigen::Vector3d &getGroundCoMTorque() { return groundCoMTorque_; }
169
6
  const std::vector<std::string> &getActiveContacts() {
170
6
    return active_contact6ds_;
171
  }
172
1011
  const std::shared_ptr<Contact6D> &getContact(std::string name) {
173
1011
    return known_contact6ds_[name];
174
  }
175
  const DynaCoMSettings &getSettings() { return settings_; }
176
533
  const pinocchio::Model &getModel() { return model_; }
177
514
  const pinocchio::Data &getData() { return data_; }
178
179
  const Eigen::MatrixXd uni_A() {
180
    return unilaterality_A_.block(0, 0, uni_i_, j_);
181
  }
182
  const Eigen::VectorXd uni_b() { return unilaterality_b_.segment(0, j_); }
183
  const Eigen::MatrixXd fri_A() { return friction_A_.block(0, 0, fri_i_, j_); }
184
  const Eigen::VectorXd fri_b() { return friction_b_.segment(0, j_); }
185
  const Eigen::VectorXd reg_A() { return regularization_A_.segment(0, j_); }
186
  const Eigen::VectorXd reg_b() { return regularization_b_.segment(0, j_); }
187
  const Eigen::Matrix<double, 6, -1> NE_A() {
188
    return newton_euler_A_.block(0, 0, 6, j_);
189
  }
190
  const Eigen::Matrix<double, 6, 1> &NE_b() { return newton_euler_b_; }
191
  const Eigen::VectorXd &allForces() { return F_; }
192
};
193
194
}  // namespace dynacom
195
196
#endif  // DYNACOM_DYNACOM