contact1d.hxx
Go to the documentation of this file.
1 // BSD 3-Clause License
3 //
4 // Copyright (C) 2020-2021, LAAS-CNRS, University of Edinburgh
5 // Copyright note valid unless otherwise stated in individual files.
6 // All rights reserved.
8 
9 #include "contact1d.hpp"
10 
11 namespace sobec {
12 namespace newcontacts {
13 
14 template <typename Scalar>
16  boost::shared_ptr<StateMultibody> state, const pinocchio::FrameIndex id,
17  const Vector3s& xref, const std::size_t nu, const Vector2s& gains,
18  const Vector3MaskType& mask, const pinocchio::ReferenceFrame type)
19  : Base(state, id, Scalar(0.), nu, Vector2s::Zero()),
20  xref_(xref),
21  gains_(gains),
22  mask_(mask),
23  type_(type) {}
24 
25 template <typename Scalar>
27  boost::shared_ptr<StateMultibody> state, const pinocchio::FrameIndex id,
28  const Vector3s& xref, const Vector2s& gains,
29  const pinocchio::ReferenceFrame type)
30  : Base(state, id, Scalar(0.), Vector2s::Zero()),
31  xref_(xref),
32  gains_(gains),
33  mask_(Vector3MaskType::z),
34  type_(type) {}
35 
36 template <typename Scalar>
38 
39 template <typename Scalar>
41  const boost::shared_ptr<crocoddyl::ContactDataAbstractTpl<Scalar>>& data,
42  const Eigen::Ref<const VectorXs>& x) {
43  Data* d = static_cast<Data*>(data.get());
44  pinocchio::updateFramePlacement(*state_->get_pinocchio().get(), *d->pinocchio,
45  id_);
46  pinocchio::getFrameJacobian(*state_->get_pinocchio().get(), *d->pinocchio,
47  id_, pinocchio::LOCAL, d->fJf);
48  d->a0_3d_ =
49  pinocchio::getFrameClassicalAcceleration(
50  *state_->get_pinocchio().get(), *d->pinocchio, id_, pinocchio::LOCAL)
51  .linear();
52  d->vv = d->fJf.template topRows<3>() * x.tail(state_->get_nv());
53  d->vw = d->fJf.template bottomRows<3>() * x.tail(state_->get_nv());
54  d->oRf = d->pinocchio->oMf[id_].rotation();
55  d->Jc.row(0) = d->fJf.row(mask_);
56  // BAUMGARTE P
57  if (gains_[0] != 0.) {
58  d->a0_3d_ += gains_[0] * d->oRf.transpose() *
59  (d->pinocchio->oMf[id_].translation() - xref_);
60  }
61  // BAUMGARTE V
62  if (gains_[1] != 0.) {
63  d->a0_3d_ += gains_[1] * d->vv;
64  }
65  // project
66  d->a0[0] = d->a0_3d_[mask_];
67 
68  if (type_ == pinocchio::LOCAL_WORLD_ALIGNED || type_ == pinocchio::WORLD) {
69  d->a0[0] = (d->oRf * d->a0_3d_)[mask_];
70  d->Jc.row(0) = (d->oRf * d->fJf.template topRows<3>()).row(mask_);
71  }
72 }
73 
74 template <typename Scalar>
76  const boost::shared_ptr<crocoddyl::ContactDataAbstractTpl<Scalar>>& data,
77  const Eigen::Ref<const VectorXs>&) {
78  Data* d = static_cast<Data*>(data.get());
79  const pinocchio::JointIndex joint =
80  state_->get_pinocchio()->frames[d->frame].parent;
81  pinocchio::getJointAccelerationDerivatives(
82  *state_->get_pinocchio().get(), *d->pinocchio, joint, pinocchio::LOCAL,
84  const std::size_t nv = state_->get_nv();
85  pinocchio::skew(d->vv, d->vv_skew);
86  pinocchio::skew(d->vw, d->vw_skew);
87 
88  d->fXjdv_dq.noalias() = d->fXj * d->v_partial_dq;
89  d->fXjda_dq.noalias() = d->fXj * d->a_partial_dq;
90  d->fXjda_dv.noalias() = d->fXj * d->a_partial_dv;
91 
92  d->da0_dx_3d_.leftCols(nv) = d->fXjda_dq.template topRows<3>();
93  d->da0_dx_3d_.leftCols(nv).noalias() +=
94  d->vw_skew * d->fXjdv_dq.template topRows<3>();
95  d->da0_dx_3d_.leftCols(nv).noalias() -=
96  d->vv_skew * d->fXjdv_dq.template bottomRows<3>();
97 
98  d->da0_dx_3d_.rightCols(nv) = d->fXjda_dv.template topRows<3>();
99  d->da0_dx_3d_.rightCols(nv).noalias() +=
100  d->vw_skew * d->fJf.template topRows<3>();
101  d->da0_dx_3d_.rightCols(nv).noalias() -=
102  d->vv_skew * d->fJf.template bottomRows<3>();
103 
104  if (gains_[0] != 0.) {
105  pinocchio::skew(
106  d->oRf.transpose() * (d->pinocchio->oMf[id_].translation() - xref_),
107  d->tmp_skew_);
108  d->da0_dx_3d_.leftCols(nv).noalias() +=
109  gains_[0] * (d->tmp_skew_ * d->fJf.template bottomRows<3>() +
110  d->fJf.template topRows<3>());
111  }
112 
113  if (gains_[1] != 0.) {
114  d->da0_dx_3d_.leftCols(nv).noalias() +=
115  gains_[1] * d->fXjdv_dq.template topRows<3>();
116  d->da0_dx_3d_.rightCols(nv).noalias() +=
117  gains_[1] * d->fJf.template topRows<3>();
118  }
119 
120  d->da0_dx.row(0) = d->da0_dx_3d_.row(mask_);
121 
122  if (type_ == pinocchio::LOCAL_WORLD_ALIGNED || type_ == pinocchio::WORLD) {
123  // Need to recompute classical acceleration + BG correction (may not be
124  // equal to drift a0 anymore)
125  d->a0_3d_ = pinocchio::getFrameClassicalAcceleration(
126  *state_->get_pinocchio().get(), *d->pinocchio, id_,
127  pinocchio::LOCAL)
128  .linear();
129  if (gains_[0] != 0.) {
130  d->a0_3d_ += gains_[0] * d->oRf.transpose() *
131  (d->pinocchio->oMf[id_].translation() - xref_);
132  }
133  if (gains_[1] != 0.) {
134  d->a0_3d_ += gains_[1] * d->vv;
135  }
136  // Skew term due to LWA frame (is zero when classical acceleration = 0,
137  // which is the case in ContactFwdDynamics)
138  pinocchio::skew(d->oRf * d->a0_3d_, d->tmp_skew_);
139  d->da0_dx.leftCols(nv).row(0) =
140  (d->oRf * d->da0_dx_3d_.leftCols(nv) -
141  d->tmp_skew_ * d->oRf * d->fJf.template bottomRows<3>())
142  .row(mask_);
143  d->da0_dx.rightCols(nv).row(0) =
144  (d->oRf * d->da0_dx_3d_.rightCols(nv)).row(mask_);
145  }
146 }
147 
148 template <typename Scalar>
150  const boost::shared_ptr<crocoddyl::ContactDataAbstractTpl<Scalar>>& data,
151  const VectorXs& force) {
152  if (force.size() != 1) {
153  throw_pretty("Invalid argument: "
154  << "lambda has wrong dimension (it should be 1)");
155  }
156  Data* d = static_cast<Data*>(data.get());
157  d->oRf = d->pinocchio->oMf[id_].rotation();
158  if (type_ == pinocchio::LOCAL) {
159  data->f.linear() = d->jMf.rotation().col(mask_) * force[0];
160  data->f.angular() = d->jMf.translation().cross(data->f.linear());
161  }
162  if (type_ == pinocchio::LOCAL_WORLD_ALIGNED || type_ == pinocchio::WORLD) {
163  data->f = d->jMf.act(pinocchio::ForceTpl<Scalar>(
164  d->oRf.transpose().col(mask_) * force[0], Vector3s::Zero()));
165  // Compute skew term to be added to rnea derivatives
166  pinocchio::skew(d->oRf.transpose().col(mask_) * force[0], d->tmp_skew_);
167  d->drnea_skew_term_ =
168  -d->fJf.topRows(3).transpose() * d->tmp_skew_ * d->fJf.bottomRows(3);
169  }
170 }
171 
172 template <typename Scalar>
173 boost::shared_ptr<crocoddyl::ContactDataAbstractTpl<Scalar>>
174 ContactModel1DTpl<Scalar>::createData(pinocchio::DataTpl<Scalar>* const data) {
175  return boost::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this,
176  data);
177 }
178 
179 template <typename Scalar>
180 void ContactModel1DTpl<Scalar>::print(std::ostream& os) const {
181  os << "ContactModel1D {frame=" << state_->get_pinocchio()->frames[id_].name
182  << "}";
183 }
184 
185 template <typename Scalar>
186 const typename crocoddyl::MathBaseTpl<Scalar>::Vector3s&
188  return xref_;
189 }
190 
191 template <typename Scalar>
192 const typename crocoddyl::MathBaseTpl<Scalar>::Vector2s&
194  return gains_;
195 }
196 
197 template <typename Scalar>
199  xref_ = reference;
200 }
201 
202 template <typename Scalar>
203 void ContactModel1DTpl<Scalar>::set_type(const pinocchio::ReferenceFrame type) {
204  type_ = type;
205 }
206 
207 template <typename Scalar>
208 const pinocchio::ReferenceFrame& ContactModel1DTpl<Scalar>::get_type() const {
209  return type_;
210 }
211 
212 template <typename Scalar>
214  mask_ = mask;
215 }
216 
217 template <typename Scalar>
219  return mask_;
220 }
221 
222 } // namespace newcontacts
223 } // namespace sobec
sobec::newcontacts::ContactData1DTpl::a_partial_da
Matrix6xs a_partial_da
Definition: contact1d.hpp:241
sobec::newcontacts::ContactModel1DTpl::Base
crocoddyl::ContactModel1DTpl< Scalar > Base
Definition: contact1d.hpp:35
sobec::newcontacts::ContactData1DTpl::fXjda_dq
Matrix6xs fXjda_dq
Definition: contact1d.hpp:243
sobec::newcontacts::ContactData1DTpl::oRf
Matrix3s oRf
Definition: contact1d.hpp:249
sobec::newcontacts::ContactModel1DTpl::ContactModel1DTpl
ContactModel1DTpl(boost::shared_ptr< StateMultibody > state, const pinocchio::FrameIndex id, const Vector3s &xref, const std::size_t nu, const Vector2s &gains=Vector2s::Zero(), const Vector3MaskType &mask=Vector3MaskType::z, const pinocchio::ReferenceFrame ref=pinocchio::LOCAL)
Initialize the 1d contact model.
Definition: contact1d.hxx:15
sobec::newcontacts::ContactData1DTpl::v_partial_dq
Matrix6xs v_partial_dq
Definition: contact1d.hpp:238
sobec::newcontacts::ContactData1DTpl::fXjda_dv
Matrix6xs fXjda_dv
Definition: contact1d.hpp:244
sobec::newcontacts::ContactModel1DTpl::Vector2s
MathBase::Vector2s Vector2s
Definition: contact1d.hpp:38
sobec::newcontacts::ContactModel1DTpl::get_reference
const Vector3s & get_reference() const
Return the reference frame translation.
Definition: contact1d.hxx:187
sobec::newcontacts::ContactModel1DTpl::calcDiff
virtual void calcDiff(const boost::shared_ptr< crocoddyl::ContactDataAbstractTpl< Scalar >> &data, const Eigen::Ref< const VectorXs > &x)
Compute the derivatives of the 1d contact holonomic constraint.
Definition: contact1d.hxx:75
sobec::newcontacts::ContactData1DTpl::da0_dx_3d_
MatrixXs da0_dx_3d_
Definition: contact1d.hpp:254
sobec::newcontacts::ContactData1DTpl::vw_skew
Matrix3s vw_skew
Definition: contact1d.hpp:248
sobec::newcontacts::ContactModel1DTpl::get_mask
const Vector3MaskType & get_mask() const
Get contact 1D mask.
Definition: contact1d.hxx:218
sobec::newcontacts::ContactData1DTpl
Definition: contact1d.hpp:173
sobec::newcontacts::ContactModel1DTpl::createData
virtual boost::shared_ptr< crocoddyl::ContactDataAbstractTpl< Scalar > > createData(pinocchio::DataTpl< Scalar > *const data)
Create the 1d contact data.
Definition: contact1d.hxx:174
sobec::newcontacts::ContactData1DTpl::vw
Vector3s vw
Definition: contact1d.hpp:246
sobec::newcontacts::ContactModel1DTpl::set_type
void set_type(const pinocchio::ReferenceFrame type)
Modify pinocchio::ReferenceFrame.
Definition: contact1d.hxx:203
sobec::newcontacts::ContactData1DTpl::a_partial_dq
Matrix6xs a_partial_dq
Definition: contact1d.hpp:239
sobec
Definition: activation-quad-ref.hpp:19
sobec::newcontacts::ContactData1DTpl::a0_3d_
Vector3s a0_3d_
Definition: contact1d.hpp:253
sobec::newcontacts::ContactModel1DTpl::print
virtual void print(std::ostream &os) const
Print relevant information of the 1d contact model.
Definition: contact1d.hxx:180
sobec::newcontacts::ContactData1DTpl::fXjdv_dq
Matrix6xs fXjdv_dq
Definition: contact1d.hpp:242
sobec::newcontacts::ContactModel1DTpl::Vector3s
MathBase::Vector3s Vector3s
Definition: contact1d.hpp:39
sobec::newcontacts::ContactModel1DTpl::get_type
const pinocchio::ReferenceFrame & get_type() const
Get pinocchio::ReferenceFrame.
Definition: contact1d.hxx:208
sobec::newcontacts::ContactData1DTpl::vv_skew
Matrix3s vv_skew
Definition: contact1d.hpp:247
sobec::newcontacts::z
@ z
Definition: contact1d.hpp:26
sobec::newcontacts::ContactData1DTpl::drnea_skew_term_
MatrixXs drnea_skew_term_
Definition: contact1d.hpp:255
sobec::newcontacts::x
@ x
Definition: contact1d.hpp:26
sobec::newcontacts::ContactModel1DTpl::calc
virtual void calc(const boost::shared_ptr< crocoddyl::ContactDataAbstractTpl< Scalar >> &data, const Eigen::Ref< const VectorXs > &x)
Compute the 1d contact Jacobian and drift.
Definition: contact1d.hxx:40
sobec::newcontacts::Vector3MaskType
Vector3MaskType
Definition: contact1d.hpp:26
sobec::newcontacts::ContactModel1DTpl::set_mask
void set_mask(const Vector3MaskType mask)
Modify contact 1D mask.
Definition: contact1d.hxx:213
sobec::newcontacts::ContactModel1DTpl::set_reference
void set_reference(const Vector3s &reference)
Modify the reference frame translation.
Definition: contact1d.hxx:198
sobec::newcontacts::ContactData1DTpl::vv
Vector3s vv
Definition: contact1d.hpp:245
sobec::newcontacts::ContactModel1DTpl::get_gains
const Vector2s & get_gains() const
Create the 1d contact data.
Definition: contact1d.hxx:193
sobec::newcontacts::ContactData1DTpl::a_partial_dv
Matrix6xs a_partial_dv
Definition: contact1d.hpp:240
contact1d.hpp
sobec::newcontacts::ContactModel1DTpl::~ContactModel1DTpl
virtual ~ContactModel1DTpl()
Definition: contact1d.hxx:37
sobec::newcontacts::ContactData1DTpl::fJf
Matrix6xs fJf
Definition: contact1d.hpp:237
sobec::newcontacts::ContactModel1DTpl::updateForce
virtual void updateForce(const boost::shared_ptr< crocoddyl::ContactDataAbstractTpl< Scalar >> &data, const VectorXs &force)
Convert the force into a stack of spatial forces.
Definition: contact1d.hxx:149
sobec::newcontacts::ContactModel1DTpl::VectorXs
MathBase::VectorXs VectorXs
Definition: contact1d.hpp:40
sobec::newcontacts::ContactData1DTpl::tmp_skew_
Matrix3s tmp_skew_
Definition: contact1d.hpp:250