GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/tasks/task-two-frames-equality.cpp Lines: 0 96 0.0 %
Date: 2024-02-02 08:47:34 Branches: 0 280 0.0 %

Line Branch Exec Source
1
//
2
// Copyright (c) 2023 MIPT
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/tasks/task-two-frames-equality.hpp"
20
#include "tsid/robots/robot-wrapper.hpp"
21
22
namespace tsid {
23
namespace tasks {
24
using namespace std;
25
using namespace math;
26
using namespace trajectories;
27
using namespace pinocchio;
28
29
TaskTwoFramesEquality::TaskTwoFramesEquality(const std::string& name,
30
                                             RobotWrapper& robot,
31
                                             const std::string& frameName1,
32
                                             const std::string& frameName2)
33
    : TaskMotion(name, robot),
34
      m_frame_name1(frameName1),
35
      m_frame_name2(frameName2),
36
      m_constraint(name, 6, robot.nv()) {
37
  assert(m_robot.model().existFrame(frameName1));
38
  assert(m_robot.model().existFrame(frameName2));
39
  m_frame_id1 = m_robot.model().getFrameId(frameName1);
40
  m_frame_id2 = m_robot.model().getFrameId(frameName2);
41
42
  m_v_ref.setZero();
43
  m_a_ref.setZero();
44
  m_wMl1.setIdentity();
45
  m_wMl2.setIdentity();
46
  m_p_error_vec.setZero(6);
47
  m_v_error_vec.setZero(6);
48
  m_p.resize(12);
49
  m_v.resize(6);
50
  m_p_ref.resize(12);
51
  m_v_ref_vec.resize(6);
52
  m_Kp.setZero(6);
53
  m_Kd.setZero(6);
54
  m_a_des.setZero(6);
55
  m_J1.setZero(6, robot.nv());
56
  m_J2.setZero(6, robot.nv());
57
  m_J1_rotated.setZero(6, robot.nv());
58
  m_J2_rotated.setZero(6, robot.nv());
59
60
  m_mask.resize(6);
61
  m_mask.fill(1.);
62
  setMask(m_mask);
63
}
64
65
void TaskTwoFramesEquality::setMask(math::ConstRefVector mask) {
66
  TaskMotion::setMask(mask);
67
  int n = dim();
68
  m_constraint.resize(n, (unsigned int)m_J1.cols());
69
  m_p_error_masked_vec.resize(n);
70
  m_v_error_masked_vec.resize(n);
71
  m_drift_masked.resize(n);
72
  m_a_des_masked.resize(n);
73
}
74
75
int TaskTwoFramesEquality::dim() const { return (int)m_mask.sum(); }
76
77
const Vector& TaskTwoFramesEquality::Kp() const { return m_Kp; }
78
79
const Vector& TaskTwoFramesEquality::Kd() const { return m_Kd; }
80
81
void TaskTwoFramesEquality::Kp(ConstRefVector Kp) {
82
  assert(Kp.size() == 6);
83
  m_Kp = Kp;
84
}
85
86
void TaskTwoFramesEquality::Kd(ConstRefVector Kd) {
87
  assert(Kd.size() == 6);
88
  m_Kd = Kd;
89
}
90
91
const Vector& TaskTwoFramesEquality::position_error() const {
92
  return m_p_error_masked_vec;
93
}
94
95
const Vector& TaskTwoFramesEquality::velocity_error() const {
96
  return m_v_error_masked_vec;
97
}
98
99
const Vector& TaskTwoFramesEquality::getDesiredAcceleration() const {
100
  return m_a_des_masked;
101
}
102
103
Vector TaskTwoFramesEquality::getAcceleration(ConstRefVector dv) const {
104
  return m_constraint.matrix() * dv + m_drift_masked;
105
}
106
107
Index TaskTwoFramesEquality::frame_id1() const { return m_frame_id1; }
108
109
Index TaskTwoFramesEquality::frame_id2() const { return m_frame_id2; }
110
111
const ConstraintBase& TaskTwoFramesEquality::getConstraint() const {
112
  return m_constraint;
113
}
114
115
const ConstraintBase& TaskTwoFramesEquality::compute(const double,
116
                                                     ConstRefVector,
117
                                                     ConstRefVector,
118
                                                     Data& data) {
119
  // Calculating task with formulation: [J1 - J2   0   0] dv = [-J1dot*v +
120
  // J2dot*v]
121
122
  SE3 oMi1, oMi2;
123
  Motion v_frame1, v_frame2;
124
  Motion m_drift1, m_drift2;
125
  m_robot.framePosition(data, m_frame_id1, oMi1);
126
  m_robot.framePosition(data, m_frame_id2, oMi2);
127
  m_robot.frameVelocity(data, m_frame_id1, v_frame1);
128
  m_robot.frameVelocity(data, m_frame_id2, v_frame2);
129
  m_robot.frameClassicAcceleration(data, m_frame_id1, m_drift1);
130
  m_robot.frameClassicAcceleration(data, m_frame_id2, m_drift2);
131
132
  // Transformations from local to local-world-aligned frame (thus only rotation
133
  // is used)
134
  m_wMl1.rotation(oMi1.rotation());
135
  m_wMl2.rotation(oMi2.rotation());
136
137
  m_robot.frameJacobianLocal(data, m_frame_id1, m_J1);
138
  m_robot.frameJacobianLocal(data, m_frame_id2, m_J2);
139
140
  // Doing all calculations in local-world-aligned frame
141
  errorInSE3(oMi1, oMi2, m_p_error);  // pos err in local oMi1 frame
142
  m_p_error_vec = m_wMl1.toActionMatrix() *
143
                  m_p_error.toVector();  // pos err in local-world-aligned frame
144
145
  m_v_error = m_wMl2.act(v_frame2) -
146
              m_wMl1.act(v_frame1);  // vel err in local-world-aligned frame
147
148
  // desired acc in local-world-aligned frame
149
  m_a_des = m_Kp.cwiseProduct(m_p_error_vec) +
150
            m_Kd.cwiseProduct(m_v_error.toVector());
151
152
  m_v_error_vec = m_v_error.toVector();
153
154
  m_drift = (m_wMl1.act(m_drift1) - m_wMl2.act(m_drift2));
155
156
  m_J1_rotated.noalias() =
157
      m_wMl1.toActionMatrix() *
158
      m_J1;  // Use an explicit temporary m_J_rotated to avoid allocations
159
  m_J1 = m_J1_rotated;
160
161
  m_J2_rotated.noalias() = m_wMl2.toActionMatrix() * m_J2;
162
  m_J2 = m_J2_rotated;
163
164
  int idx = 0;
165
  for (int i = 0; i < 6; i++) {
166
    if (m_mask(i) != 1.) continue;
167
168
    m_constraint.matrix().row(idx) = m_J1.row(i) - m_J2.row(i);
169
    m_constraint.vector().row(idx) = (m_a_des - m_drift.toVector()).row(i);
170
    m_a_des_masked(idx) = m_a_des(i);
171
    m_drift_masked(idx) = m_drift.toVector()(i);
172
    m_p_error_masked_vec(idx) = m_p_error_vec(i);
173
    m_v_error_masked_vec(idx) = m_v_error_vec(i);
174
175
    idx += 1;
176
  }
177
178
  return m_constraint;
179
}
180
}  // namespace tasks
181
}  // namespace tsid