Crocoddyl
cost-sum.hpp
1 // BSD 3-Clause License
3 //
4 // Copyright (C) 2019-2022, LAAS-CNRS, University of Edinburgh,
5 // Heriot-Watt University
6 // Copyright note valid unless otherwise stated in individual files.
7 // All rights reserved.
9 
10 #ifndef CROCODDYL_CORE_COSTS_COST_SUM_HPP_
11 #define CROCODDYL_CORE_COSTS_COST_SUM_HPP_
12 
13 #include <map>
14 #include <set>
15 #include <string>
16 #include <utility>
17 
18 #include "crocoddyl/core/cost-base.hpp"
19 #include "crocoddyl/core/fwd.hpp"
20 #include "crocoddyl/core/utils/exception.hpp"
21 
22 namespace crocoddyl {
23 
24 template <typename _Scalar>
25 struct CostItemTpl {
26  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
27 
28  typedef _Scalar Scalar;
30 
31  CostItemTpl() {}
32  CostItemTpl(const std::string& name,
33  boost::shared_ptr<CostModelAbstract> cost, const Scalar weight,
34  const bool active = true)
35  : name(name), cost(cost), weight(weight), active(active) {}
36 
40  friend std::ostream& operator<<(std::ostream& os,
41  const CostItemTpl<Scalar>& model) {
42  os << "{w=" << model.weight << ", " << *model.cost << "}";
43  return os;
44  }
45 
46  std::string name;
47  boost::shared_ptr<CostModelAbstract> cost;
48  Scalar weight;
49  bool active;
50 };
51 
73 template <typename _Scalar>
75  public:
76  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
77 
78  typedef _Scalar Scalar;
86  typedef typename MathBase::VectorXs VectorXs;
87  typedef typename MathBase::MatrixXs MatrixXs;
88 
89  typedef std::map<std::string, boost::shared_ptr<CostItem> >
90  CostModelContainer;
91  typedef std::map<std::string, boost::shared_ptr<CostDataAbstract> >
92  CostDataContainer;
93 
100  CostModelSumTpl(boost::shared_ptr<StateAbstract> state, const std::size_t nu);
101 
109  explicit CostModelSumTpl(boost::shared_ptr<StateAbstract> state);
110  ~CostModelSumTpl();
111 
120  void addCost(const std::string& name,
121  boost::shared_ptr<CostModelAbstract> cost, const Scalar weight,
122  const bool active = true);
123 
129  void removeCost(const std::string& name);
130 
137  void changeCostStatus(const std::string& name, const bool active);
138 
146  void calc(const boost::shared_ptr<CostDataSum>& data,
147  const Eigen::Ref<const VectorXs>& x,
148  const Eigen::Ref<const VectorXs>& u);
149 
160  void calc(const boost::shared_ptr<CostDataSum>& data,
161  const Eigen::Ref<const VectorXs>& x);
162 
170  void calcDiff(const boost::shared_ptr<CostDataSum>& data,
171  const Eigen::Ref<const VectorXs>& x,
172  const Eigen::Ref<const VectorXs>& u);
173 
186  void calcDiff(const boost::shared_ptr<CostDataSum>& data,
187  const Eigen::Ref<const VectorXs>& x);
188 
200  boost::shared_ptr<CostDataSum> createData(DataCollectorAbstract* const data);
201 
205  const boost::shared_ptr<StateAbstract>& get_state() const;
206 
210  const CostModelContainer& get_costs() const;
211 
215  std::size_t get_nu() const;
216 
220  std::size_t get_nr() const;
221 
225  std::size_t get_nr_total() const;
226 
230  const std::set<std::string>& get_active_set() const;
231 
235  const std::set<std::string>& get_inactive_set() const;
236 
237  DEPRECATED(
238  "get_active() is deprecated and will be replaced with get_active_set()",
239  const std::vector<std::string>& get_active() {
240  active_.clear();
241  active_.reserve(active_set_.size());
242  for (const auto& contact : active_set_) {
243  active_.push_back(contact);
244  }
245  return active_;
246  };)
247 
248  DEPRECATED(
249  "get_inactive() is deprecated and will be replaced with "
250  "get_inactive_set()",
251  const std::vector<std::string>& get_inactive() {
252  inactive_.clear();
253  inactive_.reserve(inactive_set_.size());
254  for (const auto& contact : inactive_set_) {
255  inactive_.push_back(contact);
256  }
257  return inactive_;
258  };)
259 
265  bool getCostStatus(const std::string& name) const;
266 
270  template <class Scalar>
271  friend std::ostream& operator<<(std::ostream& os,
272  const CostModelSumTpl<Scalar>& model);
273 
274  private:
275  boost::shared_ptr<StateAbstract> state_;
276  CostModelContainer costs_;
277  std::size_t nu_;
278  std::size_t nr_;
279  std::size_t nr_total_;
280  std::set<std::string> active_set_;
281  std::set<std::string>
282  inactive_set_;
283 
284  // Vector variants. These are to maintain the API compatibility for the
285  // deprecated syntax. These will be removed in future versions along with
286  // get_active() / get_inactive()
287  std::vector<std::string> active_;
288  std::vector<std::string> inactive_;
289 };
290 
291 template <typename _Scalar>
293  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
294 
295  typedef _Scalar Scalar;
299  typedef typename MathBase::VectorXs VectorXs;
300  typedef typename MathBase::MatrixXs MatrixXs;
301 
302  template <template <typename Scalar> class Model>
303  CostDataSumTpl(Model<Scalar>* const model, DataCollectorAbstract* const data)
304  : Lx_internal(model->get_state()->get_ndx()),
305  Lu_internal(model->get_nu()),
306  Lxx_internal(model->get_state()->get_ndx(),
307  model->get_state()->get_ndx()),
308  Lxu_internal(model->get_state()->get_ndx(), model->get_nu()),
309  Luu_internal(model->get_nu(), model->get_nu()),
310  shared(data),
311  cost(Scalar(0.)),
312  Lx(Lx_internal.data(), model->get_state()->get_ndx()),
313  Lu(Lu_internal.data(), model->get_nu()),
314  Lxx(Lxx_internal.data(), model->get_state()->get_ndx(),
315  model->get_state()->get_ndx()),
316  Lxu(Lxu_internal.data(), model->get_state()->get_ndx(),
317  model->get_nu()),
318  Luu(Luu_internal.data(), model->get_nu(), model->get_nu()) {
319  Lx.setZero();
320  Lu.setZero();
321  Lxx.setZero();
322  Lxu.setZero();
323  Luu.setZero();
325  it = model->get_costs().begin();
326  it != model->get_costs().end(); ++it) {
327  const boost::shared_ptr<CostItem>& item = it->second;
328  costs.insert(std::make_pair(item->name, item->cost->createData(data)));
329  }
330  }
331 
332  template <class ActionData>
333  void shareMemory(ActionData* const data) {
334  // Save memory by setting the internal variables with null dimension
335  Lx_internal.resize(0);
336  Lu_internal.resize(0);
337  Lxx_internal.resize(0, 0);
338  Lxu_internal.resize(0, 0);
339  Luu_internal.resize(0, 0);
340  // Share memory with the differential action data
341  new (&Lx) Eigen::Map<VectorXs>(data->Lx.data(), data->Lx.size());
342  new (&Lu) Eigen::Map<VectorXs>(data->Lu.data(), data->Lu.size());
343  new (&Lxx) Eigen::Map<MatrixXs>(data->Lxx.data(), data->Lxx.rows(),
344  data->Lxx.cols());
345  new (&Lxu) Eigen::Map<MatrixXs>(data->Lxu.data(), data->Lxu.rows(),
346  data->Lxu.cols());
347  new (&Luu) Eigen::Map<MatrixXs>(data->Luu.data(), data->Luu.rows(),
348  data->Luu.cols());
349  }
350 
351  VectorXs get_Lx() const { return Lx; }
352  VectorXs get_Lu() const { return Lu; }
353  MatrixXs get_Lxx() const { return Lxx; }
354  MatrixXs get_Lxu() const { return Lxu; }
355  MatrixXs get_Luu() const { return Luu; }
356 
357  void set_Lx(const VectorXs& _Lx) {
358  if (Lx.size() != _Lx.size()) {
359  throw_pretty("Invalid argument: "
360  << "Lx has wrong dimension (it should be " +
361  std::to_string(Lx.size()) + ")");
362  }
363  Lx = _Lx;
364  }
365  void set_Lu(const VectorXs& _Lu) {
366  if (Lu.size() != _Lu.size()) {
367  throw_pretty("Invalid argument: "
368  << "Lu has wrong dimension (it should be " +
369  std::to_string(Lu.size()) + ")");
370  }
371  Lu = _Lu;
372  }
373  void set_Lxx(const MatrixXs& _Lxx) {
374  if (Lxx.rows() != _Lxx.rows() || Lxx.cols() != _Lxx.cols()) {
375  throw_pretty("Invalid argument: "
376  << "Lxx has wrong dimension (it should be " +
377  std::to_string(Lxx.rows()) + ", " +
378  std::to_string(Lxx.cols()) + ")");
379  }
380  Lxx = _Lxx;
381  }
382  void set_Lxu(const MatrixXs& _Lxu) {
383  if (Lxu.rows() != _Lxu.rows() || Lxu.cols() != _Lxu.cols()) {
384  throw_pretty("Invalid argument: "
385  << "Lxu has wrong dimension (it should be " +
386  std::to_string(Lxu.rows()) + ", " +
387  std::to_string(Lxu.cols()) + ")");
388  }
389  Lxu = _Lxu;
390  }
391  void set_Luu(const MatrixXs& _Luu) {
392  if (Luu.rows() != _Luu.rows() || Luu.cols() != _Luu.cols()) {
393  throw_pretty("Invalid argument: "
394  << "Luu has wrong dimension (it should be " +
395  std::to_string(Luu.rows()) + ", " +
396  std::to_string(Luu.cols()) + ")");
397  }
398  Luu = _Luu;
399  }
400 
401  // Creates internal data in case we don't share it externally
402  VectorXs Lx_internal;
403  VectorXs Lu_internal;
404  MatrixXs Lxx_internal;
405  MatrixXs Lxu_internal;
406  MatrixXs Luu_internal;
407 
409  DataCollectorAbstract* shared;
410  Scalar cost;
411  Eigen::Map<VectorXs> Lx;
412  Eigen::Map<VectorXs> Lu;
413  Eigen::Map<MatrixXs> Lxx;
414  Eigen::Map<MatrixXs> Lxu;
415  Eigen::Map<MatrixXs> Luu;
416 };
417 
418 } // namespace crocoddyl
419 
420 /* --- Details -------------------------------------------------------------- */
421 /* --- Details -------------------------------------------------------------- */
422 /* --- Details -------------------------------------------------------------- */
423 #include "crocoddyl/core/costs/cost-sum.hxx"
424 
425 #endif // CROCODDYL_CORE_COSTS_COST_SUM_HPP_
Abstract class for cost models.
Definition: cost-base.hpp:59
Summation of individual cost models.
Definition: cost-sum.hpp:74
void addCost(const std::string &name, boost::shared_ptr< CostModelAbstract > cost, const Scalar weight, const bool active=true)
Add a cost item.
void calcDiff(const boost::shared_ptr< CostDataSum > &data, const Eigen::Ref< const VectorXs > &x)
Compute the Jacobian and Hessian of the total cost for nodes that depends on the state only.
void removeCost(const std::string &name)
Remove a cost item.
const boost::shared_ptr< StateAbstract > & get_state() const
Return the state.
CostModelSumTpl(boost::shared_ptr< StateAbstract > state)
Initialize the cost-sum model.
void changeCostStatus(const std::string &name, const bool active)
Change the cost status.
void calcDiff(const boost::shared_ptr< CostDataSum > &data, const Eigen::Ref< const VectorXs > &x, const Eigen::Ref< const VectorXs > &u)
Compute the Jacobian and Hessian of the total cost.
boost::shared_ptr< CostDataSum > createData(DataCollectorAbstract *const data)
Create the cost data.
friend std::ostream & operator<<(std::ostream &os, const CostModelSumTpl< Scalar > &model)
Print information on the stack of costs.
std::size_t get_nr_total() const
Return the dimension of the total residual vector.
void calc(const boost::shared_ptr< CostDataSum > &data, const Eigen::Ref< const VectorXs > &x)
Compute the total cost value for nodes that depends only on the state.
const std::set< std::string > & get_inactive_set() const
Return the names of the set of inactive costs.
const std::set< std::string > & get_active_set() const
Return the names of the set of active costs.
std::size_t get_nr() const
Return the dimension of the active residual vector.
CostModelSumTpl(boost::shared_ptr< StateAbstract > state, const std::size_t nu)
Initialize the cost-sum model.
void calc(const boost::shared_ptr< CostDataSum > &data, const Eigen::Ref< const VectorXs > &x, const Eigen::Ref< const VectorXs > &u)
Compute the total cost value.
const CostModelContainer & get_costs() const
Return the stack of cost models.
bool getCostStatus(const std::string &name) const
Return the status of a given cost name.
std::size_t get_nu() const
Return the dimension of the control input.
Abstract class for the state representation.
Definition: state-base.hpp:46
friend std::ostream & operator<<(std::ostream &os, const CostItemTpl< Scalar > &model)
Print information on the cost item.
Definition: cost-sum.hpp:40