Crocoddyl
Loading...
Searching...
No Matches
smooth-sat.hpp
1
2// BSD 3-Clause License
3//
4// Copyright (C) 2019-2025, University of Edinburgh, IRI: CSIC-UPC,
5// Heriot-Watt University
6// Copyright note valid unless otherwise stated in individual files.
7// All rights reserved.
9
10#ifndef CROCODDYL_CORE_SQUASHING_SMOOTH_SAT_HPP_
11#define CROCODDYL_CORE_SQUASHING_SMOOTH_SAT_HPP_
12
13#include "crocoddyl/core/actuation/squashing-base.hpp"
14#include "crocoddyl/core/fwd.hpp"
15
16namespace crocoddyl {
17
18template <typename _Scalar>
19class SquashingModelSmoothSatTpl : public SquashingModelAbstractTpl<_Scalar> {
20 public:
21 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
22 CROCODDYL_DERIVED_CAST(SquashingModelBase, SquashingModelSmoothSatTpl)
23
24 typedef _Scalar Scalar;
25 typedef MathBaseTpl<Scalar> MathBase;
26 typedef SquashingModelAbstractTpl<Scalar> Base;
27 typedef SquashingDataAbstractTpl<Scalar> SquashingDataAbstract;
28 typedef typename MathBase::VectorXs VectorXs;
29
30 SquashingModelSmoothSatTpl(const Eigen::Ref<const VectorXs>& u_lb,
31 const Eigen::Ref<const VectorXs>& u_ub,
32 const std::size_t ns)
33 : Base(ns) {
34 u_lb_ = u_lb;
35 u_ub_ = u_ub;
36
37 s_lb_ = u_lb_;
38 s_ub_ = u_ub_;
39
40 smooth_ = Scalar(0.1);
41
42 d_ = (u_ub_ - u_lb_) * smooth_;
43 a_ = d_.array() * d_.array();
44 }
45
46 virtual ~SquashingModelSmoothSatTpl() = default;
47
48 virtual void calc(const std::shared_ptr<SquashingDataAbstract>& data,
49 const Eigen::Ref<const VectorXs>& s) override {
50 // Squashing function used: "Smooth abs":
51 // s(u) = 0.5*(lb + ub + sqrt(smooth + (u - lb)^2) - sqrt(smooth + (u -
52 // ub)^2))
53 data->u =
54 Scalar(0.5) * (Eigen::sqrt((s - u_lb_).array().square() + a_.array()) -
55 Eigen::sqrt((s - u_ub_).array().square() + a_.array()) +
56 u_lb_.array() + u_ub_.array());
57 }
58
59 virtual void calcDiff(const std::shared_ptr<SquashingDataAbstract>& data,
60 const Eigen::Ref<const VectorXs>& s) override {
61 data->du_ds.diagonal() =
62 Scalar(0.5) *
63 ((s - u_lb_).array() /
64 Eigen::sqrt(a_.array() + (s - u_lb_).array().square()) -
65 (s - u_ub_).array() /
66 Eigen::sqrt(a_.array() + (s - u_ub_).array().square()));
67 }
68
69 template <typename NewScalar>
70 SquashingModelSmoothSatTpl<NewScalar> cast() const {
71 typedef SquashingModelSmoothSatTpl<NewScalar> ReturnType;
72 ReturnType ret(u_lb_.template cast<NewScalar>(),
73 u_ub_.template cast<NewScalar>(), ns_);
74 ret.set_smooth(scalar_cast<NewScalar>(smooth_));
75 return ret;
76 }
77
78 const Scalar get_smooth() const { return smooth_; };
79 void set_smooth(const Scalar smooth) {
80 if (smooth < 0.) {
81 throw_pretty("Invalid argument: " << "Smooth value has to be positive");
82 }
83 smooth_ = smooth;
84
85 d_ = (u_ub_ - u_lb_) * smooth_;
86 a_ = d_.array() * d_.array();
87
88 s_lb_ = u_lb_;
89 s_ub_ = u_ub_;
90 }
91
92 const VectorXs& get_d() const { return d_; };
93
94 private:
95 VectorXs a_;
96 VectorXs d_;
97
98 Scalar smooth_;
99
100 using Base::ns_;
101 using Base::s_lb_;
102 using Base::s_ub_;
103 using Base::u_lb_;
104 using Base::u_ub_;
105};
106
107} // namespace crocoddyl
108
109CROCODDYL_DECLARE_EXTERN_TEMPLATE_CLASS(crocoddyl::SquashingModelSmoothSatTpl)
110
111#endif // CROCODDYL_CORE_SQUASHING_SMOOTH_SAT_HPP_