GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/contacts/contact-point.cpp Lines: 0 119 0.0 %
Date: 2024-02-02 08:47:34 Branches: 0 262 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
}