GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: include/crocoddyl/multibody/actuations/floating-base.hpp Lines: 38 40 95.0 %
Date: 2024-02-13 11:12:33 Branches: 44 138 31.9 %

Line Branch Exec Source
1
///////////////////////////////////////////////////////////////////////////////
2
// BSD 3-Clause License
3
//
4
// Copyright (C) 2019-2022, LAAS-CNRS, University of Edinburgh,
5
//                          Heriot-Watt University
6
// Copyright note valid unless otherwise stated in individual files.
7
// All rights reserved.
8
///////////////////////////////////////////////////////////////////////////////
9
10
#ifndef CROCODDYL_MULTIBODY_ACTUATIONS_FLOATING_BASE_HPP_
11
#define CROCODDYL_MULTIBODY_ACTUATIONS_FLOATING_BASE_HPP_
12
13
#include "crocoddyl/core/actuation-base.hpp"
14
#include "crocoddyl/core/utils/exception.hpp"
15
#include "crocoddyl/multibody/fwd.hpp"
16
#include "crocoddyl/multibody/states/multibody.hpp"
17
18
namespace crocoddyl {
19
20
/**
21
 * @brief Floating-base actuation model
22
 *
23
 * It considers the first joint, defined in the Pinocchio model, as the
24
 * floating-base joints. Then, this joint (that might have various DoFs) is
25
 * unactuated.
26
 *
27
 * The main computations are carrying out in `calc`, and `calcDiff`, where the
28
 * former computes actuation signal \f$\mathbf{a}\f$ from a given joint-torque
29
 * input \f$\mathbf{u}\f$ and state point \f$\mathbf{x}\f$, and the latter
30
 * computes the Jacobians of the actuation-mapping function. Note that
31
 * `calcDiff` requires to run `calc` first.
32
 *
33
 * \sa `ActuationModelAbstractTpl`, `calc()`, `calcDiff()`, `createData()`
34
 */
35
template <typename _Scalar>
36
class ActuationModelFloatingBaseTpl
37
    : public ActuationModelAbstractTpl<_Scalar> {
38
 public:
39
  typedef _Scalar Scalar;
40
  typedef MathBaseTpl<Scalar> MathBase;
41
  typedef ActuationModelAbstractTpl<Scalar> Base;
42
  typedef ActuationDataAbstractTpl<Scalar> Data;
43
  typedef StateMultibodyTpl<Scalar> StateMultibody;
44
  typedef typename MathBase::VectorXs VectorXs;
45
  typedef typename MathBase::MatrixXs MatrixXs;
46
47
  /**
48
   * @brief Initialize the floating-base actuation model
49
   *
50
   * @param[in] state  State of a multibody system
51
   * @param[in] nu     Dimension of joint-torque vector
52
   */
53
703
  explicit ActuationModelFloatingBaseTpl(
54
      boost::shared_ptr<StateMultibody> state)
55
      : Base(state,
56
1406
             state->get_nv() -
57
703
                 state->get_pinocchio()
58
825
                     ->joints[(
59
703
                         state->get_pinocchio()->existJointName("root_joint")
60




1406
                             ? state->get_pinocchio()->getJointId("root_joint")
61
                             : 0)]
62


2109
                     .nv()){};
63
1410
  virtual ~ActuationModelFloatingBaseTpl(){};
64
65
  /**
66
   * @brief Compute the floating-base actuation signal from the joint-torque
67
   * input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
68
   *
69
   * @param[in] data  Actuation data
70
   * @param[in] x     State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
71
   * @param[in] u     Joint-torque input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
72
   */
73
54507
  virtual void calc(const boost::shared_ptr<Data>& data,
74
                    const Eigen::Ref<const VectorXs>& /*x*/,
75
                    const Eigen::Ref<const VectorXs>& u) {
76
54507
    if (static_cast<std::size_t>(u.size()) != nu_) {
77
      throw_pretty("Invalid argument: "
78
                   << "u has wrong dimension (it should be " +
79
                          std::to_string(nu_) + ")");
80
    }
81
54507
    data->tau.tail(nu_) = u;
82
54507
  };
83
84
  /**
85
   * @brief Compute the Jacobians of the floating-base actuation function
86
   *
87
   * @param[in] data  Actuation data
88
   * @param[in] x     State point \f$\mathbf{x}\in\mathbb{R}^{ndx}\f$
89
   * @param[in] u     Joint-torque input \f$\mathbf{u}\in\mathbb{R}^{nu}\f$
90
   */
91
#ifndef NDEBUG
92
8676
  virtual void calcDiff(const boost::shared_ptr<Data>& data,
93
                        const Eigen::Ref<const VectorXs>& /*x*/,
94
                        const Eigen::Ref<const VectorXs>& /*u*/) {
95
#else
96
  virtual void calcDiff(const boost::shared_ptr<Data>&,
97
                        const Eigen::Ref<const VectorXs>& /*x*/,
98
                        const Eigen::Ref<const VectorXs>& /*u*/) {
99
#endif
100
    // The derivatives has constant values which were set in createData.
101



8676
    assert_pretty(data->dtau_dx.isZero(), "dtau_dx has wrong value");
102



8676
    assert_pretty(MatrixXs(data->dtau_du).isApprox(dtau_du_),
103
                  "dtau_du has wrong value");
104
8676
  };
105
106
23375
  virtual void commands(const boost::shared_ptr<Data>& data,
107
                        const Eigen::Ref<const VectorXs>&,
108
                        const Eigen::Ref<const VectorXs>& tau) {
109
23375
    if (static_cast<std::size_t>(tau.size()) != state_->get_nv()) {
110
      throw_pretty("Invalid argument: "
111
                   << "tau has wrong dimension (it should be " +
112
                          std::to_string(state_->get_nv()) + ")");
113
    }
114
23375
    data->u = tau.tail(nu_);
115
23375
  }
116
117
#ifndef NDEBUG
118
3145
  virtual void torqueTransform(const boost::shared_ptr<Data>& data,
119
                               const Eigen::Ref<const VectorXs>&,
120
                               const Eigen::Ref<const VectorXs>&) {
121
#else
122
  virtual void torqueTransform(const boost::shared_ptr<Data>&,
123
                               const Eigen::Ref<const VectorXs>&,
124
                               const Eigen::Ref<const VectorXs>&) {
125
#endif
126
    // The torque transform has constant values which were set in createData.
127



3145
    assert_pretty(MatrixXs(data->Mtau).isApprox(Mtau_), "Mtau has wrong value");
128
3145
  }
129
130
  /**
131
   * @brief Create the floating-base actuation data
132
   *
133
   * @return the actuation data
134
   */
135
55605
  virtual boost::shared_ptr<Data> createData() {
136
    typedef StateMultibodyTpl<Scalar> StateMultibody;
137
55605
    boost::shared_ptr<StateMultibody> state =
138
55605
        boost::static_pointer_cast<StateMultibody>(state_);
139
55605
    boost::shared_ptr<Data> data =
140
        boost::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this);
141
55605
    const std::size_t root_joint_id =
142
55605
        state->get_pinocchio()->existJointName("root_joint")
143




55605
            ? state->get_pinocchio()->getJointId("root_joint")
144
            : 0;
145
55605
    const std::size_t nfb = state->get_pinocchio()->joints[root_joint_id].nv();
146

55605
    data->dtau_du.diagonal(-nfb).setOnes();
147

55605
    data->Mtau.diagonal(nfb).setOnes();
148
370625
    for (std::size_t i = 0; i < nfb; ++i) {
149
315020
      data->tau_set[i] = false;
150
    }
151
#ifndef NDEBUG
152
55605
    dtau_du_ = data->dtau_du;
153
55605
    Mtau_ = data->Mtau;
154
#endif
155
111210
    return data;
156
  };
157
158
 protected:
159
  using Base::nu_;
160
  using Base::state_;
161
162
#ifndef NDEBUG
163
 private:
164
  MatrixXs dtau_du_;
165
  MatrixXs Mtau_;
166
#endif
167
};
168
169
}  // namespace crocoddyl
170
171
#endif  // CROCODDYL_MULTIBODY_ACTUATIONS_FLOATING_BASE_HPP_