9 #ifndef CROCODDYL_MULTIBODY_ACTUATIONS_PROPELLERS_HPP_
10 #define CROCODDYL_MULTIBODY_ACTUATIONS_PROPELLERS_HPP_
12 #include "crocoddyl/core/actuation-base.hpp"
13 #include "crocoddyl/multibody/states/multibody.hpp"
17 enum ThrusterType { CW = 0, CCW };
19 template <
typename _Scalar>
21 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
23 typedef _Scalar Scalar;
24 typedef pinocchio::SE3Tpl<Scalar> SE3;
38 const ThrusterType
type = CW,
40 const Scalar
max_thrust = std::numeric_limits<Scalar>::infinity())
59 const Scalar
max_thrust = std::numeric_limits<Scalar>::infinity())
60 :
pose(SE3::Identity()),
72 template <
typename NewScalar>
73 ThrusterTpl<NewScalar> cast()
const {
74 typedef ThrusterTpl<NewScalar> ReturnType;
81 ThrusterTpl& operator=(
const ThrusterTpl<Scalar>& other) {
92 template <
typename OtherScalar>
93 bool operator==(
const ThrusterTpl<OtherScalar>& other)
const {
94 return (
pose == other.pose &&
ctorque == other.ctorque &&
99 friend std::ostream& operator<<(std::ostream& os,
100 const ThrusterTpl<Scalar>& X) {
101 os <<
" pose:" << std::endl
102 << X.pose <<
" ctorque: " << X.ctorque << std::endl
103 <<
" type: " << X.type << std::endl
104 <<
"min_thrust: " << X.min_thrust << std::endl
105 <<
"max_thrust: " << X.max_thrust << std::endl;
135 template <
typename _Scalar>
139 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
143 typedef _Scalar Scalar;
149 typedef typename MathBase::Vector3s Vector3s;
150 typedef typename MathBase::VectorXs VectorXs;
151 typedef typename MathBase::MatrixXs MatrixXs;
161 const std::vector<Thruster>& thrusters)
164 state->get_pinocchio()
166 state->get_pinocchio()->existJointName(
"root_joint")
167 ? state->get_pinocchio()->getJointId(
"root_joint")
175 if (!state->get_pinocchio()->existJointName(
"root_joint")) {
178 <<
"the first joint has to be a root one (e.g., free-flyer joint)");
200 virtual void calc(
const std::shared_ptr<Data>& data,
201 const Eigen::Ref<const VectorXs>&,
202 const Eigen::Ref<const VectorXs>& u)
override {
203 if (
static_cast<std::size_t
>(u.size()) !=
nu_) {
205 "Invalid argument: " <<
"u has wrong dimension (it should be " +
206 std::to_string(
nu_) +
")");
211 data->tau.noalias() = data->dtau_du * u;
223 virtual void calcDiff(
const std::shared_ptr<Data>& data,
224 const Eigen::Ref<const VectorXs>&,
225 const Eigen::Ref<const VectorXs>&)
override {
227 virtual void calcDiff(
const std::shared_ptr<Data>&,
228 const Eigen::Ref<const VectorXs>&,
229 const Eigen::Ref<const VectorXs>&)
override {
232 assert_pretty(MatrixXs(data->dtau_du).isApprox(
W_thrust_),
233 "dtau_du has wrong value");
236 virtual void commands(
const std::shared_ptr<Data>& data,
237 const Eigen::Ref<const VectorXs>&,
238 const Eigen::Ref<const VectorXs>& tau)
override {
239 data->u.noalias() = data->Mtau * tau;
244 const Eigen::Ref<const VectorXs>&,
245 const Eigen::Ref<const VectorXs>&)
override {
248 const Eigen::Ref<const VectorXs>&,
249 const Eigen::Ref<const VectorXs>&)
override {
252 assert_pretty(MatrixXs(data->Mtau).isApprox(
Mtau_),
"Mtau has wrong value");
261 std::shared_ptr<Data> data =
262 std::allocate_shared<Data>(Eigen::aligned_allocator<Data>(),
this);
267 template <
typename NewScalar>
272 std::vector<ThrusterType> thrusters = vector_cast<NewScalar>(
thrusters_);
274 std::static_pointer_cast<StateType>(
state_->template cast<NewScalar>()),
298 if (
static_cast<std::size_t
>(thrusters.size()) !=
n_thrusters_) {
299 throw_pretty(
"Invalid argument: "
300 <<
"the number of thrusters is wrong (it should be " +
307 const Vector3s& f_z = p.
pose.rotation() * Vector3s::UnitZ();
308 W_thrust_.template topRows<3>().col(i) += f_z;
309 W_thrust_.template middleRows<3>(3).col(i).noalias() +=
310 p.
pose.translation().cross(f_z);
327 const MatrixXs& get_Wthrust()
const {
return W_thrust_; }
329 const MatrixXs& get_S()
const {
return S_; }
331 void print(std::ostream& os)
const override {
332 os <<
"ActuationModelFloatingBaseThrusters {nu=" <<
nu_
333 <<
", nthrusters=" <<
n_thrusters_ <<
", thrusters=" << std::endl;
335 os << std::to_string(i) <<
": " <<
thrusters_[i];
353 void updateData(
const std::shared_ptr<Data>& data) {
356 const std::size_t nv =
state_->get_nv();
357 for (std::size_t k = 0; k < nv; ++k) {
358 data->tau_set[k] = if_static(
S_(k, k));
360 update_data_ =
false;
364 template <
typename Scalar>
365 typename std::enable_if<std::is_floating_point<Scalar>::value,
bool>::type
366 if_static(
const Scalar& condition) {
367 return (fabs(condition) < std::numeric_limits<Scalar>::epsilon()) ? false
371 #ifdef CROCODDYL_WITH_CODEGEN
373 template <
typename Scalar>
374 typename std::enable_if<!std::is_floating_point<Scalar>::value,
bool>::type
375 if_static(
const Scalar& condition) {
376 return CppAD::Value(CppAD::fabs(condition)) >=
377 CppAD::numeric_limits<Scalar>::epsilon();
385 CROCODDYL_DECLARE_EXTERN_TEMPLATE_CLASS(
Abstract class for the actuation-mapping model.
std::shared_ptr< StateAbstract > state_
Model of the state.
std::size_t nu_
Dimension of joint torque inputs.
Actuation models for floating base systems actuated with thrusters.
MatrixXs S_
Selection matrix for under-actuation part.
std::shared_ptr< StateAbstract > state_
Model of the state.
virtual void calc(const std::shared_ptr< Data > &data, const Eigen::Ref< const VectorXs > &, const Eigen::Ref< const VectorXs > &u) override
Compute the actuation signal and actuation set from its thrust and joint torque inputs .
virtual std::shared_ptr< Data > createData() override
Create the floating base thruster actuation data.
const std::vector< Thruster > & get_thrusters() const
Return the vector of thrusters.
std::size_t n_thrusters_
Number of thrusters.
ActuationModelFloatingBaseThrustersTpl(std::shared_ptr< StateMultibody > state, const std::vector< Thruster > &thrusters)
Initialize the floating base actuation model equipped with thrusters.
virtual void commands(const std::shared_ptr< Data > &data, const Eigen::Ref< const VectorXs > &, const Eigen::Ref< const VectorXs > &tau) override
Compute the joint torque input from the generalized torques.
std::vector< Thruster > thrusters_
Vector of thrusters.
virtual void torqueTransform(const std::shared_ptr< Data > &data, const Eigen::Ref< const VectorXs > &, const Eigen::Ref< const VectorXs > &) override
Compute the torque transform from generalized torques to joint torque inputs.
std::size_t nu_
Dimension of joint torque inputs.
std::size_t get_nthrusters() const
Return the number of thrusters.
virtual void calcDiff(const std::shared_ptr< Data > &data, const Eigen::Ref< const VectorXs > &, const Eigen::Ref< const VectorXs > &) override
Compute the Jacobians of the floating base thruster actuation function.
MatrixXs W_thrust_
Matrix from thrusters thrusts to body wrench.
void set_thrusters(const std::vector< Thruster > &thrusters)
Modify the vector of thrusters.
void print(std::ostream &os) const override
Print relevant information of the residual model.
State multibody representation.
Scalar min_thrust
Minimum thrust.
ThrusterTpl(const SE3 &pose, const Scalar ctorque, const ThrusterType type=CW, const Scalar min_thrust=Scalar(0.), const Scalar max_thrust=std::numeric_limits< Scalar >::infinity())
Initialize the thruster in a give pose from the root joint.
Scalar max_thrust
Minimum thrust.
ThrusterTpl(const Scalar ctorque, const ThrusterType type=CW, const Scalar min_thrust=Scalar(0.), const Scalar max_thrust=std::numeric_limits< Scalar >::infinity())
Initialize the thruster in a pose in the origin of the root joint.
Scalar ctorque
Coefficient of generated torque per thrust.