TVM  0.9.4
Clamped.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017-2020 CNRS-AIST JRL and CNRS-UM LIRMM
3  */
4 
5 #pragma once
6 
7 // std::variant is basically unusable in clang 6 + libstdc++ due to a bug
8 // see, e.g. https://bugs.llvm.org/show_bug.cgi?id=33222
9 // We use https://github.com/mpark/variant/ instead
10 #include <mpark/variant.hpp>
11 
12 #include <tvm/defs.h>
13 
16 
17 namespace tvm::task_dynamics
18 {
24 template<class TD, class TDImpl = typename TD::Impl>
25 class Clamped : public TD
26 {
27 public:
28  using Bounds = mpark::variant<double, Eigen::VectorXd>;
29 
30  class Impl : public TDImpl
31  {
32  public:
33  template<typename... Args>
34  Impl(FunctionPtr f,
36  const Eigen::VectorXd & rhs,
37  const Bounds & min,
38  const Bounds & max,
39  Args &&... args);
40  void updateValue() override;
41  ~Impl() override = default;
42 
44  const Eigen::VectorXd & min() const { return min_; }
51  Eigen::VectorXd & min() { return min_; }
53  const Eigen::VectorXd & max() const { return max_; }
60  Eigen::VectorXd & max() { return max_; }
61 
62  private:
63  Eigen::VectorXd min_;
64  Eigen::VectorXd max_;
65  };
66 
73  template<typename... Args>
74  Clamped(double max, Args &&... args);
75 
83  template<typename... Args>
84  Clamped(const std::pair<double, double> & minMax, Args &&... args);
85 
92  template<typename... Args>
93  Clamped(const VectorConstRef & max, Args &&... args);
94 
102  template<typename... Args>
103  Clamped(const std::pair<VectorConstRef, VectorConstRef> & minMax, Args &&... args);
104 
105  ~Clamped() override = default;
106 
107 protected:
108  std::unique_ptr<abstract::TaskDynamicsImpl> impl_(FunctionPtr f,
110  const Eigen::VectorXd & rhs) const override
111  { return TD::template impl_<Impl>(f, t, rhs, min_, max_); }
112 
114 
115 private:
116  Bounds min_;
117  Bounds max_;
118 };
119 
120 template<class TD, class TDImpl>
121 template<typename... Args>
122 inline Clamped<TD, TDImpl>::Clamped(double max, Args &&... args)
123 : Clamped<TD, TDImpl>({-max, max}, std::forward<Args>(args)...)
124 {}
125 
126 template<class TD, class TDImpl>
127 template<typename... Args>
128 inline Clamped<TD, TDImpl>::Clamped(const std::pair<double, double> & minMax, Args &&... args)
129 : TD(std::forward<Args>(args)...), min_(minMax.first), max_(minMax.second)
130 {
131  const auto & [min, max] = minMax;
132  if(min > 0)
133  {
134  throw std::runtime_error("[task_dynamics::Clamped] Minimum values must be negative.");
135  }
136  if(max < 0)
137  {
138  throw std::runtime_error("[task_dynamics::Clamped] Maximum values must be positive.");
139  }
140 }
141 
142 template<class TD, class TDImpl>
143 template<typename... Args>
144 inline Clamped<TD, TDImpl>::Clamped(const VectorConstRef & max, Args &&... args)
145 : Clamped<TD>({-max, max}, std::forward<Args>(args)...)
146 {}
147 
148 template<class TD, class TDImpl>
149 template<typename... Args>
150 inline Clamped<TD, TDImpl>::Clamped(const std::pair<VectorConstRef, VectorConstRef> & minMax, Args &&... args)
151 : TD(std::forward<Args>(args)...), min_(minMax.first), max_(minMax.second)
152 {
153  const auto & [min, max] = minMax;
154  if(min.size() != max.size())
155  {
156  throw std::runtime_error("[task_dynamics::Clamped] The minimum and maximum must have the same size.");
157  }
158  if((min.array() > 0).any())
159  {
160  throw std::runtime_error("[task_dynamics::Clamped] Minimum values must be negative.");
161  }
162  if((max.array() < 0).any())
163  {
164  throw std::runtime_error("[task_dynamics::Clamped] Maximum values must be positive.");
165  }
166 }
167 
168 template<class TD, class TDImpl>
169 template<typename... Args>
172  const Eigen::VectorXd & rhs,
173  const Bounds & min,
174  const Bounds & max,
175  Args &&... args)
176 : TDImpl(f, t, rhs, std::forward<Args>(args)...),
177  min_(min.index() == 1 ? mpark::get<Eigen::VectorXd>(min)
178  : Eigen::VectorXd::Constant(f->size(), mpark::get<double>(min))),
179  max_(max.index() == 1 ? mpark::get<Eigen::VectorXd>(max)
180  : Eigen::VectorXd::Constant(f->size(), mpark::get<double>(max)))
181 {
182  if(min_.size() != f->size() || max_.size() != f->size())
183  {
184  throw std::runtime_error(
185  "[task_dynamics::Clamped::Impl] Sizes of the minimum, maximum and function must be the same.");
186  }
187  if((min_.array() > 0).any())
188  {
189  throw std::runtime_error("[task_dynamics::Clamped::Impl] Minimum values must be negative.");
190  }
191  if((max_.array() < 0).any())
192  {
193  throw std::runtime_error("[task_dynamics::Clamped::Impl] Maximum values must be positive.");
194  }
195 }
196 
197 template<class TD, class TDImpl>
199 {
200  TDImpl::updateValue();
201  double s = 1;
202  for(int i = 0; i < this->function().size(); ++i)
203  {
204  if(this->value_[i] > max_[i])
205  {
206  // innerValue[i] > max_[i] >= 0 so that innerValue[i] != 0
207  s = std::min(s, max_[i] / this->value_[i]);
208  }
209  else if(this->value_[i] < min_[i])
210  {
211  // this->value_[i] < min_[i] <= 0 so that this->value_[i] != 0
212  s = std::min(s, min_[i] / this->value_[i]);
213  }
214  }
215  this->value_ *= s;
216 }
217 
218 } // namespace tvm::task_dynamics
#define COMPOSABLE_TASK_DYNAMICS_DERIVED_FACTORY(T,...)
Definition: TaskDynamics.h:82
Definition: Clamped.h:31
const Eigen::VectorXd & min() const
Definition: Clamped.h:44
const Eigen::VectorXd & max() const
Definition: Clamped.h:53
Eigen::VectorXd & min()
Definition: Clamped.h:51
Impl(FunctionPtr f, constraint::Type t, const Eigen::VectorXd &rhs, const Bounds &min, const Bounds &max, Args &&... args)
Definition: Clamped.h:170
void updateValue() override
Definition: Clamped.h:198
Eigen::VectorXd & max()
Definition: Clamped.h:60
Definition: Clamped.h:26
mpark::variant< double, Eigen::VectorXd > Bounds
Definition: Clamped.h:28
~Clamped() override=default
Clamped(double max, Args &&... args)
Definition: Clamped.h:122
std::unique_ptr< abstract::TaskDynamicsImpl > impl_(FunctionPtr f, constraint::Type t, const Eigen::VectorXd &rhs) const override
Definition: Clamped.h:108
Definition: Constant.h:16
Definition: AffineExprDetail.h:95
Definition: probe.h:44
Type
Definition: enums.h:15
Definition: defs.h:35
std::shared_ptr< function::abstract::Function > FunctionPtr
Definition: defs.h:57
Eigen::Ref< const Eigen::VectorXd > VectorConstRef
Definition: defs.h:50