GCC Code Coverage Report


Directory: ./
File: include/crocoddyl/multibody/contacts/contact-2d.hxx
Date: 2025-06-03 08:14:12
Exec Total Coverage
Lines: 0 113 0.0%
Functions: 0 22 0.0%
Branches: 0 420 0.0%

Line Branch Exec Source
1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (C) 2020-2025, LAAS-CNRS, University of Edinburgh,
5 // Heriot-Watt University
6 // Copyright note valid unless otherwise stated in individual files.
7 // All rights reserved.
8 ///////////////////////////////////////////////////////////////////////////////
9
10 namespace crocoddyl {
11
12 template <typename Scalar>
13 ✗ ContactModel2DTpl<Scalar>::ContactModel2DTpl(
14 std::shared_ptr<StateMultibody> state, const pinocchio::FrameIndex id,
15 const Vector2s& xref, const std::size_t nu, const Vector2s& gains)
16 : Base(state, pinocchio::ReferenceFrame::LOCAL, 2, nu),
17 ✗ xref_(xref),
18 ✗ gains_(gains) {
19 ✗ id_ = id;
20 ✗ }
21
22 template <typename Scalar>
23 ✗ ContactModel2DTpl<Scalar>::ContactModel2DTpl(
24 std::shared_ptr<StateMultibody> state, const pinocchio::FrameIndex id,
25 const Vector2s& xref, const Vector2s& gains)
26 : Base(state, pinocchio::ReferenceFrame::LOCAL, 2),
27 ✗ xref_(xref),
28 ✗ gains_(gains) {
29 ✗ id_ = id;
30 ✗ }
31
32 template <typename Scalar>
33 ✗ void ContactModel2DTpl<Scalar>::calc(
34 const std::shared_ptr<ContactDataAbstract>& data,
35 const Eigen::Ref<const VectorXs>&) {
36 ✗ Data* d = static_cast<Data*>(data.get());
37 ✗ pinocchio::updateFramePlacement(*state_->get_pinocchio().get(), *d->pinocchio,
38 id_);
39 ✗ pinocchio::getFrameJacobian(*state_->get_pinocchio().get(), *d->pinocchio,
40 ✗ id_, pinocchio::LOCAL, d->fJf);
41 ✗ d->v = pinocchio::getFrameVelocity(*state_->get_pinocchio().get(),
42 ✗ *d->pinocchio, id_);
43 ✗ d->a = pinocchio::getFrameAcceleration(*state_->get_pinocchio().get(),
44 ✗ *d->pinocchio, id_);
45
46 ✗ d->Jc.row(0) = d->fJf.row(0);
47 ✗ d->Jc.row(1) = d->fJf.row(2);
48
49 ✗ d->vw = d->v.angular();
50 ✗ d->vv = d->v.linear();
51
52 ✗ d->a0[0] = d->a.linear()[0] + d->vw[1] * d->vv[2] - d->vw[2] * d->vv[1];
53 ✗ d->a0[1] = d->a.linear()[2] + d->vw[0] * d->vv[1] - d->vw[1] * d->vv[0];
54
55 ✗ if (gains_[0] != 0.) {
56 ✗ d->a0[0] +=
57 ✗ gains_[0] * (d->pinocchio->oMf[id_].translation()[0] - xref_[0]);
58 ✗ d->a0[1] +=
59 ✗ gains_[0] * (d->pinocchio->oMf[id_].translation()[2] - xref_[1]);
60 }
61 ✗ if (gains_[1] != 0.) {
62 ✗ d->a0[0] += gains_[1] * d->vv[0];
63 ✗ d->a0[1] += gains_[1] * d->vv[2];
64 }
65 ✗ }
66
67 template <typename Scalar>
68 ✗ void ContactModel2DTpl<Scalar>::calcDiff(
69 const std::shared_ptr<ContactDataAbstract>& data,
70 const Eigen::Ref<const VectorXs>&) {
71 ✗ Data* d = static_cast<Data*>(data.get());
72 ✗ const pinocchio::JointIndex joint =
73 ✗ state_->get_pinocchio()->frames[d->frame].parentJoint;
74 ✗ pinocchio::getJointAccelerationDerivatives(
75 ✗ *state_->get_pinocchio().get(), *d->pinocchio, joint, pinocchio::LOCAL,
76 ✗ d->v_partial_dq, d->a_partial_dq, d->a_partial_dv, d->a_partial_da);
77 ✗ const std::size_t nv = state_->get_nv();
78 ✗ pinocchio::skew(d->vv, d->vv_skew);
79 ✗ pinocchio::skew(d->vw, d->vw_skew);
80 ✗ d->fXjdv_dq.noalias() = d->fXj * d->v_partial_dq;
81 ✗ d->fXjda_dq.noalias() = d->fXj * d->a_partial_dq;
82 ✗ d->fXjda_dv.noalias() = d->fXj * d->a_partial_dv;
83
84 ✗ d->da0_dx.leftCols(nv).row(0) = d->fXjda_dq.row(0);
85 ✗ d->da0_dx.leftCols(nv).row(0).noalias() +=
86 ✗ d->vw_skew.row(0) * d->fXjdv_dq.template topRows<3>();
87 ✗ d->da0_dx.leftCols(nv).row(0).noalias() -=
88 ✗ d->vv_skew.row(0) * d->fXjdv_dq.template bottomRows<3>();
89
90 ✗ d->da0_dx.leftCols(nv).row(1) = d->fXjda_dq.row(2);
91 ✗ d->da0_dx.leftCols(nv).row(1).noalias() +=
92 ✗ d->vw_skew.row(2) * d->fXjdv_dq.template topRows<3>();
93 ✗ d->da0_dx.leftCols(nv).row(1).noalias() -=
94 ✗ d->vv_skew.row(2) * d->fXjdv_dq.template bottomRows<3>();
95
96 ✗ d->da0_dx.rightCols(nv).row(0) = d->fXjda_dv.row(0);
97 ✗ d->da0_dx.rightCols(nv).row(0).noalias() +=
98 ✗ d->vw_skew.row(0) * d->fJf.template topRows<3>();
99 ✗ d->da0_dx.rightCols(nv).row(0).noalias() -=
100 ✗ d->vv_skew.row(0) * d->fJf.template bottomRows<3>();
101
102 ✗ d->da0_dx.rightCols(nv).row(1) = d->fXjda_dv.row(2);
103 ✗ d->da0_dx.rightCols(nv).row(1).noalias() +=
104 ✗ d->vw_skew.row(2) * d->fJf.template topRows<3>();
105 ✗ d->da0_dx.rightCols(nv).row(1).noalias() -=
106 ✗ d->vv_skew.row(2) * d->fJf.template bottomRows<3>();
107
108 ✗ if (gains_[0] != 0.) {
109 ✗ const Eigen::Ref<const Matrix3s> oRf = d->pinocchio->oMf[id_].rotation();
110 ✗ d->oRf(0, 0) = oRf(0, 0);
111 ✗ d->oRf(1, 0) = oRf(2, 0);
112 ✗ d->oRf(0, 1) = oRf(0, 2);
113 ✗ d->oRf(1, 1) = oRf(2, 2);
114 ✗ d->da0_dx.leftCols(nv).noalias() += gains_[0] * d->oRf * d->Jc;
115 }
116 ✗ if (gains_[1] != 0.) {
117 ✗ d->da0_dx.leftCols(nv).row(0).noalias() +=
118 ✗ gains_[1] * d->fXj.row(0) * d->v_partial_dq;
119 ✗ d->da0_dx.leftCols(nv).row(1).noalias() +=
120 ✗ gains_[1] * d->fXj.row(2) * d->v_partial_dq;
121 ✗ d->da0_dx.rightCols(nv).row(0).noalias() +=
122 ✗ gains_[1] * d->fXj.row(0) * d->a_partial_da;
123 ✗ d->da0_dx.rightCols(nv).row(1).noalias() +=
124 ✗ gains_[1] * d->fXj.row(2) * d->a_partial_da;
125 }
126 ✗ }
127
128 template <typename Scalar>
129 ✗ void ContactModel2DTpl<Scalar>::updateForce(
130 const std::shared_ptr<ContactDataAbstract>& data, const VectorXs& force) {
131 ✗ if (force.size() != 2) {
132 ✗ throw_pretty(
133 "Invalid argument: " << "lambda has wrong dimension (it should be 2)");
134 }
135 ✗ Data* d = static_cast<Data*>(data.get());
136 ✗ const Eigen::Ref<const Matrix3s> R = d->jMf.rotation();
137 ✗ data->f.linear() = R.col(0) * force[0] + R.col(2) * force[1];
138 ✗ data->f.angular().setZero();
139 ✗ data->fext.linear() = R.col(0) * force[0] + R.col(2) * force[1];
140 ✗ data->fext.angular() = d->jMf.translation().cross(data->fext.linear());
141 ✗ }
142
143 template <typename Scalar>
144 std::shared_ptr<ContactDataAbstractTpl<Scalar> >
145 ✗ ContactModel2DTpl<Scalar>::createData(pinocchio::DataTpl<Scalar>* const data) {
146 ✗ return std::allocate_shared<Data>(Eigen::aligned_allocator<Data>(), this,
147 ✗ data);
148 }
149
150 template <typename Scalar>
151 template <typename NewScalar>
152 ✗ ContactModel2DTpl<NewScalar> ContactModel2DTpl<Scalar>::cast() const {
153 typedef ContactModel2DTpl<NewScalar> ReturnType;
154 typedef StateMultibodyTpl<NewScalar> StateType;
155 ✗ ReturnType ret(
156 ✗ std::make_shared<StateType>(state_->template cast<NewScalar>()), id_,
157 ✗ xref_.template cast<NewScalar>(), nu_, gains_.template cast<NewScalar>());
158 ✗ return ret;
159 }
160
161 template <typename Scalar>
162 ✗ void ContactModel2DTpl<Scalar>::print(std::ostream& os) const {
163 ✗ os << "ContactModel2D {frame=" << state_->get_pinocchio()->frames[id_].name
164 ✗ << "}";
165 ✗ }
166
167 template <typename Scalar>
168 const typename MathBaseTpl<Scalar>::Vector2s&
169 ✗ ContactModel2DTpl<Scalar>::get_reference() const {
170 ✗ return xref_;
171 }
172
173 template <typename Scalar>
174 const typename MathBaseTpl<Scalar>::Vector2s&
175 ✗ ContactModel2DTpl<Scalar>::get_gains() const {
176 ✗ return gains_;
177 }
178
179 template <typename Scalar>
180 ✗ void ContactModel2DTpl<Scalar>::set_reference(const Vector2s& reference) {
181 ✗ xref_ = reference;
182 ✗ }
183
184 } // namespace crocoddyl
185