10 #include <crocoddyl/core/utils/exception.hpp>
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()),
26 time_step_(time_step),
27 time_step2_(time_step * time_step),
28 with_cost_residual_(with_cost_residual),
31 tau_plus_integration_(tau_plus_integration),
34 boost::shared_ptr<StateMultibody> state =
35 boost::static_pointer_cast<StateMultibody>(model->get_state());
36 pin_model_ = state->get_pinocchio();
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) {
47 <<
"Joint " << *iter <<
" has nv=" << jointNv
48 <<
". Low-pass filtered joints must have nv=1 in pinocchio model ! ");
50 lpf_joint_ids_.push_back(
static_cast<int>(jointId));
52 lpf_joint_names_ = lpf_joint_names;
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]);
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());
68 ny_ = model->get_state()->get_nx() + lpf_torque_ids_.size();
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);
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]);
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());
99 state_ = boost::make_shared<StateLPF>(pin_model_, lpf_joint_ids_);
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;
114 boost::make_shared<ActivationModelQuadraticBarrier>(
117 tauReg_weight_ =
Scalar(0.);
118 tauLim_weight_ =
Scalar(0.);
119 tauReg_residual_.resize(
ntau_);
120 tauLim_residual_.resize(
ntau_);
123 template <
typename Scalar>
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();
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_) +
")");
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_) +
")");
145 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
147 const Eigen::Ref<const VectorXs>&
x =
y.head(nx);
149 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
150 d->tau_tmp(non_lpf_torque_ids_) =
151 w(non_lpf_torque_ids_);
152 d->tau_tmp(lpf_torque_ids_) =
y.tail(ntau_);
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);
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]);
162 const Eigen::Ref<const VectorXs>& tau = d->tau_tmp;
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) +
")");
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_) +
")");
174 if (
static_cast<std::size_t
>(d->Fy.rows()) !=
175 boost::static_pointer_cast<StateLPF>(state_)->get_ndy()) {
178 <<
"Fy.rows() has wrong dimension (it should be " +
180 boost::static_pointer_cast<StateLPF>(state_)->get_ndy()) +
183 if (
static_cast<std::size_t
>(d->Fy.cols()) !=
184 boost::static_pointer_cast<StateLPF>(state_)->get_ndy()) {
187 <<
"Fy.cols() has wrong dimension (it should be " +
189 boost::static_pointer_cast<StateLPF>(state_)->get_ndy()) +
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_) +
")");
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_) +
204 if (
static_cast<std::size_t
>(d->Ly.size()) !=
205 boost::static_pointer_cast<StateLPF>(state_)->get_ndy()) {
208 <<
"Ly has wrong dimension (it should be " +
210 boost::static_pointer_cast<StateLPF>(state_)->get_ndy()) +
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_) +
")");
222 if (!tau_plus_integration_) {
223 differential_->calc(d->differential,
x, tau);
227 const Eigen::Ref<const VectorXs>& tau_plus =
228 alpha_ * tau + (1 - alpha_) * w;
229 differential_->calc(d->differential,
x, tau_plus);
233 const Eigen::VectorBlock<const Eigen::Ref<const VectorXs>, Eigen::Dynamic> v =
235 const VectorXs& a = d->differential->xout;
237 d->dy.head(nv).noalias() = v * time_step_ + a * time_step2_;
238 d->dy.segment(nv, nv).noalias() = a * time_step_;
241 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
242 d->dy.tail(ntau_) = ((1 - alpha_) * (w - tau))(lpf_torque_ids_);
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]);
250 state_->integrate(
y, d->dy, d->ynext);
252 d->cost = time_step_ * d->differential->cost;
256 if (tauReg_weight_ > 0) {
257 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
258 tauReg_residual_ = w(lpf_torque_ids_) - tauReg_reference_;
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);
265 d->cost += Scalar(0.5 * time_step_ * tauReg_weight_ *
266 tauReg_residual_.transpose() * tauReg_residual_);
269 if (tauLim_weight_ > 0) {
270 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
271 activation_model_tauLim_->calc(
274 tauLim_residual_ = w(lpf_torque_ids_);
276 for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
277 tauLim_residual_(i) = w(lpf_torque_ids_[i]);
279 activation_model_tauLim_->calc(d->activation, tauLim_residual_);
282 d->cost += Scalar(0.5 * time_step_ * tauLim_weight_ *
283 d->activation->a_value);
287 if (with_cost_residual_) {
288 d->r.head(differential_->get_nr()) = d->differential->r;
291 if (tauReg_weight_ > 0) {
292 d->r.segment(differential_->get_nr(), ntau_) = tauReg_residual_;
294 if (tauLim_weight_ > 0) {
295 d->r.tail(ntau_) = tauLim_residual_;
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();
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_) +
")");
314 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
316 const Eigen::Ref<const VectorXs>&
x =
y.head(nx);
319 differential_->calc(d->differential,
x);
322 d->cost = d->differential->cost;
324 if (with_cost_residual_) {
325 d->r.head(differential_->get_nr()) = d->differential->r;
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();
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_) +
")");
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_) +
")");
349 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
354 const Eigen::Ref<const VectorXs>&
x =
y.head(nx);
356 #if EIGEN_VERSION_AT_LEAST(3, 4, 0)
357 d->tau_tmp(non_lpf_torque_ids_) =
358 w(non_lpf_torque_ids_);
359 d->tau_tmp(lpf_torque_ids_) =
y.tail(ntau_);
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);
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]);
368 const Eigen::Ref<const VectorXs>& tau = d->tau_tmp;
371 if (!tau_plus_integration_) {
373 differential_->calcDiff(d->differential,
x, tau);
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_));
380 for (std::size_t i = 0; i < lpf_torque_ids_.size(); i++) {
381 tauLim_residual_(i) = w(lpf_torque_ids_[i]);
383 activation_model_tauLim_->calcDiff(d->activation, tauLim_residual_);
388 const MatrixXs& da_dx = d->differential->Fx;
389 const MatrixXs& da_du = d->differential->Fu;
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_);
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_;
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_;
410 d->Fy.bottomRightCorner(ntau_, ntau_).diagonal().array() = Scalar(alpha_);
412 state_->JintegrateTransport(
y, d->dy, d->Fy, second);
414 y, d->dy, d->Fy, d->Fy, first,
417 d->Fy.bottomRightCorner(ntau_, ntau_).diagonal().array() -= Scalar(1.);
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() +=
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_;
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_);
443 state_->JintegrateTransport(
y, d->dy, d->Fw, second);
446 d->Ly.head(ndx).noalias() = time_step_ * d->differential->Lx;
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() =
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_);
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) =
471 d->differential->Luu(lpf_torque_ids_[i], lpf_torque_ids_[j]);
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() =
489 d->differential->Luu(non_lpf_torque_ids_, non_lpf_torque_ids_);
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]);
501 for (std::size_t j = 0; j < lpf_torque_ids_.size(); j++) {
502 d->Lyw.bottomRows(ntau_)(j, non_lpf_torque_ids_[i]) =
504 d->differential->Luu(lpf_torque_ids_[j], non_lpf_torque_ids_[i]);
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_);
515 d->Lww.diagonal().array()(lpf_torque_ids_) +=
516 Scalar(time_step_ * tauReg_weight_);
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);
522 d->Lww.diagonal().array()(lpf_torque_ids_[i]) +=
523 Scalar(time_step_ * tauReg_weight_);
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;
531 d->Lww.diagonal()(lpf_torque_ids_) +=
532 time_step_ * tauLim_weight_ *
533 d->activation->Arr.diagonal();
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);
538 d->Lww.diagonal()(lpf_torque_ids_[i]) +=
539 time_step_ * tauLim_weight_ *
540 d->activation->Arr.diagonal()(i);
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();
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_) +
")");
749 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
754 const Eigen::Ref<const VectorXs>&
x =
y.head(nx);
756 differential_->calcDiff(d->differential,
x);
758 state_->Jintegrate(
y, d->dy, d->Fy, d->Fy);
761 d->Ly.head(ndx).noalias() = d->differential->Lx;
762 d->Lyy.topLeftCorner(ndx, ndx).noalias() = d->differential->Lxx;
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_);
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]);
787 template <
typename Scalar>
788 boost::shared_ptr<ActionDataAbstractTpl<Scalar> >
790 return boost::allocate_shared<Data>(Eigen::aligned_allocator<Data>(),
this);
793 template <
typename Scalar>
795 const boost::shared_ptr<ActionDataAbstract>& data) {
796 boost::shared_ptr<Data> d = boost::dynamic_pointer_cast<Data>(data);
798 return differential_->checkData(d->differential);
804 template <
typename Scalar>
805 const boost::shared_ptr<DifferentialActionModelAbstractTpl<Scalar> >&
807 return differential_;
810 template <
typename Scalar>
815 template <
typename Scalar>
820 template <
typename Scalar>
823 throw_pretty(
"Invalid argument: "
824 <<
"dt has positive value");
827 time_step2_ = dt * dt;
830 template <
typename Scalar>
834 throw_pretty(
"Invalid argument: "
835 <<
"fc must be positive");
841 template <
typename Scalar>
844 if (alpha < 0. || alpha > 1) {
845 throw_pretty(
"Invalid argument: "
846 <<
"alpha must be in [0,1]");
852 template <
typename Scalar>
855 if (fc > 0 && time_step_ != 0) {
856 const Scalar& pi = 3.14159;
859 alpha_ = exp(-2. * pi * fc * time_step_);
863 double omega = 1 / (2. * pi * time_step_ * fc);
864 alpha_ = omega / (omega + 1);
868 double y = cos(2. * pi * time_step_ * fc);
869 alpha_ = 1 - (
y - 1 + sqrt(
y *
y - 4 *
y + 3));
876 template <
typename Scalar>
878 boost::shared_ptr<DifferentialActionModelAbstract> model) {
879 const std::size_t& nu = model->get_nu();
882 unone_ = VectorXs::Zero(nu_);
884 nr_ = model->get_nr() + 2 * ntau_;
885 state_ = boost::static_pointer_cast<StateLPF>(
887 differential_ = model;
888 Base::set_u_lb(differential_->get_u_lb());
889 Base::set_u_ub(differential_->get_u_ub());
892 template <
typename Scalar>
894 const Scalar& weight,
const VectorXs& ref) {
896 throw_pretty(
"cost weight is positive ");
898 if ((std::size_t)ref.size() != (std::size_t)(ntau_)) {
899 throw_pretty(
"cost ref must have size " << ntau_);
901 tauReg_weight_ = weight;
902 tauReg_reference_ = ref;
905 template <
typename Scalar>
907 const Scalar& weight) {
909 throw_pretty(
"cost weight is positive ");
911 tauLim_weight_ = weight;
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,
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_) +
")");
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()) +
")");
931 boost::shared_ptr<Data> d = boost::static_pointer_cast<Data>(data);
933 differential_->quasiStatic(d->differential, u,
x, maxiter, tol);