9#ifndef CROCODDYL_MULTIBODY_ACTUATIONS_PROPELLERS_HPP_ 10#define CROCODDYL_MULTIBODY_ACTUATIONS_PROPELLERS_HPP_ 12#include "crocoddyl/core/actuation-base.hpp" 13#include "crocoddyl/core/utils/conversions.hpp" 14#include "crocoddyl/multibody/states/multibody.hpp" 18enum ThrusterType { CW = 0, CCW };
20template <
typename _Scalar>
22 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
24 typedef _Scalar Scalar;
25 typedef pinocchio::SE3Tpl<Scalar> SE3;
39 const ThrusterType
type = CW,
41 const Scalar
max_thrust = std::numeric_limits<Scalar>::infinity())
60 const Scalar
max_thrust = std::numeric_limits<Scalar>::infinity())
61 :
pose(SE3::Identity()),
73 template <
typename NewScalar>
93 template <
typename OtherScalar>
95 return (
pose == other.pose &&
ctorque == other.ctorque &&
100 friend std::ostream& operator<<(std::ostream& os,
102 typedef typename ScalarSelector<Scalar>::type PrintableScalar;
103 os <<
" pose:" << std::endl
105 << X.pose.rotation().template cast<PrintableScalar>() << std::endl
107 << X.pose.translation().template cast<PrintableScalar>().transpose()
109 <<
" ctorque: " << scalar_cast<PrintableScalar>(X.ctorque) << std::endl
110 <<
" type: " << X.type << std::endl
111 <<
"min_thrust: " << scalar_cast<PrintableScalar>(X.min_thrust)
113 <<
"max_thrust: " << scalar_cast<PrintableScalar>(X.max_thrust)
144template <
typename _Scalar>
148 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
152 typedef _Scalar Scalar;
158 typedef typename MathBase::Vector3s Vector3s;
159 typedef typename MathBase::VectorXs VectorXs;
160 typedef typename MathBase::MatrixXs MatrixXs;
170 const std::vector<Thruster>& thrusters)
173 state->get_pinocchio()
175 state->get_pinocchio()->existJointName(
"root_joint")
176 ? state->get_pinocchio()->getJointId(
"root_joint")
184 if (!state->get_pinocchio()->existJointName(
"root_joint")) {
187 <<
"the first joint has to be a root one (e.g., free-flyer joint)");
190 const std::size_t nv_f =
191 state->get_pinocchio()
192 ->joints[(state->get_pinocchio()->existJointName(
"root_joint")
193 ? state->get_pinocchio()->getJointId(
"root_joint")
220 virtual void calc(
const std::shared_ptr<Data>& data,
221 const Eigen::Ref<const VectorXs>&,
222 const Eigen::Ref<const VectorXs>& u)
override {
223 if (
static_cast<std::size_t
>(u.size()) !=
nu_) {
225 "Invalid argument: " <<
"u has wrong dimension (it should be " +
226 std::to_string(
nu_) +
")");
231 data->tau.noalias() = data->dtau_du * u;
243 virtual void calcDiff(
const std::shared_ptr<Data>& data,
244 const Eigen::Ref<const VectorXs>&,
245 const Eigen::Ref<const VectorXs>&)
override {
247 virtual void calcDiff(
const std::shared_ptr<Data>&,
248 const Eigen::Ref<const VectorXs>&,
249 const Eigen::Ref<const VectorXs>&)
override {
252 assert_pretty(MatrixXs(data->dtau_du).isApprox(
W_thrust_),
253 "dtau_du has wrong value");
256 virtual void commands(
const std::shared_ptr<Data>& data,
257 const Eigen::Ref<const VectorXs>&,
258 const Eigen::Ref<const VectorXs>& tau)
override {
259 data->u.noalias() = data->Mtau * tau;
264 const Eigen::Ref<const VectorXs>&,
265 const Eigen::Ref<const VectorXs>&)
override {
268 const Eigen::Ref<const VectorXs>&,
269 const Eigen::Ref<const VectorXs>&)
override {
272 assert_pretty(MatrixXs(data->Mtau).isApprox(
Mtau_),
"Mtau has wrong value");
281 std::shared_ptr<Data> data =
282 std::allocate_shared<Data>(Eigen::aligned_allocator<Data>(),
this);
287 template <
typename NewScalar>
292 std::vector<ThrusterType> thrusters = vector_cast<NewScalar>(
thrusters_);
294 std::static_pointer_cast<StateType>(
state_->template cast<NewScalar>()),
318 if (
static_cast<std::size_t
>(thrusters.size()) !=
n_thrusters_) {
319 throw_pretty(
"Invalid argument: " 320 <<
"the number of thrusters is wrong (it should be " +
327 const Vector3s& f_z = p.
pose.rotation() * Vector3s::UnitZ();
328 W_thrust_.template topRows<3>().col(i) += f_z;
329 W_thrust_.template middleRows<3>(3).col(i).noalias() +=
330 p.
pose.translation().cross(f_z);
351 const MatrixXs& get_S()
const {
return S_; }
353 void print(std::ostream& os)
const override {
354 os <<
"ActuationModelFloatingBaseThrusters {nu=" <<
nu_ 355 <<
", nthrusters=" <<
n_thrusters_ <<
", thrusters=" << std::endl;
357 os << std::to_string(i) <<
": " <<
thrusters_[i];
375 void updateData(
const std::shared_ptr<Data>& data) {
378 const std::size_t nv =
state_->get_nv();
379 for (std::size_t k = 0; k < nv; ++k) {
380 data->tau_set[k] = if_static(
S_(k, k));
382 update_data_ =
false;
386 template <
typename Scalar>
387 typename std::enable_if<std::is_floating_point<Scalar>::value,
bool>
::type 388 if_static(
const Scalar& condition) {
389 return (fabs(condition) < std::numeric_limits<Scalar>::epsilon()) ? false
393#ifdef CROCODDYL_WITH_CODEGEN 395 template <
typename Scalar>
396 typename std::enable_if<!std::is_floating_point<Scalar>::value,
bool>::type
397 if_static(
const Scalar& condition) {
398 return CppAD::Value(CppAD::fabs(condition)) >=
399 CppAD::numeric_limits<Scalar>::epsilon();
406CROCODDYL_DECLARE_EXTERN_TEMPLATE_STRUCT(crocoddyl::ThrusterTpl)
407CROCODDYL_DECLARE_EXTERN_TEMPLATE_CLASS(
408 crocoddyl::ActuationModelFloatingBaseThrustersTpl)
std::shared_ptr< StateAbstract > state_
ActuationModelAbstractTpl(std::shared_ptr< StateAbstract > state, const std::size_t nu)
Initialize the actuation model.
Actuation models for floating base systems actuated with thrusters.
std::shared_ptr< StateAbstract > 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.
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_
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 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.
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.
const std::vector< Thruster > & get_thrusters() const
Return the vector of thrusters.
State multibody representation.
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.
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.