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, std::shared_ptr<CostModelAbstract> cost,
33  const Scalar weight, const bool active = true)
34  : name(name), cost(cost), weight(weight), active(active) {}
35 
39  friend std::ostream& operator<<(std::ostream& os,
40  const CostItemTpl<Scalar>& model) {
41  os << "{w=" << model.weight << ", " << *model.cost << "}";
42  return os;
43  }
44 
45  std::string name;
46  std::shared_ptr<CostModelAbstract> cost;
47  Scalar weight;
48  bool active;
49 };
50 
72 template <typename _Scalar>
74  public:
75  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
76 
77  typedef _Scalar Scalar;
85  typedef typename MathBase::VectorXs VectorXs;
86  typedef typename MathBase::MatrixXs MatrixXs;
87 
88  typedef std::map<std::string, std::shared_ptr<CostItem> > CostModelContainer;
89  typedef std::map<std::string, std::shared_ptr<CostDataAbstract> >
90  CostDataContainer;
91 
98  CostModelSumTpl(std::shared_ptr<StateAbstract> state, const std::size_t nu);
99 
107  explicit CostModelSumTpl(std::shared_ptr<StateAbstract> state);
108  ~CostModelSumTpl();
109 
118  void addCost(const std::string& name, std::shared_ptr<CostModelAbstract> cost,
119  const Scalar weight, const bool active = true);
120 
126  void removeCost(const std::string& name);
127 
134  void changeCostStatus(const std::string& name, const bool active);
135 
143  void calc(const std::shared_ptr<CostDataSum>& data,
144  const Eigen::Ref<const VectorXs>& x,
145  const Eigen::Ref<const VectorXs>& u);
146 
157  void calc(const std::shared_ptr<CostDataSum>& data,
158  const Eigen::Ref<const VectorXs>& x);
159 
167  void calcDiff(const std::shared_ptr<CostDataSum>& data,
168  const Eigen::Ref<const VectorXs>& x,
169  const Eigen::Ref<const VectorXs>& u);
170 
183  void calcDiff(const std::shared_ptr<CostDataSum>& data,
184  const Eigen::Ref<const VectorXs>& x);
185 
197  std::shared_ptr<CostDataSum> createData(DataCollectorAbstract* const data);
198 
202  const std::shared_ptr<StateAbstract>& get_state() const;
203 
207  const CostModelContainer& get_costs() const;
208 
212  std::size_t get_nu() const;
213 
217  std::size_t get_nr() const;
218 
222  std::size_t get_nr_total() const;
223 
227  const std::set<std::string>& get_active_set() const;
228 
232  const std::set<std::string>& get_inactive_set() const;
233 
234  DEPRECATED(
235  "get_active() is deprecated and will be replaced with get_active_set()",
236  const std::vector<std::string>& get_active() {
237  active_.clear();
238  active_.reserve(active_set_.size());
239  for (const auto& contact : active_set_) {
240  active_.push_back(contact);
241  }
242  return active_;
243  };)
244 
245  DEPRECATED(
246  "get_inactive() is deprecated and will be replaced with "
247  "get_inactive_set()",
248  const std::vector<std::string>& get_inactive() {
249  inactive_.clear();
250  inactive_.reserve(inactive_set_.size());
251  for (const auto& contact : inactive_set_) {
252  inactive_.push_back(contact);
253  }
254  return inactive_;
255  };)
256 
262  bool getCostStatus(const std::string& name) const;
263 
267  template <class Scalar>
268  friend std::ostream& operator<<(std::ostream& os,
269  const CostModelSumTpl<Scalar>& model);
270 
271  private:
272  std::shared_ptr<StateAbstract> state_;
273  CostModelContainer costs_;
274  std::size_t nu_;
275  std::size_t nr_;
276  std::size_t nr_total_;
277  std::set<std::string> active_set_;
278  std::set<std::string>
279  inactive_set_;
280 
281  // Vector variants. These are to maintain the API compatibility for the
282  // deprecated syntax. These will be removed in future versions along with
283  // get_active() / get_inactive()
284  std::vector<std::string> active_;
285  std::vector<std::string> inactive_;
286 };
287 
288 template <typename _Scalar>
290  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
291 
292  typedef _Scalar Scalar;
296  typedef typename MathBase::VectorXs VectorXs;
297  typedef typename MathBase::MatrixXs MatrixXs;
298 
299  template <template <typename Scalar> class Model>
300  CostDataSumTpl(Model<Scalar>* const model, DataCollectorAbstract* const data)
301  : Lx_internal(model->get_state()->get_ndx()),
302  Lu_internal(model->get_nu()),
303  Lxx_internal(model->get_state()->get_ndx(),
304  model->get_state()->get_ndx()),
305  Lxu_internal(model->get_state()->get_ndx(), model->get_nu()),
306  Luu_internal(model->get_nu(), model->get_nu()),
307  shared(data),
308  cost(Scalar(0.)),
309  Lx(Lx_internal.data(), model->get_state()->get_ndx()),
310  Lu(Lu_internal.data(), model->get_nu()),
311  Lxx(Lxx_internal.data(), model->get_state()->get_ndx(),
312  model->get_state()->get_ndx()),
313  Lxu(Lxu_internal.data(), model->get_state()->get_ndx(),
314  model->get_nu()),
315  Luu(Luu_internal.data(), model->get_nu(), model->get_nu()) {
316  Lx.setZero();
317  Lu.setZero();
318  Lxx.setZero();
319  Lxu.setZero();
320  Luu.setZero();
322  it = model->get_costs().begin();
323  it != model->get_costs().end(); ++it) {
324  const std::shared_ptr<CostItem>& item = it->second;
325  costs.insert(std::make_pair(item->name, item->cost->createData(data)));
326  }
327  }
328 
329  template <class ActionData>
330  void shareMemory(ActionData* const data) {
331  // Save memory by setting the internal variables with null dimension
332  Lx_internal.resize(0);
333  Lu_internal.resize(0);
334  Lxx_internal.resize(0, 0);
335  Lxu_internal.resize(0, 0);
336  Luu_internal.resize(0, 0);
337  // Share memory with the differential action data
338  new (&Lx) Eigen::Map<VectorXs>(data->Lx.data(), data->Lx.size());
339  new (&Lu) Eigen::Map<VectorXs>(data->Lu.data(), data->Lu.size());
340  new (&Lxx) Eigen::Map<MatrixXs>(data->Lxx.data(), data->Lxx.rows(),
341  data->Lxx.cols());
342  new (&Lxu) Eigen::Map<MatrixXs>(data->Lxu.data(), data->Lxu.rows(),
343  data->Lxu.cols());
344  new (&Luu) Eigen::Map<MatrixXs>(data->Luu.data(), data->Luu.rows(),
345  data->Luu.cols());
346  }
347 
348  VectorXs get_Lx() const { return Lx; }
349  VectorXs get_Lu() const { return Lu; }
350  MatrixXs get_Lxx() const { return Lxx; }
351  MatrixXs get_Lxu() const { return Lxu; }
352  MatrixXs get_Luu() const { return Luu; }
353 
354  void set_Lx(const VectorXs& _Lx) {
355  if (Lx.size() != _Lx.size()) {
356  throw_pretty(
357  "Invalid argument: " << "Lx has wrong dimension (it should be " +
358  std::to_string(Lx.size()) + ")");
359  }
360  Lx = _Lx;
361  }
362  void set_Lu(const VectorXs& _Lu) {
363  if (Lu.size() != _Lu.size()) {
364  throw_pretty(
365  "Invalid argument: " << "Lu has wrong dimension (it should be " +
366  std::to_string(Lu.size()) + ")");
367  }
368  Lu = _Lu;
369  }
370  void set_Lxx(const MatrixXs& _Lxx) {
371  if (Lxx.rows() != _Lxx.rows() || Lxx.cols() != _Lxx.cols()) {
372  throw_pretty(
373  "Invalid argument: " << "Lxx has wrong dimension (it should be " +
374  std::to_string(Lxx.rows()) + ", " +
375  std::to_string(Lxx.cols()) + ")");
376  }
377  Lxx = _Lxx;
378  }
379  void set_Lxu(const MatrixXs& _Lxu) {
380  if (Lxu.rows() != _Lxu.rows() || Lxu.cols() != _Lxu.cols()) {
381  throw_pretty(
382  "Invalid argument: " << "Lxu has wrong dimension (it should be " +
383  std::to_string(Lxu.rows()) + ", " +
384  std::to_string(Lxu.cols()) + ")");
385  }
386  Lxu = _Lxu;
387  }
388  void set_Luu(const MatrixXs& _Luu) {
389  if (Luu.rows() != _Luu.rows() || Luu.cols() != _Luu.cols()) {
390  throw_pretty(
391  "Invalid argument: " << "Luu has wrong dimension (it should be " +
392  std::to_string(Luu.rows()) + ", " +
393  std::to_string(Luu.cols()) + ")");
394  }
395  Luu = _Luu;
396  }
397 
398  // Creates internal data in case we don't share it externally
399  VectorXs Lx_internal;
400  VectorXs Lu_internal;
401  MatrixXs Lxx_internal;
402  MatrixXs Lxu_internal;
403  MatrixXs Luu_internal;
404 
406  DataCollectorAbstract* shared;
407  Scalar cost;
408  Eigen::Map<VectorXs> Lx;
409  Eigen::Map<VectorXs> Lu;
410  Eigen::Map<MatrixXs> Lxx;
411  Eigen::Map<MatrixXs> Lxu;
412  Eigen::Map<MatrixXs> Luu;
413 };
414 
415 } // namespace crocoddyl
416 
417 /* --- Details -------------------------------------------------------------- */
418 /* --- Details -------------------------------------------------------------- */
419 /* --- Details -------------------------------------------------------------- */
420 #include "crocoddyl/core/costs/cost-sum.hxx"
421 
422 #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:73
void calcDiff(const std::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.
void addCost(const std::string &name, std::shared_ptr< CostModelAbstract > cost, const Scalar weight, const bool active=true)
Add a cost item.
std::shared_ptr< CostDataSum > createData(DataCollectorAbstract *const data)
Create the cost data.
void calc(const std::shared_ptr< CostDataSum > &data, const Eigen::Ref< const VectorXs > &x)
Compute the total cost value for nodes that depends only on the state.
void calc(const std::shared_ptr< CostDataSum > &data, const Eigen::Ref< const VectorXs > &x, const Eigen::Ref< const VectorXs > &u)
Compute the total cost value.
void changeCostStatus(const std::string &name, const bool active)
Change the cost status.
CostModelSumTpl(std::shared_ptr< StateAbstract > state)
Initialize the cost-sum model.
CostModelSumTpl(std::shared_ptr< StateAbstract > state, const std::size_t nu)
Initialize the cost-sum model.
void calcDiff(const std::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.
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.
const std::set< std::string > & get_inactive_set() const
Return the names of the set of inactive costs.
const std::shared_ptr< StateAbstract > & get_state() const
Return the state.
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.
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:39