chainexternalwrenchestimator.cpp
Go to the documentation of this file.
1 // Copyright (C) 2021 Djordje Vukcevic <djordje dot vukcevic at h-brs dot de>
2 
3 // Version: 1.0
4 // Author: Djordje Vukcevic <djordje dot vukcevic at h-brs dot de>
5 // URL: http://www.orocos.org/kdl
6 
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // Lesser General Public License for more details.
16 
17 // You should have received a copy of the GNU Lesser General Public
18 // License along with this library; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 
22 
23 namespace KDL {
24 
25 ChainExternalWrenchEstimator::ChainExternalWrenchEstimator(const Chain &chain, const Vector &gravity, const double sample_frequency, const double estimation_gain, const double filter_constant, const double eps, const int maxiter) :
26  CHAIN(chain),
27  DT_SEC(1.0 / sample_frequency), FILTER_CONST(filter_constant),
28  svd_eps(eps),
29  svd_maxiter(maxiter),
30  nj(CHAIN.getNrOfJoints()), ns(CHAIN.getNrOfSegments()),
31  jnt_mass_matrix(nj), previous_jnt_mass_matrix(nj), jnt_mass_matrix_dot(nj),
32  initial_jnt_momentum(nj), estimated_momentum_integral(nj), filtered_estimated_ext_torque(nj),
33  gravity_torque(nj), coriolis_torque(nj), total_torque(nj), estimated_ext_torque(nj),
34  jacobian_end_eff(nj),
35  jacobian_end_eff_transpose(Eigen::MatrixXd::Zero(nj, 6)), jacobian_end_eff_transpose_inv(Eigen::MatrixXd::Zero(6, nj)),
36  U(Eigen::MatrixXd::Zero(nj, 6)), V(Eigen::MatrixXd::Zero(6, 6)),
37  S(Eigen::VectorXd::Zero(6)), S_inv(Eigen::VectorXd::Zero(6)), tmp(Eigen::VectorXd::Zero(6)),
38  ESTIMATION_GAIN(Eigen::VectorXd::Constant(nj, estimation_gain)),
39  dynparam_solver(CHAIN, gravity),
40  jacobian_solver(CHAIN),
41  fk_pos_solver(CHAIN)
42 {
43 }
44 
46 {
49  jnt_mass_matrix.resize(nj);
51  jnt_mass_matrix_dot.resize(nj);
60  jacobian_end_eff_transpose.conservativeResizeLike(Eigen::MatrixXd::Zero(nj, 6));
61  jacobian_end_eff_transpose_inv.conservativeResizeLike(Eigen::MatrixXd::Zero(6, nj));
62  U.conservativeResizeLike(Eigen::MatrixXd::Zero(nj, 6));
63  V.conservativeResizeLike(Eigen::MatrixXd::Zero(6, 6));
64  S.conservativeResizeLike(Eigen::VectorXd::Zero(6));
65  S_inv.conservativeResizeLike(Eigen::VectorXd::Zero(6));
66  tmp.conservativeResizeLike(Eigen::VectorXd::Zero(6));
67  ESTIMATION_GAIN.conservativeResizeLike(Eigen::VectorXd::Constant(nj, ESTIMATION_GAIN(0)));
71 }
72 
73 // Calculates robot's initial momentum in the joint space. If this method is not called by the user, zero values will be taken for the initial momentum.
74 int ChainExternalWrenchEstimator::setInitialMomentum(const JntArray &joint_position, const JntArray &joint_velocity)
75 {
76  // Check sizes first
77  if (joint_position.rows() != nj || joint_velocity.rows() != nj)
78  return (error = E_SIZE_MISMATCH);
79 
80  // Calculate robot's inertia and momentum in the joint space
81  if (E_NOERROR != dynparam_solver.JntToMass(joint_position, jnt_mass_matrix))
83 
84  initial_jnt_momentum.data = jnt_mass_matrix.data * joint_velocity.data;
85 
86  // Reset data because of the new momentum offset
89 
90  return (error = E_NOERROR);
91 }
92 
93 // Sets singular-value eps parameter for the SVD calculation
94 void ChainExternalWrenchEstimator::setSVDEps(const double eps_in)
95 {
96  svd_eps = eps_in;
97 }
98 
99 // Sets maximum iteration parameter for the SVD calculation
101 {
102  svd_maxiter = maxiter_in;
103 }
104 
105 // This method calculates the external wrench that is applied on the robot's end-effector.
106 int ChainExternalWrenchEstimator::JntToExtWrench(const JntArray &joint_position, const JntArray &joint_velocity, const JntArray &joint_torque, Wrench &external_wrench)
107 {
117  // Check sizes first
118  if (nj != CHAIN.getNrOfJoints() || ns != CHAIN.getNrOfSegments())
119  return (error = E_NOT_UP_TO_DATE);
120  if (joint_position.rows() != nj || joint_velocity.rows() != nj || joint_torque.rows() != nj)
121  return (error = E_SIZE_MISMATCH);
122 
129  // Calculate decomposed robot's dynamics
130  if (E_NOERROR != dynparam_solver.JntToMass(joint_position, jnt_mass_matrix))
132 
133  if (E_NOERROR != dynparam_solver.JntToCoriolis(joint_position, joint_velocity, coriolis_torque))
135 
136  if (E_NOERROR != dynparam_solver.JntToGravity(joint_position, gravity_torque))
138 
139  // Calculate the change of robot's inertia in the joint space
141 
142  // Save data for the next iteration
144 
145  // Calculate total torque exerted on the joint
146  total_torque.data = joint_torque.data - gravity_torque.data - coriolis_torque.data + jnt_mass_matrix_dot.data * joint_velocity.data;
147 
148  // Accumulate main integral
150 
151  // Estimate external joint torque
153 
154  // First order low-pass filter: filter out the noise from the estimated signal
155  // This filter can be turned off by setting FILTER_CONST value to 0
157 
164  // Compute robot's end-effector frame, expressed in the base frame
165  Frame end_eff_frame;
166  if (E_NOERROR != fk_pos_solver.JntToCart(joint_position, end_eff_frame))
167  return (error = E_FKSOLVERPOS_FAILED);
168 
169  // Compute robot's jacobian for the end-effector frame, expressed in the base frame
170  if (E_NOERROR != jacobian_solver.JntToJac(joint_position, jacobian_end_eff))
171  return (error = E_JACSOLVER_FAILED);
172 
173  // Transform the jacobian from the base frame to the end-effector frame.
174  // This part can be commented out if the user wants estimated wrench to be expressed w.r.t. base frame
175  jacobian_end_eff.changeBase(end_eff_frame.M.Inverse()); // Jacobian is now expressed w.r.t. end-effector frame
176 
177  // SVD of "Jac^T" with maximum iterations "maxiter": Jac^T = U * S^-1 * V^T
180  return (error = E_SVD_FAILED);
181 
182  // Invert singular values: S^-1
183  for (int i = 0; i < S.size(); ++i)
184  S_inv(i) = (std::fabs(S(i)) < svd_eps) ? 0.0 : 1.0 / S(i);
185 
186  // Compose the inverse: (Jac^T)^-1 = V * S^-1 * U^T
187  jacobian_end_eff_transpose_inv = V * S_inv.asDiagonal() * U.adjoint();
188 
189  // Compute end-effector's Cartesian wrench from the estimated joint torques: (Jac^T)^-1 * ext_tau
191  for (int i = 0; i < 6; i++)
192  external_wrench(i) = estimated_wrench(i);
193 
194  return (error = E_NOERROR);
195 }
196 
197 // Getter for the torques felt in the robot's joints due to the external wrench being applied on the robot
199 {
200  assert(external_joint_torque.rows() == filtered_estimated_ext_torque.rows());
201  external_joint_torque = filtered_estimated_ext_torque;
202 }
203 
204 const char* ChainExternalWrenchEstimator::strError(const int error) const
205 {
206  if (E_FKSOLVERPOS_FAILED == error) return "Internally-used Forward Position Kinematics (Recursive) solver failed";
207  else if (E_JACSOLVER_FAILED == error) return "Internally-used Jacobian solver failed";
208  else if (E_DYNPARAMSOLVERMASS_FAILED == error) return "Internally-used Dynamics Parameters (Mass) solver failed";
209  else if (E_DYNPARAMSOLVERCORIOLIS_FAILED == error) return "Internally-used Dynamics Parameters (Coriolis) solver failed";
210  else if (E_DYNPARAMSOLVERGRAVITY_FAILED == error) return "Internally-used Dynamics Parameters (Gravity) solver failed";
211  else return SolverI::strError(error);
212 }
213 
214 } // namespace
static const int E_JACSOLVER_FAILED
Internally-used Forward Position Kinematics (Recursive) solver failed.
virtual int JntToCart(const JntArray &q_in, Frame &p_out, int segmentNr=-1)
void resize(unsigned int newNrOfColumns)
Allocates memory for new size (can break realtime behavior)
Definition: jacobian.cpp:54
This class encapsulates a serial kinematic interconnection structure. It is built out of segments...
Definition: chain.hpp:35
unsigned int getNrOfSegments() const
Definition: chain.hpp:76
Chain size changed.
Definition: solveri.hpp:97
This class represents an fixed size array containing joint values of a KDL::Chain.
Definition: jntarray.hpp:69
int JntToExtWrench(const JntArray &joint_position, const JntArray &joint_velocity, const JntArray &joint_torque, Wrench &external_wrench)
Input size does not match internal state.
Definition: solveri.hpp:99
static const int E_DYNPARAMSOLVERMASS_FAILED
Internally-used Jacobian solver failed.
unsigned int rows() const
Definition: jntarray.cpp:70
EIGEN_MAKE_ALIGNED_OPERATOR_NEW Eigen::Matrix< double, 6, Eigen::Dynamic > data
Definition: jacobian.hpp:41
IMETHOD void SetToZero(Vector &v)
Definition: frames.hpp:1069
virtual void updateInternalDataStructures()
unsigned int getNrOfJoints() const
Definition: chain.hpp:71
A concrete implementation of a 3 dimensional vector class.
Definition: frames.hpp:162
Internal svd calculation failed.
Definition: solveri.hpp:107
virtual const char * strError(const int error) const
Eigen::VectorXd data
Definition: jntarray.hpp:72
ChainExternalWrenchEstimator(const Chain &chain, const Vector &gravity, const double sample_frequency, const double estimation_gain, const double filter_constant, const double eps=0.00001, const int maxiter=150)
Internally-used Dynamics Parameters (Gravity) solver failed.
int svd_eigen_HH(const Eigen::MatrixXd &A, Eigen::MatrixXd &U, Eigen::VectorXd &S, Eigen::MatrixXd &V, Eigen::VectorXd &tmp, int maxiter, double epsilon)
friend bool changeBase(const Jacobian &src1, const Rotation &rot, Jacobian &dest)
Definition: jacobian.cpp:103
static const int E_DYNPARAMSOLVERGRAVITY_FAILED
Internally-used Dynamics Parameters (Coriolis) solver failed.
int setInitialMomentum(const JntArray &joint_position, const JntArray &joint_velocity)
virtual int JntToCoriolis(const JntArray &q, const JntArray &q_dot, JntArray &coriolis)
void resize(unsigned int newSize)
Definition: jntarray.cpp:53
represents a frame transformation in 3D space (rotation + translation)
Definition: frames.hpp:572
virtual void updateInternalDataStructures()
void getEstimatedJntTorque(JntArray &external_joint_torque)
represents both translational and rotational acceleration.
Definition: frames.hpp:881
virtual const char * strError(const int error) const
Definition: solveri.hpp:125
virtual int JntToJac(const JntArray &q_in, Jacobian &jac, int seg_nr=-1)
static const int E_DYNPARAMSOLVERCORIOLIS_FAILED
Internally-used Dynamics Parameters (Mass) solver failed.
virtual int JntToMass(const JntArray &q, JntSpaceInertiaMatrix &H)
int error
Latest error, initialized to E_NOERROR in constructor.
Definition: solveri.hpp:149
virtual int JntToGravity(const JntArray &q, JntArray &gravity)


orocos_kdl
Author(s):
autogenerated on Thu Apr 13 2023 02:19:14