crocoddyl 1.9.0
Contact RObot COntrol by Differential DYnamic programming Library (Crocoddyl)
 
Loading...
Searching...
No Matches
quadratic-barrier.hpp
1
2// BSD 3-Clause License
3//
4// Copyright (C) 2019-2021, LAAS-CNRS, University of Edinburgh, University of Oxford
5// Copyright note valid unless otherwise stated in individual files.
6// All rights reserved.
8
9#ifndef CROCODDYL_CORE_ACTIVATIONS_QUADRATIC_BARRIER_HPP_
10#define CROCODDYL_CORE_ACTIVATIONS_QUADRATIC_BARRIER_HPP_
11
12#include <stdexcept>
13#include <math.h>
14#include <pinocchio/utils/static-if.hpp>
15
16#include "crocoddyl/core/fwd.hpp"
17#include "crocoddyl/core/utils/exception.hpp"
18#include "crocoddyl/core/activation-base.hpp"
19
20namespace crocoddyl {
21
22template <typename _Scalar>
24 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
25
26 typedef _Scalar Scalar;
28 typedef typename MathBase::VectorXs VectorXs;
29 typedef typename MathBase::MatrixXs MatrixXs;
30
31 ActivationBoundsTpl(const VectorXs& lower, const VectorXs& upper, const Scalar b = (Scalar)1.)
32 : lb(lower), ub(upper), beta(b) {
33 if (lb.size() != ub.size()) {
34 throw_pretty("Invalid argument: "
35 << "The lower and upper bounds don't have the same dimension (lb,ub dimensions equal to " +
36 std::to_string(lb.size()) + "," + std::to_string(ub.size()) + ", respectively)");
37 }
38 if (beta < Scalar(0) || beta > Scalar(1.)) {
39 throw_pretty("Invalid argument: "
40 << "The range of beta is between 0 and 1");
41 }
42 using std::isfinite;
43 for (std::size_t i = 0; i < static_cast<std::size_t>(lb.size()); ++i) {
44 if (isfinite(lb(i)) && isfinite(ub(i))) {
45 if (lb(i) - ub(i) > 0) {
46 throw_pretty("Invalid argument: "
47 << "The lower and upper bounds are badly defined; ub has to be bigger / equals to lb");
48 }
49 }
50 // Assign the maximum value for infinity/nan values
51 if (!isfinite(lb(i))) {
52 lb(i) = -std::numeric_limits<Scalar>::max();
53 }
54 if (!isfinite(ub(i))) {
55 ub(i) = std::numeric_limits<Scalar>::max();
56 }
57 }
58
59 if (beta >= Scalar(0) && beta <= Scalar(1.)) {
60 VectorXs m = Scalar(0.5) * (lb + ub);
61 VectorXs d = Scalar(0.5) * (ub - lb);
62 lb = m - beta * d;
63 ub = m + beta * d;
64 } else {
65 beta = Scalar(1.);
66 }
67 }
68 ActivationBoundsTpl(const ActivationBoundsTpl& other) : lb(other.lb), ub(other.ub), beta(other.beta) {}
69 ActivationBoundsTpl() : beta(Scalar(1.)) {}
70
71 ActivationBoundsTpl& operator=(const ActivationBoundsTpl& other) {
72 if (this != &other) {
73 lb = other.lb;
74 ub = other.ub;
75 beta = other.beta;
76 }
77 return *this;
78 }
79
80 VectorXs lb;
81 VectorXs ub;
82 Scalar beta;
83};
84
85template <typename _Scalar>
87 public:
88 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
89
90 typedef _Scalar Scalar;
96 typedef typename MathBase::VectorXs VectorXs;
97 typedef typename MathBase::MatrixXs MatrixXs;
98
100 : Base(bounds.lb.size()), bounds_(bounds){};
102
103 virtual void calc(const boost::shared_ptr<ActivationDataAbstract>& data, const Eigen::Ref<const VectorXs>& r) {
104 if (static_cast<std::size_t>(r.size()) != nr_) {
105 throw_pretty("Invalid argument: "
106 << "r has wrong dimension (it should be " + std::to_string(nr_) + ")");
107 }
108
109 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
110
111 d->rlb_min_ = (r - bounds_.lb).array().min(Scalar(0.));
112 d->rub_max_ = (r - bounds_.ub).array().max(Scalar(0.));
113 data->a_value =
114 Scalar(0.5) * d->rlb_min_.matrix().squaredNorm() + Scalar(0.5) * d->rub_max_.matrix().squaredNorm();
115 };
116
117 virtual void calcDiff(const boost::shared_ptr<ActivationDataAbstract>& data, const Eigen::Ref<const VectorXs>& r) {
118 if (static_cast<std::size_t>(r.size()) != nr_) {
119 throw_pretty("Invalid argument: "
120 << "r has wrong dimension (it should be " + std::to_string(nr_) + ")");
121 }
122
123 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
124 data->Ar = (d->rlb_min_ + d->rub_max_).matrix();
125
126 using pinocchio::internal::if_then_else;
127 for (Eigen::Index i = 0; i < data->Arr.cols(); i++) {
128 data->Arr.diagonal()[i] = if_then_else(
129 pinocchio::internal::LE, r[i] - bounds_.lb[i], Scalar(0.), Scalar(1.),
130 if_then_else(pinocchio::internal::GE, r[i] - bounds_.ub[i], Scalar(0.), Scalar(1.), Scalar(0.)));
131 }
132 };
133
134 virtual boost::shared_ptr<ActivationDataAbstract> createData() {
135 return boost::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this);
136 };
137
138 const ActivationBounds& get_bounds() const { return bounds_; };
139 void set_bounds(const ActivationBounds& bounds) { bounds_ = bounds; };
140
146 virtual void print(std::ostream& os) const { os << "ActivationModelQuadraticBarrier {nr=" << nr_ << "}"; }
147
148 protected:
149 using Base::nr_;
150
151 private:
152 ActivationBounds bounds_;
153};
154
155template <typename _Scalar>
157 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
158
159 typedef _Scalar Scalar;
161 typedef typename MathBase::ArrayXs ArrayXs;
163
164 template <typename Activation>
165 explicit ActivationDataQuadraticBarrierTpl(Activation* const activation)
166 : Base(activation), rlb_min_(activation->get_nr()), rub_max_(activation->get_nr()) {
167 rlb_min_.setZero();
168 rub_max_.setZero();
169 }
170
171 ArrayXs rlb_min_;
172 ArrayXs rub_max_;
173 using Base::a_value;
174 using Base::Ar;
175 using Base::Arr;
176};
177
178} // namespace crocoddyl
179
180#endif // CROCODDYL_CORE_ACTIVATIONS_QUADRATIC_BARRIER_HPP_
virtual void print(std::ostream &os) const
Print relevant information of the quadratic barrier model.