9 #ifndef CROCODDYL_CORE_ACTIVATIONS_QUADRATIC_BARRIER_HPP_ 10 #define CROCODDYL_CORE_ACTIVATIONS_QUADRATIC_BARRIER_HPP_ 15 #include "crocoddyl/core/fwd.hpp" 16 #include "crocoddyl/core/utils/exception.hpp" 17 #include "crocoddyl/core/activation-base.hpp" 19 #include <pinocchio/utils/static-if.hpp> 23 template <
typename _Scalar>
25 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
27 typedef _Scalar Scalar;
29 typedef typename MathBase::VectorXs VectorXs;
30 typedef typename MathBase::MatrixXs MatrixXs;
32 ActivationBoundsTpl(
const VectorXs& lower,
const VectorXs& upper,
const Scalar b = (Scalar)1.)
33 : lb(lower), ub(upper), beta(b) {
34 if (lb.size() != ub.size()) {
35 throw_pretty(
"Invalid argument: " 36 <<
"The lower and upper bounds don't have the same dimension (lb,ub dimensions equal to " +
37 std::to_string(lb.size()) +
"," + std::to_string(ub.size()) +
", respectively)");
39 if (beta < Scalar(0) || beta > Scalar(1.)) {
40 throw_pretty(
"Invalid argument: " 41 <<
"The range of beta is between 0 and 1");
44 for (std::size_t i = 0; i < static_cast<std::size_t>(lb.size()); ++i) {
45 if (isfinite(lb(i)) && isfinite(ub(i))) {
46 if (lb(i) - ub(i) > 0) {
47 throw_pretty(
"Invalid argument: " 48 <<
"The lower and upper bounds are badly defined; ub has to be bigger / equals to lb");
53 if (beta >= Scalar(0) && beta <= Scalar(1.)) {
54 VectorXs m = Scalar(0.5) * (lower + upper);
55 VectorXs d = Scalar(0.5) * (upper - lower);
79 template <
typename _Scalar>
82 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
84 typedef _Scalar Scalar;
90 typedef typename MathBase::VectorXs VectorXs;
91 typedef typename MathBase::MatrixXs MatrixXs;
94 : Base(bounds.lb.size()), bounds_(bounds){};
97 virtual void calc(
const boost::shared_ptr<ActivationDataAbstract>& data,
const Eigen::Ref<const VectorXs>& r) {
98 if (static_cast<std::size_t>(r.size()) != nr_) {
99 throw_pretty(
"Invalid argument: " 100 <<
"r has wrong dimension (it should be " + std::to_string(nr_) +
")");
103 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
105 d->rlb_min_ = (r - bounds_.lb).array().min(Scalar(0.));
106 d->rub_max_ = (r - bounds_.ub).array().max(Scalar(0.));
108 Scalar(0.5) * d->rlb_min_.matrix().squaredNorm() + Scalar(0.5) * d->rub_max_.matrix().squaredNorm();
111 virtual void calcDiff(
const boost::shared_ptr<ActivationDataAbstract>& data,
const Eigen::Ref<const VectorXs>& r) {
112 if (static_cast<std::size_t>(r.size()) != nr_) {
113 throw_pretty(
"Invalid argument: " 114 <<
"r has wrong dimension (it should be " + std::to_string(nr_) +
")");
117 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
118 data->Ar = (d->rlb_min_ + d->rub_max_).matrix();
120 using pinocchio::internal::if_then_else;
121 for (Eigen::Index i = 0; i < data->Arr.cols(); i++) {
122 data->Arr.diagonal()[i] = if_then_else(
123 pinocchio::internal::LE, r[i] - bounds_.lb[i], Scalar(0.), Scalar(1.),
124 if_then_else(pinocchio::internal::GE, r[i] - bounds_.ub[i], Scalar(0.), Scalar(1.), Scalar(0.)));
128 virtual boost::shared_ptr<ActivationDataAbstract> createData() {
129 return boost::allocate_shared<Data>(Eigen::aligned_allocator<Data>(),
this);
132 const ActivationBounds& get_bounds()
const {
return bounds_; };
133 void set_bounds(
const ActivationBounds& bounds) { bounds_ = bounds; };
139 ActivationBounds bounds_;
142 template <
typename _Scalar>
144 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
146 typedef _Scalar Scalar;
148 typedef typename MathBase::ArrayXs ArrayXs;
151 template <
typename Activation>
153 : Base(activation), rlb_min_(activation->get_nr()), rub_max_(activation->get_nr()) {
167 #endif // CROCODDYL_CORE_ACTIVATIONS_QUADRATIC_BARRIER_HPP_