action.hxx
Go to the documentation of this file.
1 // BSD 3-Clause License
3 //
4 // Copyright (C) 2018-2020, LAAS-CNRS, University of Edinburgh
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
8 
9 #include <cmath>
10 #include <crocoddyl/core/utils/exception.hpp>
11 #include <iostream>
12 
13 #include "action.hpp"
14 
15 namespace sobec {
16 using namespace crocoddyl;
17 template <typename Scalar>
19  boost::shared_ptr<DifferentialActionModelAbstract> model,
20  std::vector<std::string> lpf_joint_names, const Scalar& time_step,
21  const bool& with_cost_residual, const Scalar& fc,
22  const bool& tau_plus_integration, const int& filter)
23  : Base(model->get_state(), model->get_nu(),
24  model->get_nr() + 2 * lpf_joint_names.size()),
25  differential_(model),
26  time_step_(time_step),
27  time_step2_(time_step * time_step),
28  with_cost_residual_(with_cost_residual),
29  fc_(fc),
30  nw_(model->get_nu()),
31  tau_plus_integration_(tau_plus_integration),
32  filter_(filter) {
33  // Downcast DAM state (abstract --> multibody)
34  boost::shared_ptr<StateMultibody> state =
35  boost::static_pointer_cast<StateMultibody>(model->get_state());
36  pin_model_ = state->get_pinocchio();
37  // Check that used-specified LPF joints are valid (no free-flyer) and collect
38  // ids
39  ntau_ = lpf_joint_names.size();
40  for (std::vector<std::string>::iterator iter = lpf_joint_names.begin();
41  iter != lpf_joint_names.end(); ++iter) {
42  std::size_t jointId = pin_model_->getJointId(*iter);
43  std::size_t jointNv = pin_model_->nvs[jointId];
44  if (jointNv != (std::size_t)1) {
45  throw_pretty(
46  "Invalid argument: "
47  << "Joint " << *iter << " has nv=" << jointNv
48  << ". Low-pass filtered joints must have nv=1 in pinocchio model ! ");
49  }
50  lpf_joint_ids_.push_back(static_cast<int>(jointId));
51  }
52  lpf_joint_names_ = lpf_joint_names;
53  // Get lpf torque ids
54  // fixed base
55  if (pin_model_->joints[1].nv() == 1) {
56  for (std::vector<int>::iterator iter = lpf_joint_ids_.begin();
57  iter != lpf_joint_ids_.end(); ++iter) {
58  lpf_torque_ids_.push_back(pin_model_->idx_vs[*iter]);
59  }
60  // floating base
61  } else {
62  for (std::vector<int>::iterator iter = lpf_joint_ids_.begin();
63  iter != lpf_joint_ids_.end(); ++iter) {
64  lpf_torque_ids_.push_back(pin_model_->idx_vs[*iter] -
65  pin_model_->joints[1].nv());
66  }
67  }
68  ny_ = model->get_state()->get_nx() + lpf_torque_ids_.size();
69  // Get NON lpf joint ids
70  for (std::vector<std::string>::iterator joint_names_iter =
71  pin_model_->names.begin();
72  joint_names_iter != pin_model_->names.end(); ++joint_names_iter) {
73  std::vector<std::string>::iterator it = std::find(
74  lpf_joint_names.begin(), lpf_joint_names.end(), *joint_names_iter);
75  if (it == lpf_joint_names.end()) {
76  std::size_t jointId = pin_model_->getJointId(*joint_names_iter);
77  std::size_t jointNv = pin_model_->nvs[jointId];
78  if (jointNv == (std::size_t)1) {
79  non_lpf_joint_ids_.push_back(jointId);
80  }
81  }
82  }
83  // Get NON lpf torque ids
84  // fixed base
85  if (pin_model_->joints[1].nv() == 1) {
86  for (std::vector<int>::iterator iter = non_lpf_joint_ids_.begin();
87  iter != non_lpf_joint_ids_.end(); ++iter) {
88  non_lpf_torque_ids_.push_back(pin_model_->idx_vs[*iter]);
89  }
90  // floating base
91  } else {
92  for (std::vector<int>::iterator iter = non_lpf_joint_ids_.begin();
93  iter != non_lpf_joint_ids_.end(); ++iter) {
94  non_lpf_torque_ids_.push_back(pin_model_->idx_vs[*iter] -
95  pin_model_->joints[1].nv());
96  }
97  }
98  // Instantiate stateLPF using pinocchio model of DAM state
99  state_ = boost::make_shared<StateLPF>(pin_model_, lpf_joint_ids_);
100  // Check stuff
101  if (time_step_ < Scalar(0.)) {
102  time_step_ = Scalar(1e-3);
103  time_step2_ = time_step_ * time_step_;
104  std::cerr << "Warning: dt should be positive, set to 1e-3" << std::endl;
105  }
106  // Compute alpha parameter from fc_
107  compute_alpha(fc_);
108  // init barrier for lim cost
109  VectorXs wlb = state_->get_lb().tail(ntau_);
110  VectorXs wub = state_->get_ub().tail(ntau_);
111  // Base::set_u_lb(wlb);
112  // Base::set_u_ub(wub);
114  boost::make_shared<ActivationModelQuadraticBarrier>(
115  ActivationBounds(wlb, wub));
116  // cost weights are zero by default
117  tauReg_weight_ = Scalar(0.);
118  tauLim_weight_ = Scalar(0.);
119  tauReg_residual_.resize(ntau_);
120  tauLim_residual_.resize(ntau_);
121 }
122 
123 template <typename Scalar>
125 
126 template <typename Scalar>
128  const boost::shared_ptr<ActionDataAbstract>& data,
129  const Eigen::Ref<const VectorXs>& y, const Eigen::Ref<const VectorXs>& w) {
130  const std::size_t& nv = differential_->get_state()->get_nv();
131  const std::size_t& nx = differential_->get_state()->get_nx();
132 
133  if (static_cast<std::size_t>(y.size()) != ny_) {
134  throw_pretty("Invalid argument: "
135  << "y has wrong dimension (it should be " +
136  std::to_string(ny_) + ")");
137  }
138  if (static_cast<std::size_t>(w.size()) != nw_) {
139  throw_pretty("Invalid argument: "
140  << "w has wrong dimension (it should be " +
141  std::to_string(nw_) + ")");
142  }
143 
144  // Static casting the data
145  boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
146  // Extract x=(q,v) and tau from augmented state y
147  const Eigen::Ref<const VectorXs>& x = y.head(nx); // get q,v_q
148 
149 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
150  d->tau_tmp(non_lpf_torque_ids_) =
151  w(non_lpf_torque_ids_); // NON-LPF dimensions
152  d->tau_tmp(lpf_torque_ids_) = y.tail(ntau_); // LPF dimensions
153 #else
154  for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
155  d->tau_tmp(lpf_torque_ids_[i]) = y.tail(ntau_)(i);
156  }
157  for (std::size_t i = 0; i < non_lpf_torque_ids_.size(); i++) {
158  d->tau_tmp(non_lpf_torque_ids_[i]) = w(non_lpf_torque_ids_[i]);
159  }
160 #endif
161 
162  const Eigen::Ref<const VectorXs>& tau = d->tau_tmp;
163  // std::cout << "[lpf.calc] tau = " << tau << std::endl;
164  if (static_cast<std::size_t>(x.size()) != nx) {
165  throw_pretty("Invalid argument: "
166  << "x has wrong dimension (it should be " +
167  std::to_string(nx) + ")");
168  }
169  if (static_cast<std::size_t>(tau.size()) != nw_) {
170  throw_pretty("Invalid argument: "
171  << "tau has wrong dimension (it should be " +
172  std::to_string(nw_) + ")");
173  }
174  if (static_cast<std::size_t>(d->Fy.rows()) !=
175  boost::static_pointer_cast<StateLPF>(state_)->get_ndy()) {
176  throw_pretty(
177  "Invalid argument: "
178  << "Fy.rows() has wrong dimension (it should be " +
179  std::to_string(
180  boost::static_pointer_cast<StateLPF>(state_)->get_ndy()) +
181  ")");
182  }
183  if (static_cast<std::size_t>(d->Fy.cols()) !=
184  boost::static_pointer_cast<StateLPF>(state_)->get_ndy()) {
185  throw_pretty(
186  "Invalid argument: "
187  << "Fy.cols() has wrong dimension (it should be " +
188  std::to_string(
189  boost::static_pointer_cast<StateLPF>(state_)->get_ndy()) +
190  ")");
191  }
192  if (static_cast<std::size_t>(d->Fw.cols()) != nw_) {
193  throw_pretty("Invalid argument: "
194  << "Fw.cols() has wrong dimension (it should be " +
195  std::to_string(nw_) + ")");
196  }
197  if (static_cast<std::size_t>(d->r.size()) !=
198  differential_->get_nr() + 2 * ntau_) {
199  throw_pretty("Invalid argument: "
200  << "r has wrong dimension (it should be " +
201  std::to_string(differential_->get_nr() + 2 * ntau_) +
202  ")");
203  }
204  if (static_cast<std::size_t>(d->Ly.size()) !=
205  boost::static_pointer_cast<StateLPF>(state_)->get_ndy()) {
206  throw_pretty(
207  "Invalid argument: "
208  << "Ly has wrong dimension (it should be " +
209  std::to_string(
210  boost::static_pointer_cast<StateLPF>(state_)->get_ndy()) +
211  ")");
212  }
213  if (static_cast<std::size_t>(d->Lw.size()) != nw_) {
214  throw_pretty("Invalid argument: "
215  << "Lw has wrong dimension (it should be " +
216  std::to_string(nw_) + ")");
217  }
218 
219  // Compute acceleration and cost (DAM, i.e. CT model)
220  // explicit scheme "tau integration"
221  // a_q, cost = DAM(q, v_q, tau_q)
222  if (!tau_plus_integration_) {
223  differential_->calc(d->differential, x, tau);
224  // explicit scheme "tau+ integration"
225  // a_q, cost = DAM(q, v_q, tau_q+)
226  } else {
227  const Eigen::Ref<const VectorXs>& tau_plus =
228  alpha_ * tau + (1 - alpha_) * w;
229  differential_->calc(d->differential, x, tau_plus);
230  }
231 
232  // Computing the next state x+ = x + dx and cost+ = dt*cost
233  const Eigen::VectorBlock<const Eigen::Ref<const VectorXs>, Eigen::Dynamic> v =
234  x.tail(nv);
235  const VectorXs& a = d->differential->xout;
236  // dq(a_q, dt) & dv_q(a_q, dt)
237  d->dy.head(nv).noalias() = v * time_step_ + a * time_step2_;
238  d->dy.segment(nv, nv).noalias() = a * time_step_;
239 
240  // Update dtau from LPF ids
241 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
242  d->dy.tail(ntau_) = ((1 - alpha_) * (w - tau))(lpf_torque_ids_);
243 #else
244  for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
245  d->dy.tail(ntau_)(i) = ((1 - alpha_) * (w - tau))(lpf_torque_ids_[i]);
246  }
247 #endif
248 
249  // integrate using stateLPF rule : tau+ = tau + dtau(tau, w)
250  state_->integrate(y, d->dy, d->ynext);
251  // get cost+ from cost
252  d->cost = time_step_ * d->differential->cost;
253 
254  // Add hard-coded cost on unfiltered torque a[r(w)] only at LPF joints
255  // Torque REG
256  if (tauReg_weight_ > 0) {
257 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
258  tauReg_residual_ = w(lpf_torque_ids_) - tauReg_reference_;
259 #else
260  for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
261  tauReg_residual_(i) = w(lpf_torque_ids_[i]) - tauReg_reference_(i);
262  }
263 #endif
264  // add to cost
265  d->cost += Scalar(0.5 * time_step_ * tauReg_weight_ *
266  tauReg_residual_.transpose() * tauReg_residual_);
267  }
268  // Torque LIM
269  if (tauLim_weight_ > 0) {
270 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
271  activation_model_tauLim_->calc(
272  d->activation,
273  w(lpf_torque_ids_)); // Compute limit cost torque residual of w
274  tauLim_residual_ = w(lpf_torque_ids_);
275 #else
276  for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
277  tauLim_residual_(i) = w(lpf_torque_ids_[i]);
278  }
279  activation_model_tauLim_->calc(d->activation, tauLim_residual_);
280 #endif
281  // add to cost
282  d->cost += Scalar(0.5 * time_step_ * tauLim_weight_ *
283  d->activation->a_value); // tau lim
284  }
285 
286  // Update RESIDUAL
287  if (with_cost_residual_) {
288  d->r.head(differential_->get_nr()) = d->differential->r;
289 
290  // Add unfiltered torque residuals
291  if (tauReg_weight_ > 0) {
292  d->r.segment(differential_->get_nr(), ntau_) = tauReg_residual_;
293  }
294  if (tauLim_weight_ > 0) {
295  d->r.tail(ntau_) = tauLim_residual_;
296  }
297  }
298 } // calc
299 
300 template <typename Scalar>
302  const boost::shared_ptr<ActionDataAbstract>& data,
303  const Eigen::Ref<const VectorXs>& y) {
304  const std::size_t& nv = differential_->get_state()->get_nv();
305  const std::size_t& nx = differential_->get_state()->get_nx();
306 
307  if (static_cast<std::size_t>(y.size()) != ny_) {
308  throw_pretty("Invalid argument: "
309  << "y has wrong dimension (it should be " +
310  std::to_string(ny_) + ")");
311  }
312 
313  // Static casting the data
314  boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
315  // Extract x=(q,v) and tau from augmented state y
316  const Eigen::Ref<const VectorXs>& x = y.head(nx); // get q,v_q
317 
318  // Compute acceleration and cost (DAM, i.e. CT model)
319  differential_->calc(d->differential, x);
320  d->dy.setZero();
321  // d->ynext = y;
322  d->cost = d->differential->cost;
323  // Update RESIDUAL
324  if (with_cost_residual_) {
325  d->r.head(differential_->get_nr()) = d->differential->r;
326  }
327 } // calc
328 
329 template <typename Scalar>
331  const boost::shared_ptr<ActionDataAbstract>& data,
332  const Eigen::Ref<const VectorXs>& y, const Eigen::Ref<const VectorXs>& w) {
333  const std::size_t& nv = differential_->get_state()->get_nv();
334  const std::size_t& nx = differential_->get_state()->get_nx();
335  const std::size_t& ndx = differential_->get_state()->get_ndx();
336 
337  if (static_cast<std::size_t>(y.size()) != ny_) {
338  throw_pretty("Invalid argument: "
339  << "y has wrong dimension (it should be " +
340  std::to_string(ny_) + ")");
341  }
342  if (static_cast<std::size_t>(w.size()) != nw_) {
343  throw_pretty("Invalid argument: "
344  << "w has wrong dimension (it should be " +
345  std::to_string(nw_) + ")");
346  }
347 
348  // Static casting the data
349  boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
350 
351  // Computing the derivatives for the time-continuous model (i.e. differential
352  // model)
353  // Extract x=(q,v) and tau from augmented state y
354  const Eigen::Ref<const VectorXs>& x = y.head(nx); // get q,v_q
355  // d->tau_tmp = w; // Initialize torques from unfiltered input
356 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
357  d->tau_tmp(non_lpf_torque_ids_) =
358  w(non_lpf_torque_ids_); // NON-LPF dimensions
359  d->tau_tmp(lpf_torque_ids_) = y.tail(ntau_); // LPF dimensions
360 #else
361  for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
362  d->tau_tmp(lpf_torque_ids_[i]) = y.tail(ntau_)(i);
363  }
364  for (std::size_t i = 0; i < non_lpf_torque_ids_.size(); i++) {
365  d->tau_tmp(non_lpf_torque_ids_[i]) = w(non_lpf_torque_ids_[i]);
366  }
367 #endif
368  const Eigen::Ref<const VectorXs>& tau = d->tau_tmp;
369 
370  // TAU INTEGRATION
371  if (!tau_plus_integration_) {
372  // Get partials of CT model a_q ('f'), cost w.r.t. (q,v,tau)
373  differential_->calcDiff(d->differential, x, tau);
374 
375  // Get cost lim w derivatives
376  if (tauLim_weight_ > 0) {
377 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
378  activation_model_tauLim_->calcDiff(d->activation, w(lpf_torque_ids_));
379 #else
380  for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
381  tauLim_residual_(i) = w(lpf_torque_ids_[i]);
382  }
383  activation_model_tauLim_->calcDiff(d->activation, tauLim_residual_);
384 #endif
385  } // tauLim_weight_ != 0
386 
387  // Fill RUNNING MODELS partials of (y+,cost+) w.r.t. (y,w)
388  const MatrixXs& da_dx = d->differential->Fx;
389  const MatrixXs& da_du = d->differential->Fu;
390  // d(x+)/dy
391  d->Fy.block(0, 0, nv, ndx).noalias() = da_dx * time_step2_;
392  d->Fy.block(nv, 0, nv, ndx).noalias() = da_dx * time_step_;
393  d->Fy.block(0, nv, nv, nv).diagonal().array() += Scalar(time_step_);
394 
395  // Partial blocks of LPF dimensions due y+ dependency on tau
396 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
397  d->Fy.block(0, ndx, nv, ntau_).noalias() =
398  da_du(Eigen::all, lpf_torque_ids_) * time_step2_;
399  d->Fy.block(nv, ndx, nv, ntau_).noalias() =
400  da_du(Eigen::all, lpf_torque_ids_) * time_step_;
401 #else
402  for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
403  d->Fy.block(0, ndx, nv, ntau_).col(i).noalias() =
404  da_du.col(lpf_torque_ids_[i]) * time_step2_;
405  d->Fy.block(nv, ndx, nv, ntau_).col(i).noalias() =
406  da_du.col(lpf_torque_ids_[i]) * time_step_;
407  }
408 #endif
409  // LPF partial block
410  d->Fy.bottomRightCorner(ntau_, ntau_).diagonal().array() = Scalar(alpha_);
411 
412  state_->JintegrateTransport(y, d->dy, d->Fy, second);
413  state_->Jintegrate(
414  y, d->dy, d->Fy, d->Fy, first,
415  addto); // add identity to Fx = d(x+dx)/dx = d(q,v)/d(q,v)
416  // !!! remove identity from Ftau (due to stateLPF.Jintegrate) !!!
417  d->Fy.bottomRightCorner(ntau_, ntau_).diagonal().array() -= Scalar(1.);
418 
419  // d(y+)/dw : the "non-LPF" dimensions cause the next state to depend
420  // directly on the input w since in those dimensions we have tau = w . So we
421  // fill the partials w.r.t. w accordingly
422  d->Fw.setZero();
423 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
424  d->Fw.topRows(nv)(Eigen::all, non_lpf_torque_ids_).noalias() =
425  da_du(Eigen::all, non_lpf_torque_ids_) * time_step2_;
426  d->Fw.block(nv, 0, nv, nw_)(Eigen::all, non_lpf_torque_ids_).noalias() =
427  da_du(Eigen::all, non_lpf_torque_ids_) * time_step_;
428  d->Fw.bottomRows(ntau_)(Eigen::all, lpf_torque_ids_).diagonal().array() +=
429  Scalar(1 - alpha_);
430 #else
431  for (std::size_t i = 0; i < non_lpf_torque_ids_.size(); i++) {
432  d->Fw.topRows(nv).col(non_lpf_torque_ids_[i]).noalias() =
433  da_du.col(non_lpf_torque_ids_[i]) * time_step2_;
434  d->Fw.block(nv, 0, nv, nw_).col(non_lpf_torque_ids_[i]).noalias() =
435  da_du.col(non_lpf_torque_ids_[i]) * time_step_;
436  }
437  for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
438  d->Fw.bottomRows(ntau_)(i, lpf_torque_ids_[i]) += Scalar(1 - alpha_);
439  }
440 #endif
441  // LPF partial
442  // d->Fw.bottomRows(ntau_).diagonal().array() += Scalar(1 - alpha_);
443  state_->JintegrateTransport(y, d->dy, d->Fw, second);
444 
445  // d(cost+)/dy
446  d->Ly.head(ndx).noalias() = time_step_ * d->differential->Lx;
447  // Partial blocks for LPF dimensions
448  d->Lyy.topLeftCorner(ndx, ndx).noalias() =
449  time_step_ * d->differential->Lxx;
450 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
451  d->Ly.tail(ntau_).noalias() =
452  time_step_ * d->differential->Lu(lpf_torque_ids_);
453  d->Lyy.block(0, ndx, ndx, ntau_).noalias() =
454  time_step_ * d->differential->Lxu(Eigen::all, lpf_torque_ids_);
455  d->Lyy.block(ndx, 0, ntau_, ndx).noalias() =
456  time_step_ *
457  d->differential->Lxu.transpose()(lpf_torque_ids_, Eigen::all);
458  d->Lyy.bottomRightCorner(ntau_, ntau_).noalias() =
459  time_step_ * d->differential->Luu(lpf_torque_ids_, lpf_torque_ids_);
460 #else
461  for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
462  d->Ly.tail(ntau_)(i) =
463  time_step_ * d->differential->Lu(lpf_torque_ids_[i]);
464  d->Lyy.block(0, ndx, ndx, ntau_).col(i).noalias() =
465  time_step_ * d->differential->Lxu.col(lpf_torque_ids_[i]);
466  d->Lyy.block(ndx, 0, ntau_, ndx).row(i).noalias() =
467  time_step_ * d->differential->Lxu.transpose().row(lpf_torque_ids_[i]);
468  for (std::size_t j = 0; j < lpf_torque_ids_.size(); j++) {
469  d->Lyy.bottomRightCorner(ntau_, ntau_)(i, j) =
470  time_step_ *
471  d->differential->Luu(lpf_torque_ids_[i], lpf_torque_ids_[j]);
472  }
473  }
474 #endif
475 
476  // Partials blocks for non-LPF dimensions
477  d->Lw.setZero();
478  d->Lyw.setZero();
479  d->Lww.setZero();
480 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
481  d->Lw(non_lpf_torque_ids_).noalias() =
482  time_step_ * d->differential->Lu(non_lpf_torque_ids_);
483  d->Lyw.topRows(ndx)(Eigen::all, non_lpf_torque_ids_).noalias() =
484  time_step_ * d->differential->Lxu(Eigen::all, non_lpf_torque_ids_);
485  d->Lyw.bottomRows(ntau_)(Eigen::all, non_lpf_torque_ids_).noalias() =
486  time_step_ * d->differential->Luu(lpf_torque_ids_, non_lpf_torque_ids_);
487  d->Lww(non_lpf_torque_ids_, non_lpf_torque_ids_).noalias() =
488  time_step_ *
489  d->differential->Luu(non_lpf_torque_ids_, non_lpf_torque_ids_);
490 #else
491  for (std::size_t i = 0; i < non_lpf_torque_ids_.size(); i++) {
492  d->Lw(non_lpf_torque_ids_[i]) =
493  time_step_ * d->differential->Lu(non_lpf_torque_ids_[i]);
494  d->Lyw.topRows(ndx).col(non_lpf_torque_ids_[i]).noalias() =
495  time_step_ * d->differential->Lxu.col(non_lpf_torque_ids_[i]);
496  for (std::size_t j = 0; j < non_lpf_torque_ids_.size(); j++) {
497  d->Lww(non_lpf_torque_ids_[i], non_lpf_torque_ids_[j]) =
498  time_step_ * d->differential->Luu(non_lpf_torque_ids_[i],
499  non_lpf_torque_ids_[j]);
500  }
501  for (std::size_t j = 0; j < lpf_torque_ids_.size(); j++) {
502  d->Lyw.bottomRows(ntau_)(j, non_lpf_torque_ids_[i]) =
503  time_step_ *
504  d->differential->Luu(lpf_torque_ids_[j], non_lpf_torque_ids_[i]);
505  }
506  }
507 #endif
508 
509  // Partials of hard-coded cost+(tauReg) & cost+(tauLim) w.r.t. (y,w)
510  if (tauReg_weight_ > 0) {
511 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
512  d->Lw(lpf_torque_ids_) +=
513  time_step_ * tauReg_weight_ *
514  d->r.segment(differential_->get_nr(), ntau_); // tau reg
515  d->Lww.diagonal().array()(lpf_torque_ids_) +=
516  Scalar(time_step_ * tauReg_weight_); // tau reg
517 #else
518  for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
519  d->Lw(lpf_torque_ids_[i]) +=
520  time_step_ * tauReg_weight_ *
521  d->r(differential_->get_nr() + i); // tau reg
522  d->Lww.diagonal().array()(lpf_torque_ids_[i]) +=
523  Scalar(time_step_ * tauReg_weight_); // tau reg
524  }
525 #endif
526  } // tauReg !=0
527  if (tauLim_weight_ > 0) {
528 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
529  d->Lw(lpf_torque_ids_) +=
530  time_step_ * tauLim_weight_ * d->activation->Ar; // tau lim
531  d->Lww.diagonal()(lpf_torque_ids_) +=
532  time_step_ * tauLim_weight_ *
533  d->activation->Arr.diagonal(); // tau lim
534 #else
535  for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
536  d->Lw(lpf_torque_ids_[i]) +=
537  time_step_ * tauLim_weight_ * d->activation->Ar(i); // tau lim
538  d->Lww.diagonal()(lpf_torque_ids_[i]) +=
539  time_step_ * tauLim_weight_ *
540  d->activation->Arr.diagonal()(i); // tau lim
541  }
542 #endif
543  } // tauLim !=0
544  } // tau integration
545 
546  // // TAU PLUS INTEGRATION
547  // else {
548  // // get tau_q+ from (tau_q, w)
549  // const Eigen::Ref<const VectorXs>& tau_plus =
550  // alpha_ * tau + (1 - alpha_) * w;
551  // // Get partials of CT model a_q ('f'), cost w.r.t. (q,v,tau+)
552  // differential_->calcDiff(d->differential, x, tau_plus);
553  // // Get cost lim w
554  // if (!is_terminal_) {
555  // activation_model_tauLim_->calcDiff(d->activation, w);
556  // }
557  // // Fill out partials of IAM
558  // if (enable_integration_) {
559  // const MatrixXs& da_dx = d->differential->Fx;
560  // const MatrixXs& da_du = d->differential->Fu;
561  // d->Fy.block(0, 0, nv, ndx).noalias() = da_dx * time_step2_;
562  // d->Fy.block(nv, 0, nv, ndx).noalias() = da_dx * time_step_;
563  // #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
564  // d->Fy.block(0, ndx, nv, ntau_).noalias() =
565  // alpha_ * alpha_ * da_du(Eigen::all, lpf_torque_ids_) *
566  // time_step2_;
567  // d->Fy.block(nv, ndx, nv, ntau_).noalias() =
568  // alpha_ * da_du(Eigen::all, lpf_torque_ids_) * time_step_;
569  // #else
570  // for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
571  // d->Fy.block(0, ndx, nv, ntau_).col(i).noalias() =
572  // alpha_ * alpha_ * da_du.col(lpf_torque_ids_[i]) * time_step2_;
573  // d->Fy.block(nv, ndx, nv, ntau_).col(i).noalias() =
574  // alpha_ * da_du.col(lpf_torque_ids_[i]) * time_step_;
575  // }
576  // #endif
577  // d->Fy.block(0, nv, nv, nv).diagonal().array() +=
578  // Scalar(time_step_); // dt*identity top row middle col (eq.
579  // // Jsecond = d(xnext)/d(dx))
580  // // d->Fy.topLeftCorner(nx, nx).diagonal().array() += Scalar(1.); //
581  // // managed by Jintegrate (eq. Jsecond = d(xnext)/d(dx))
582  // d->Fy.bottomRightCorner(ntau_, ntau_).diagonal().array() =
583  // Scalar(alpha_); d->Fw.topRows(nv).noalias() = da_du * time_step2_ *
584  // (1 - alpha_);
585  // #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
586  // d->Fw.block(nv, 0, nv, ntau_).noalias() =
587  // da_du(Eigen::all, lpf_torque_ids_) * time_step_ * (1 - alpha_);
588  // #else
589  // for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
590  // d->Fw.block(nv, 0, nv, ntau_).col(i).noalias() =
591  // da_du.col(lpf_torque_ids_[i]) * time_step_ * (1 - alpha_);
592  // }
593  // #endif
594  // d->Fw.bottomRows(nv).diagonal().array() = Scalar(1 - alpha_);
595  // state_->JintegrateTransport(y, d->dy, d->Fy, second); // it this
596  // correct? state_->Jintegrate(y, d->dy, d->Fy, d->Fy, first,
597  // addto); // for d(x+dx)/d(x)
598  // d->Fy.bottomRightCorner(ntau_, ntau_).diagonal().array() -=
599  // Scalar(1.); // remove identity from Ftau (due to
600  // stateLPF.Jintegrate)
601  // state_->JintegrateTransport(y, d->dy, d->Fw, second); // it this
602  // correct? d->Ly.head(ndx).noalias() = time_step_ *
603  // d->differential->Lx;
604  // #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
605  // d->Ly.tail(ntau_).noalias() =
606  // alpha_ * time_step_ * d->differential->Lu(lpf_torque_ids_);
607 
608  // #else
609  // for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
610  // d->Ly.tail(ntau_)(i) =
611  // alpha_ * time_step_ * d->differential->Lu(lpf_torque_ids_[i]);
612  // }
613  // #endif
614  // d->Lw.noalias() = (1 - alpha_) * time_step_ * d->differential->Lu;
615  // d->Lyy.topLeftCorner(ndx, ndx).noalias() =
616  // time_step_ * d->differential->Lxx;
617  // #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
618  // d->Lyy.block(0, ndx, ndx, ntau_).noalias() =
619  // alpha_ * time_step_ *
620  // d->differential->Lxu(Eigen::all, lpf_torque_ids_);
621  // d->Lyy.block(ndx, 0, ntau_, ndx).noalias() =
622  // alpha_ * time_step_ *
623  // d->differential->Lxu.transpose()(lpf_torque_ids_, Eigen::all);
624  // d->Lyy.bottomRightCorner(ntau_, ntau_).noalias() =
625  // alpha_ * alpha_ * time_step_ *
626  // d->differential->Luu(lpf_torque_ids_, lpf_torque_ids_);
627  // d->Lyw.topRows(ndx).noalias() =
628  // (1 - alpha_) * time_step_ *
629  // d->differential->Lxu(Eigen::all, lpf_torque_ids_);
630  // d->Lyw.bottomRows(ntau_).noalias() =
631  // (1 - alpha_) * alpha_ * time_step_ *
632  // d->differential->Luu(lpf_torque_ids_, lpf_torque_ids_);
633  // #else
634  // for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
635  // d->Lyy.block(0, ndx, ndx, ntau_).col(i).noalias() =
636  // alpha_ * time_step_ *
637  // d->differential->Lxu.col(lpf_torque_ids_[i]);
638  // d->Lyy.block(ndx, 0, ntau_, ndx).row(i).noalias() =
639  // alpha_ * time_step_ *
640  // d->differential->Lxu.transpose().row(lpf_torque_ids_[i]);
641  // d->Lyw.topRows(ndx).col(i).noalias() =
642  // (1 - alpha_) * time_step_ *
643  // d->differential->Lxu.col(lpf_torque_ids_[i]);
644  // for (std::size_t j = 0; j < lpf_torque_ids_.size(); j++) {
645  // d->Lyy.bottomRightCorner(ntau_, ntau_)(i, j) =
646  // alpha_ * alpha_ * time_step_ *
647  // d->differential->Luu(lpf_torque_ids_[i], lpf_torque_ids_[j]);
648  // d->Lyw.bottomRows(ntau_)(i, j) =
649  // (1 - alpha_) * alpha_ * time_step_ *
650  // d->differential->Luu(lpf_torque_ids_[i], lpf_torque_ids_[j]);
651  // }
652  // }
653  // #endif
654  // d->Lww.noalias() =
655  // (1 - alpha_) * (1 - alpha_) * time_step_ * d->differential->Luu;
656  // // Add partials related to unfiltered torque costs w_reg, w_lim (only
657  // for
658  // // running models)
659  // if (!is_terminal_) {
660  // // Torque reg and lim
661  // d->Lw.noalias() =
662  // time_step_ * tauReg_weight_ *
663  // d->r.segment(differential_->get_nr(), nw_); // tau reg
664  // d->Lw.noalias() +=
665  // time_step_ * tauLim_weight_ * d->activation->Ar; // tau lim
666  // d->Lww.diagonal().array() = Scalar(time_step_ * tauReg_weight_); //
667  // reg d->Lww.diagonal() +=
668  // time_step_ * tauLim_weight_ * d->activation->Arr.diagonal(); //
669  // lim
670  // }
671 
672  // } else {
673  // // state_->Jintegrate(y, d->dy, d->Fy, d->Fy);
674  // d->Fw.setZero();
675  // d->Ly.head(ndx).noalias() = d->differential->Lx;
676 
677  // #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
678  // d->Ly.tail(ntau_).noalias() =
679  // alpha_ * d->differential->Lu(lpf_torque_ids_);
680  // d->Lw.noalias() = (1 - alpha_) * d->differential->Lu;
681  // d->Lyy.topLeftCorner(ndx, ndx).noalias() = d->differential->Lxx;
682  // d->Lyy.block(0, ndx, ndx, ntau_).noalias() =
683  // alpha_ * d->differential->Lxu(Eigen::all, lpf_torque_ids_);
684  // d->Lyy.block(ndx, 0, ntau_, ndx).noalias() =
685  // alpha_ *
686  // d->differential->Lxu.transpose()(lpf_torque_ids_, Eigen::all);
687  // d->Lyy.bottomRightCorner(ntau_, ntau_).noalias() =
688  // alpha_ * alpha_ *
689  // d->differential->Luu(lpf_torque_ids_, lpf_torque_ids_);
690  // d->Lyw.topRows(ndx).noalias() = (1 - alpha_) * d->differential->Lxu;
691  // d->Lyw.bottomRows(ntau_).noalias() =
692  // (1 - alpha_) * alpha_ *
693  // d->differential->Luu(lpf_torque_ids_, lpf_torque_ids_);
694  // #else
695  // for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
696  // d->Ly.tail(ntau_)(i) = alpha_ *
697  // d->differential->Lu(lpf_torque_ids_[i]); d->Lw.noalias() = (1 -
698  // alpha_) * d->differential->Lu; d->Lyy.topLeftCorner(ndx,
699  // ndx).noalias() = d->differential->Lxx; d->Lyy.block(0, ndx, ndx,
700  // ntau_).col(i).noalias() =
701  // alpha_ * d->differential->Lxu.col(lpf_torque_ids_[i]);
702  // d->Lyy.block(ndx, 0, ntau_, ndx).row(i).noalias() =
703  // alpha_ *
704  // d->differential->Lxu.transpose().row(lpf_torque_ids_[i]);
705  // d->Lyw.topRows(ndx).noalias() = (1 - alpha_) *
706  // d->differential->Lxu; for (std::size_t j = 0; j <
707  // lpf_torque_ids_.size(); j++) {
708  // d->Lyy.bottomRightCorner(ntau_, ntau_)(i, j) =
709  // alpha_ * alpha_ *
710  // d->differential->Luu(lpf_torque_ids_[i], lpf_torque_ids_[j]);
711  // d->Lyw.bottomRows(ntau_)(i, j) =
712  // (1 - alpha_) * alpha_ *
713  // d->differential->Luu(lpf_torque_ids_[i], lpf_torque_ids_[j]);
714  // }
715  // }
716  // #endif
717  // d->Lww.noalias() = (1 - alpha_) * (1 - alpha_) *
718  // d->differential->Luu;
719  // // Add partials related to unfiltered torque costs w_reg, w_lim (only
720  // for
721  // // running models)
722  // if (!is_terminal_) {
723  // d->Lw.noalias() += tauReg_weight_ *
724  // d->r.segment(differential_->get_nr(), ntau_); //
725  // reg
726  // d->Lw.noalias() += tauLim_weight_ * d->activation->Ar; // lim
727  // d->Lww.diagonal().array() += Scalar(tauReg_weight_); // tau reg
728  // d->Lww.diagonal() +=
729  // tauLim_weight_ * d->activation->Arr.diagonal(); // tau lim
730  // }
731  // }
732  // } // tau_plus_integration
733 }
734 
735 template <typename Scalar>
737  const boost::shared_ptr<ActionDataAbstract>& data,
738  const Eigen::Ref<const VectorXs>& y) {
739  const std::size_t& nv = differential_->get_state()->get_nv();
740  const std::size_t& nx = differential_->get_state()->get_nx();
741  const std::size_t& ndx = differential_->get_state()->get_ndx();
742 
743  if (static_cast<std::size_t>(y.size()) != ny_) {
744  throw_pretty("Invalid argument: "
745  << "y has wrong dimension (it should be " +
746  std::to_string(ny_) + ")");
747  }
748  // Static casting the data
749  boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
750 
751  // Computing the derivatives for the time-continuous model (i.e. differential
752  // model)
753  // Extract x=(q,v) and tau from augmented state y
754  const Eigen::Ref<const VectorXs>& x = y.head(nx); // get q,v_q
755 
756  differential_->calcDiff(d->differential, x);
757 
758  state_->Jintegrate(y, d->dy, d->Fy, d->Fy);
759  // d->Fw.setZero();
760  // d(cost+)/dy
761  d->Ly.head(ndx).noalias() = d->differential->Lx;
762  d->Lyy.topLeftCorner(ndx, ndx).noalias() = d->differential->Lxx;
763  // Partial blocks for LPF dimensions
764 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
765  d->Ly.tail(ntau_).noalias() = d->differential->Lu(lpf_torque_ids_);
766  d->Lyy.block(0, ndx, ndx, ntau_).noalias() =
767  d->differential->Lxu(Eigen::all, lpf_torque_ids_);
768  d->Lyy.block(ndx, 0, ntau_, ndx).noalias() =
769  d->differential->Lxu.transpose()(lpf_torque_ids_, Eigen::all);
770  d->Lyy.bottomRightCorner(ntau_, ntau_).noalias() =
771  d->differential->Luu(lpf_torque_ids_, lpf_torque_ids_);
772 #else
773  for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
774  d->Ly.tail(ntau_)(i) = d->differential->Lu(lpf_torque_ids_[i]);
775  d->Lyy.block(0, ndx, ndx, ntau_).col(i).noalias() =
776  d->differential->Lxu.col(lpf_torque_ids_[i]);
777  d->Lyy.block(ndx, 0, ntau_, ndx).row(i).noalias() =
778  d->differential->Lxu.transpose().row(lpf_torque_ids_[i]);
779  for (std::size_t j = 0; j < lpf_torque_ids_.size(); j++) {
780  d->Lyy.bottomRightCorner(ntau_, ntau_)(i, j) =
781  d->differential->Luu(lpf_torque_ids_[i], lpf_torque_ids_[j]);
782  }
783  }
784 #endif
785 }
786 
787 template <typename Scalar>
788 boost::shared_ptr<ActionDataAbstractTpl<Scalar> >
790  return boost::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this);
791 }
792 
793 template <typename Scalar>
795  const boost::shared_ptr<ActionDataAbstract>& data) {
796  boost::shared_ptr<Data> d = boost::dynamic_pointer_cast<Data>(data);
797  if (data != NULL) {
798  return differential_->checkData(d->differential);
799  } else {
800  return false;
801  }
802 }
803 
804 template <typename Scalar>
805 const boost::shared_ptr<DifferentialActionModelAbstractTpl<Scalar> >&
807  return differential_;
808 }
809 
810 template <typename Scalar>
812  return time_step_;
813 }
814 
815 template <typename Scalar>
817  return fc_;
818 }
819 
820 template <typename Scalar>
822  if (dt < 0.) {
823  throw_pretty("Invalid argument: "
824  << "dt has positive value");
825  }
826  time_step_ = dt;
827  time_step2_ = dt * dt;
828 }
829 
830 template <typename Scalar>
832  // Set the cut-off frequency
833  if (fc <= 0.) {
834  throw_pretty("Invalid argument: "
835  << "fc must be positive");
836  } else {
837  fc_ = fc;
838  }
839 }
840 
841 template <typename Scalar>
843  // Set the cut-off frequency
844  if (alpha < 0. || alpha > 1) {
845  throw_pretty("Invalid argument: "
846  << "alpha must be in [0,1]");
847  } else {
848  alpha_ = alpha;
849  }
850 }
851 
852 template <typename Scalar>
854  // Update alpha parameter
855  if (fc > 0 && time_step_ != 0) {
856  const Scalar& pi = 3.14159;
857  // Exponential Moving Average (EMA) (IIR filter) >> quite sharp
858  if (filter_ == 0) {
859  alpha_ = exp(-2. * pi * fc * time_step_);
860  }
861  // Using the formula "fc = 1/2*pi*RC" ??? >> less sharp
862  if (filter_ == 1) {
863  double omega = 1 / (2. * pi * time_step_ * fc);
864  alpha_ = omega / (omega + 1);
865  }
866  // Exact formula to get fc out of EMA's alpha >> inbetween sharp
867  if (filter_ == 2) {
868  double y = cos(2. * pi * time_step_ * fc);
869  alpha_ = 1 - (y - 1 + sqrt(y * y - 4 * y + 3));
870  }
871  } else {
872  alpha_ = 0;
873  }
874 }
875 
876 template <typename Scalar>
878  boost::shared_ptr<DifferentialActionModelAbstract> model) {
879  const std::size_t& nu = model->get_nu();
880  if (nu_ != nu) {
881  nu_ = nu;
882  unone_ = VectorXs::Zero(nu_);
883  }
884  nr_ = model->get_nr() + 2 * ntau_;
885  state_ = boost::static_pointer_cast<StateLPF>(
886  model->get_state()); // cast StateAbstract from DAM as StateLPF for IAM
887  differential_ = model;
888  Base::set_u_lb(differential_->get_u_lb());
889  Base::set_u_ub(differential_->get_u_ub());
890 }
891 
892 template <typename Scalar>
894  const Scalar& weight, const VectorXs& ref) {
895  if (weight < 0.) {
896  throw_pretty("cost weight is positive ");
897  }
898  if ((std::size_t)ref.size() != (std::size_t)(ntau_)) {
899  throw_pretty("cost ref must have size " << ntau_);
900  }
901  tauReg_weight_ = weight;
902  tauReg_reference_ = ref;
903 }
904 
905 template <typename Scalar>
907  const Scalar& weight) {
908  if (weight < 0.) {
909  throw_pretty("cost weight is positive ");
910  }
911  tauLim_weight_ = weight;
912 }
913 
914 template <typename Scalar>
916  const boost::shared_ptr<ActionDataAbstract>& data, Eigen::Ref<VectorXs> u,
917  const Eigen::Ref<const VectorXs>& x, const std::size_t maxiter,
918  const Scalar tol) {
919  if (static_cast<std::size_t>(u.size()) != nu_) {
920  throw_pretty("Invalid argument: "
921  << "u has wrong dimension (it should be " +
922  std::to_string(nu_) + ")");
923  }
924  if (static_cast<std::size_t>(x.size()) != state_->get_nx()) {
925  throw_pretty("Invalid argument: "
926  << "x has wrong dimension (it should be " +
927  std::to_string(state_->get_nx()) + ")");
928  }
929 
930  // Static casting the data
931  boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
932 
933  differential_->quasiStatic(d->differential, u, x, maxiter, tol);
934 }
935 
936 } // namespace sobec
sobec::IntegratedActionModelLPFTpl::calcDiff
virtual void calcDiff(const boost::shared_ptr< ActionDataAbstract > &data, const Eigen::Ref< const VectorXs > &y, const Eigen::Ref< const VectorXs > &w)
Definition: action.hxx:330
sobec::IntegratedActionModelLPFTpl::ny_
std::size_t ny_
Augmented state dimension : nq+nv+ntau.
Definition: action.hpp:120
sobec::newcontacts::y
@ y
Definition: contact1d.hpp:26
sobec::IntegratedActionModelLPFTpl::get_differential
const boost::shared_ptr< DifferentialActionModelAbstract > & get_differential() const
Definition: action.hxx:806
sobec::IntegratedActionModelLPFTpl::set_differential
void set_differential(boost::shared_ptr< DifferentialActionModelAbstract > model)
Definition: action.hxx:877
sobec::IntegratedActionModelLPFTpl::checkData
virtual bool checkData(const boost::shared_ptr< ActionDataAbstract > &data)
Definition: action.hxx:794
sobec::IntegratedActionModelLPFTpl::get_fc
const Scalar & get_fc() const
Definition: action.hxx:816
sobec::IntegratedActionModelLPFTpl::set_fc
void set_fc(const Scalar &fc)
Definition: action.hxx:831
sobec::IntegratedActionModelLPFTpl::VectorXs
MathBase::VectorXs VectorXs
Definition: action.hpp:36
sobec::IntegratedActionModelLPFTpl::Base
ActionModelAbstractTpl< Scalar > Base
Definition: action.hpp:31
sobec::IntegratedActionModelLPFTpl::calc
virtual void calc(const boost::shared_ptr< ActionDataAbstract > &data, const Eigen::Ref< const VectorXs > &y, const Eigen::Ref< const VectorXs > &w)
Definition: action.hxx:127
sobec::IntegratedActionModelLPFTpl::ActivationBounds
ActivationBoundsTpl< Scalar > ActivationBounds
Definition: action.hpp:43
sobec::IntegratedActionModelLPFTpl::activation_model_tauLim_
boost::shared_ptr< ActivationModelQuadraticBarrier > activation_model_tauLim_
< Model of the state
Definition: action.hpp:125
sobec::IntegratedActionModelLPFTpl::createData
virtual boost::shared_ptr< ActionDataAbstract > createData()
Definition: action.hxx:789
sobec::IntegratedActionModelLPFTpl::set_dt
void set_dt(const Scalar &dt)
Definition: action.hxx:821
sobec::IntegratedActionModelLPFTpl::ntau_
std::size_t ntau_
Filtered torque dimension ("lpf" dimension)
Definition: action.hpp:119
sobec::IntegratedActionModelLPFTpl::Scalar
EIGEN_MAKE_ALIGNED_OPERATOR_NEW typedef _Scalar Scalar
Definition: action.hpp:29
sobec
Definition: activation-quad-ref.hpp:19
sobec::IntegratedActionModelLPFTpl::set_alpha
void set_alpha(const Scalar &alpha)
Definition: action.hxx:842
sobec::newcontacts::x
@ x
Definition: contact1d.hpp:26
sobec::IntegratedActionModelLPFTpl::MatrixXs
MathBase::MatrixXs MatrixXs
Definition: action.hpp:37
sobec::IntegratedActionModelLPFTpl::set_control_reg_cost
void set_control_reg_cost(const Scalar &cost_weight_w_reg, const VectorXs &cost_ref_w_reg)
Definition: action.hxx:893
sobec::IntegratedActionModelLPFTpl::quasiStatic
virtual void quasiStatic(const boost::shared_ptr< ActionDataAbstract > &data, Eigen::Ref< VectorXs > u, const Eigen::Ref< const VectorXs > &x, const std::size_t maxiter=100, const Scalar tol=Scalar(1e-9))
Definition: action.hxx:915
sobec::IntegratedActionModelLPFTpl::~IntegratedActionModelLPFTpl
virtual ~IntegratedActionModelLPFTpl()
Definition: action.hxx:124
sobec::IntegratedActionModelLPFTpl::get_dt
const Scalar & get_dt() const
Definition: action.hxx:811
sobec::IntegratedActionModelLPFTpl::IntegratedActionModelLPFTpl
IntegratedActionModelLPFTpl(boost::shared_ptr< DifferentialActionModelAbstract > model, std::vector< std::string > lpf_joint_names={}, const Scalar &time_step=Scalar(1e-3), const bool &with_cost_residual=true, const Scalar &fc=0, const bool &tau_plus_integration=true, const int &filter=0)
Definition: action.hxx:18
sobec::IntegratedActionModelLPFTpl::set_control_lim_cost
void set_control_lim_cost(const Scalar &cost_weight_w_lim)
Definition: action.hxx:906
action.hpp
sobec::IntegratedActionModelLPFTpl::compute_alpha
void compute_alpha(const Scalar &fc)
Definition: action.hxx:853