GCC Code Coverage Report


Directory: ./
File: src/tasks/task-se3-equality.cpp
Date: 2024-10-10 01:09:49
Exec Total Coverage
Lines: 0 111 0.0%
Branches: 0 306 0.0%

Line Branch Exec Source
1 //
2 // Copyright (c) 2017-2020 CNRS, NYU, MPI Tübingen, Inria
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-se3-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 TaskSE3Equality::TaskSE3Equality(const std::string& name, RobotWrapper& robot,
30 const std::string& frameName)
31 : TaskMotion(name, robot),
32 m_frame_name(frameName),
33 m_constraint(name, 6, robot.nv()),
34 m_ref(12, 6) {
35 PINOCCHIO_CHECK_INPUT_ARGUMENT(
36 m_robot.model().existFrame(frameName),
37 "The frame with name '" + frameName + "' does not exist");
38 m_frame_id = m_robot.model().getFrameId(frameName);
39
40 m_v_ref.setZero();
41 m_a_ref.setZero();
42 m_M_ref.setIdentity();
43 m_wMl.setIdentity();
44 m_p_error_vec.setZero(6);
45 m_v_error_vec.setZero(6);
46 m_p.resize(12);
47 m_v.resize(6);
48 m_p_ref.resize(12);
49 m_v_ref_vec.resize(6);
50 m_Kp.setZero(6);
51 m_Kd.setZero(6);
52 m_a_des.setZero(6);
53 m_J.setZero(6, robot.nv());
54 m_J_rotated.setZero(6, robot.nv());
55
56 m_mask.resize(6);
57 m_mask.fill(1.);
58 setMask(m_mask);
59
60 m_local_frame = true;
61 }
62
63 void TaskSE3Equality::setMask(math::ConstRefVector mask) {
64 TaskMotion::setMask(mask);
65 int n = dim();
66 m_constraint.resize(n, (unsigned int)m_J.cols());
67 m_p_error_masked_vec.resize(n);
68 m_v_error_masked_vec.resize(n);
69 m_drift_masked.resize(n);
70 m_a_des_masked.resize(n);
71 }
72
73 int TaskSE3Equality::dim() const { return (int)m_mask.sum(); }
74
75 const Vector& TaskSE3Equality::Kp() const { return m_Kp; }
76
77 const Vector& TaskSE3Equality::Kd() const { return m_Kd; }
78
79 void TaskSE3Equality::Kp(ConstRefVector Kp) {
80 PINOCCHIO_CHECK_INPUT_ARGUMENT(Kp.size() == 6,
81 "The size of the Kp vector needs to equal 6");
82 m_Kp = Kp;
83 }
84
85 void TaskSE3Equality::Kd(ConstRefVector Kd) {
86 PINOCCHIO_CHECK_INPUT_ARGUMENT(Kd.size() == 6,
87 "The size of the Kd vector needs to equal 6");
88 m_Kd = Kd;
89 }
90
91 void TaskSE3Equality::setReference(TrajectorySample& ref) {
92 m_ref = ref;
93 TSID_DISABLE_WARNING_PUSH
94 TSID_DISABLE_WARNING_DEPRECATED
95 PINOCCHIO_CHECK_INPUT_ARGUMENT(
96 ref.pos.size() == 12, "The size of the reference vector needs to be 12");
97 m_M_ref.translation(ref.pos.head<3>());
98 m_M_ref.rotation(MapMatrix3(&ref.pos(3), 3, 3));
99 TSID_DISABLE_WARNING_POP
100 m_v_ref = Motion(ref.getDerivative());
101 m_a_ref = Motion(ref.getSecondDerivative());
102 }
103
104 void TaskSE3Equality::setReference(const SE3& ref) {
105 TrajectorySample s(12, 6);
106 TSID_DISABLE_WARNING_PUSH
107 TSID_DISABLE_WARNING_DEPRECATED
108 tsid::math::SE3ToVector(ref, s.pos);
109 TSID_DISABLE_WARNING_POP
110 setReference(s);
111 }
112
113 const TrajectorySample& TaskSE3Equality::getReference() const { return m_ref; }
114
115 const Vector& TaskSE3Equality::position_error() const {
116 return m_p_error_masked_vec;
117 }
118
119 const Vector& TaskSE3Equality::velocity_error() const {
120 return m_v_error_masked_vec;
121 }
122
123 const Vector& TaskSE3Equality::position() const { return m_p; }
124
125 const Vector& TaskSE3Equality::velocity() const { return m_v; }
126
127 const Vector& TaskSE3Equality::position_ref() const { return m_p_ref; }
128
129 const Vector& TaskSE3Equality::velocity_ref() const { return m_v_ref_vec; }
130
131 const Vector& TaskSE3Equality::getDesiredAcceleration() const {
132 return m_a_des_masked;
133 }
134
135 Vector TaskSE3Equality::getAcceleration(ConstRefVector dv) const {
136 return m_constraint.matrix() * dv + m_drift_masked;
137 }
138
139 Index TaskSE3Equality::frame_id() const { return m_frame_id; }
140
141 const ConstraintBase& TaskSE3Equality::getConstraint() const {
142 return m_constraint;
143 }
144
145 void TaskSE3Equality::useLocalFrame(bool local_frame) {
146 m_local_frame = local_frame;
147 }
148
149 const ConstraintBase& TaskSE3Equality::compute(const double, ConstRefVector,
150 ConstRefVector, Data& data) {
151 SE3 oMi;
152 Motion v_frame;
153 m_robot.framePosition(data, m_frame_id, oMi);
154 m_robot.frameVelocity(data, m_frame_id, v_frame);
155 m_robot.frameClassicAcceleration(data, m_frame_id, m_drift);
156
157 // @todo Since Jacobian computation is cheaper in world frame
158 // we could do all computations in world frame
159 m_robot.frameJacobianLocal(data, m_frame_id, m_J);
160
161 errorInSE3(oMi, m_M_ref, m_p_error); // pos err in local frame
162 SE3ToVector(m_M_ref, m_p_ref);
163 SE3ToVector(oMi, m_p);
164
165 // Transformation from local to world
166 m_wMl.rotation(oMi.rotation());
167
168 if (m_local_frame) {
169 m_p_error_vec = m_p_error.toVector();
170 m_v_error = m_wMl.actInv(m_v_ref) - v_frame; // vel err in local frame
171
172 // desired acc in local frame
173 m_a_des = m_Kp.cwiseProduct(m_p_error_vec) +
174 m_Kd.cwiseProduct(m_v_error.toVector()) +
175 m_wMl.actInv(m_a_ref).toVector();
176 } else {
177 m_p_error_vec =
178 m_wMl.toActionMatrix() * // pos err in local world-oriented frame
179 m_p_error.toVector();
180
181 // cout<<"m_p_error_vec="<<m_p_error_vec.head<3>().transpose()<<endl;
182 // cout<<"oMi-m_M_ref
183 // ="<<-(oMi.translation()-m_M_ref.translation()).transpose()<<endl;
184
185 m_v_error =
186 m_v_ref - m_wMl.act(v_frame); // vel err in local world-oriented frame
187
188 m_drift = m_wMl.act(m_drift);
189
190 // desired acc in local world-oriented frame
191 m_a_des = m_Kp.cwiseProduct(m_p_error_vec) +
192 m_Kd.cwiseProduct(m_v_error.toVector()) + m_a_ref.toVector();
193
194 // Use an explicit temporary `m_J_rotated` here to avoid allocations.
195 m_J_rotated.noalias() = m_wMl.toActionMatrix() * m_J;
196 m_J = m_J_rotated;
197 }
198
199 m_v_error_vec = m_v_error.toVector();
200 m_v_ref_vec = m_v_ref.toVector();
201 m_v = v_frame.toVector();
202
203 int idx = 0;
204 for (int i = 0; i < 6; i++) {
205 if (m_mask(i) != 1.) continue;
206
207 m_constraint.matrix().row(idx) = m_J.row(i);
208 m_constraint.vector().row(idx) = (m_a_des - m_drift.toVector()).row(i);
209 m_a_des_masked(idx) = m_a_des(i);
210 m_drift_masked(idx) = m_drift.toVector()(i);
211 m_p_error_masked_vec(idx) = m_p_error_vec(i);
212 m_v_error_masked_vec(idx) = m_v_error_vec(i);
213
214 idx += 1;
215 }
216
217 return m_constraint;
218 }
219 } // namespace tasks
220 } // namespace tsid
221