GCC Code Coverage Report


Directory: ./
File: src/contacts/contact-point.cpp
Date: 2024-08-26 20:29:39
Exec Total Coverage
Lines: 0 125 0.0%
Branches: 0 258 0.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2017 CNRS, NYU, MPI Tübingen
3 //
4 // This file is part of tsid
5 // tsid is free software: you can redistribute it
6 // and/or modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation, either version
8 // 3 of the License, or (at your option) any later version.
9 // tsid is distributed in the hope that it will be
10 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Lesser Public License for more details. You should have
13 // received a copy of the GNU Lesser General Public License along with
14 // tsid If not, see
15 // <http://www.gnu.org/licenses/>.
16 //
17
18 #include "tsid/math/utils.hpp"
19 #include "tsid/contacts/contact-point.hpp"
20
21 #include <pinocchio/spatial/skew.hpp>
22
23 using namespace tsid;
24 using namespace contacts;
25 using namespace math;
26 using namespace trajectories;
27 using namespace tasks;
28
29 ContactPoint::ContactPoint(const std::string& name, RobotWrapper& robot,
30 const std::string& frameName,
31 ConstRefVector contactNormal,
32 const double frictionCoefficient,
33 const double minNormalForce,
34 const double maxNormalForce)
35 : ContactBase(name, robot),
36 m_motionTask(name, robot, frameName),
37 m_forceInequality(name, 5, 3),
38 m_forceRegTask(name, 3, 3),
39 m_contactNormal(contactNormal),
40 m_mu(frictionCoefficient),
41 m_fMin(minNormalForce),
42 m_fMax(maxNormalForce) {
43 m_weightForceRegTask << 1, 1, 1e-3;
44 m_forceGenMat.resize(3, 3);
45 m_fRef = Vector3::Zero();
46 m_contactPoints.resize(3, 1);
47 m_contactPoints.setZero();
48 updateForceGeneratorMatrix();
49 updateForceInequalityConstraints();
50 updateForceRegularizationTask();
51
52 math::Vector motion_mask(6);
53 motion_mask << 1., 1., 1., 0., 0., 0.;
54 m_motionTask.setMask(motion_mask);
55 }
56
57 void ContactPoint::useLocalFrame(bool local_frame) {
58 m_motionTask.useLocalFrame(local_frame);
59 }
60
61 void ContactPoint::updateForceInequalityConstraints() {
62 Vector3 t1, t2;
63 const int n_in = 4 * 1 + 1;
64 const int n_var = 3 * 1;
65 Matrix B = Matrix::Zero(n_in, n_var);
66 Vector lb = -1e10 * Vector::Ones(n_in);
67 Vector ub = Vector::Zero(n_in);
68 t1 = m_contactNormal.cross(Vector3::UnitX());
69 if (t1.norm() < 1e-5) t1 = m_contactNormal.cross(Vector3::UnitY());
70 t2 = m_contactNormal.cross(t1);
71 t1.normalize();
72 t2.normalize();
73
74 B.block<1, 3>(0, 0) = (-t1 - m_mu * m_contactNormal).transpose();
75 B.block<1, 3>(1, 0) = (t1 - m_mu * m_contactNormal).transpose();
76 B.block<1, 3>(2, 0) = (-t2 - m_mu * m_contactNormal).transpose();
77 B.block<1, 3>(3, 0) = (t2 - m_mu * m_contactNormal).transpose();
78
79 B.block<1, 3>(n_in - 1, 0) = m_contactNormal.transpose();
80 ub(n_in - 1) = m_fMax;
81 lb(n_in - 1) = m_fMin;
82
83 m_forceInequality.setMatrix(B);
84 m_forceInequality.setLowerBound(lb);
85 m_forceInequality.setUpperBound(ub);
86 }
87
88 double ContactPoint::getNormalForce(ConstRefVector f) const {
89 PINOCCHIO_CHECK_INPUT_ARGUMENT(
90 f.size() == n_force(),
91 "Size of f is wrong - needs to be " + std::to_string(n_force()));
92 return m_contactNormal.dot(f);
93 }
94
95 const Matrix3x& ContactPoint::getContactPoints() const {
96 return m_contactPoints;
97 }
98
99 void ContactPoint::setRegularizationTaskWeightVector(ConstRefVector& w) {
100 m_weightForceRegTask = w;
101 updateForceRegularizationTask();
102 }
103
104 void ContactPoint::updateForceRegularizationTask() {
105 Eigen::Matrix3d A = Eigen::Matrix3d::Zero();
106 A.diagonal() = m_weightForceRegTask;
107 m_forceRegTask.setMatrix(A);
108 m_forceRegTask.setVector(A * m_fRef);
109 }
110
111 void ContactPoint::updateForceGeneratorMatrix() { m_forceGenMat.setIdentity(); }
112
113 unsigned int ContactPoint::n_motion() const { return m_motionTask.dim(); }
114 unsigned int ContactPoint::n_force() const { return 3; }
115
116 const Vector& ContactPoint::Kp() {
117 m_Kp3 = m_motionTask.Kp().head<3>();
118 return m_Kp3;
119 }
120
121 const Vector& ContactPoint::Kd() {
122 m_Kd3 = m_motionTask.Kd().head<3>();
123 return m_Kd3;
124 }
125
126 void ContactPoint::Kp(ConstRefVector Kp) {
127 PINOCCHIO_CHECK_INPUT_ARGUMENT(Kp.size() == 3,
128 "Size of Kp vector needs to equal 3");
129 Vector6 Kp6;
130 Kp6.head<3>() = Kp;
131 m_motionTask.Kp(Kp6);
132 }
133
134 void ContactPoint::Kd(ConstRefVector Kd) {
135 PINOCCHIO_CHECK_INPUT_ARGUMENT(Kd.size() == 3,
136 "Size of Kd vector needs to equal 3");
137 Vector6 Kd6;
138 Kd6.head<3>() = Kd;
139 m_motionTask.Kd(Kd6);
140 }
141
142 bool ContactPoint::setContactNormal(ConstRefVector contactNormal) {
143 PINOCCHIO_CHECK_INPUT_ARGUMENT(
144 contactNormal.size() == 3,
145 "Size of contact normal vector needs to equal 3");
146 if (contactNormal.size() != 3) return false;
147 m_contactNormal = contactNormal;
148 updateForceInequalityConstraints();
149 return true;
150 }
151
152 bool ContactPoint::setFrictionCoefficient(const double frictionCoefficient) {
153 PINOCCHIO_CHECK_INPUT_ARGUMENT(frictionCoefficient > 0.0,
154 "Friction coefficient needs to be positive");
155 if (frictionCoefficient <= 0.0) return false;
156 m_mu = frictionCoefficient;
157 updateForceInequalityConstraints();
158 return true;
159 }
160
161 bool ContactPoint::setMinNormalForce(const double minNormalForce) {
162 PINOCCHIO_CHECK_INPUT_ARGUMENT(
163 minNormalForce > 0.0 && minNormalForce <= m_fMax,
164 "The minimal normal force needs to be greater than 0 and less than or "
165 "equal to the maximum force.");
166 if (minNormalForce <= 0.0 || minNormalForce > m_fMax) return false;
167 m_fMin = minNormalForce;
168 Vector& lb = m_forceInequality.lowerBound();
169 lb(lb.size() - 1) = m_fMin;
170 return true;
171 }
172
173 bool ContactPoint::setMaxNormalForce(const double maxNormalForce) {
174 PINOCCHIO_CHECK_INPUT_ARGUMENT(maxNormalForce >= m_fMin,
175 "The maximal normal force needs to be greater "
176 "than or equal to the minimal force");
177 if (maxNormalForce < m_fMin) return false;
178 m_fMax = maxNormalForce;
179 Vector& ub = m_forceInequality.upperBound();
180 ub(ub.size() - 1) = m_fMax;
181 return true;
182 }
183
184 void ContactPoint::setForceReference(ConstRefVector& f_ref) {
185 PINOCCHIO_CHECK_INPUT_ARGUMENT(
186 f_ref.size() == 3, "The size of the force reference needs to equal 3");
187 m_fRef = f_ref;
188 updateForceRegularizationTask();
189 }
190
191 void ContactPoint::setReference(const SE3& ref) {
192 m_motionTask.setReference(ref);
193 }
194
195 const ConstraintBase& ContactPoint::computeMotionTask(const double t,
196 ConstRefVector q,
197 ConstRefVector v,
198 Data& data) {
199 return m_motionTask.compute(t, q, v, data);
200 }
201
202 const ConstraintInequality& ContactPoint::computeForceTask(const double,
203 ConstRefVector,
204 ConstRefVector,
205 const Data&) {
206 return m_forceInequality;
207 }
208
209 const Matrix& ContactPoint::getForceGeneratorMatrix() { return m_forceGenMat; }
210
211 const ConstraintEquality& ContactPoint::computeForceRegularizationTask(
212 const double, ConstRefVector, ConstRefVector, const Data&) {
213 return m_forceRegTask;
214 }
215
216 double ContactPoint::getMinNormalForce() const { return m_fMin; }
217 double ContactPoint::getMaxNormalForce() const { return m_fMax; }
218
219 const TaskSE3Equality& ContactPoint::getMotionTask() const {
220 return m_motionTask;
221 }
222
223 const ConstraintBase& ContactPoint::getMotionConstraint() const {
224 return m_motionTask.getConstraint();
225 }
226
227 const ConstraintInequality& ContactPoint::getForceConstraint() const {
228 return m_forceInequality;
229 }
230
231 const ConstraintEquality& ContactPoint::getForceRegularizationTask() const {
232 return m_forceRegTask;
233 }
234