inverse_jacobian_calculation.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #include <ros/ros.h>
19 #include <Eigen/Core>
20 #include <Eigen/SVD>
21 
23 
28 Eigen::MatrixXd PInvBySVD::calculate(const Eigen::MatrixXd& jacobian) const
29 {
30  Eigen::JacobiSVD<Eigen::MatrixXd> svd(jacobian, Eigen::ComputeThinU | Eigen::ComputeThinV);
31  double eps_truncation = DIV0_SAFE; // prevent division by 0.0
32  Eigen::VectorXd singularValues = svd.singularValues();
33  Eigen::VectorXd singularValuesInv = Eigen::VectorXd::Zero(singularValues.rows());
34 
35  // small change to ref: here quadratic damping due to Control of Redundant Robot Manipulators : R.V. Patel, 2005, Springer [Page 13-14]
36  for (uint32_t i = 0; i < singularValues.rows(); ++i)
37  {
38  double denominator = singularValues(i) * singularValues(i);
39  // singularValuesInv(i) = (denominator < eps_truncation) ? 0.0 : singularValues(i) / denominator;
40  singularValuesInv(i) = (singularValues(i) < eps_truncation) ? 0.0 : singularValues(i) / denominator;
41  }
42  Eigen::MatrixXd result = svd.matrixV() * singularValuesInv.asDiagonal() * svd.matrixU().transpose();
43 
44  return result;
45 }
46 
51 Eigen::MatrixXd PInvBySVD::calculate(const TwistControllerParams& params,
53  const Eigen::MatrixXd& jacobian) const
54 {
55  Eigen::JacobiSVD<Eigen::MatrixXd> svd(jacobian, Eigen::ComputeThinU | Eigen::ComputeThinV);
56  double eps_truncation = params.eps_truncation;
57  Eigen::VectorXd singularValues = svd.singularValues();
58  Eigen::VectorXd singularValuesInv = Eigen::VectorXd::Zero(singularValues.rows());
59  Eigen::MatrixXd lambda = db->getDampingFactor(singularValues, jacobian);
60 
61  if (params.numerical_filtering)
62  {
63  // Formula 20 Singularity-robust Task-priority Redundandancy Resolution
64  // Sum part
65  for (uint32_t i = 0; i < singularValues.rows()-1; ++i)
66  {
67  // pow(beta, 2) << pow(lambda, 2)
68  singularValuesInv(i) = singularValues(i) / (pow(singularValues(i), 2) + pow(params.beta, 2));
69  }
70  // Formula 20 - additional part - numerical filtering for least singular value m
71  uint32_t m = singularValues.rows()-1;
72  singularValuesInv(m) = singularValues(m) / (pow(singularValues(m), 2) + pow(params.beta, 2) + lambda(m, m));
73  }
74  else
75  {
76  // small change to ref: here quadratic damping due to Control of Redundant Robot Manipulators : R.V. Patel, 2005, Springer [Page 13-14]
77  for (uint32_t i = 0; i < singularValues.rows(); ++i)
78  {
79  double denominator = (singularValues(i) * singularValues(i) + lambda(i, i) );
80  // singularValuesInv(i) = (denominator < eps_truncation) ? 0.0 : singularValues(i) / denominator;
81  singularValuesInv(i) = (singularValues(i) < eps_truncation) ? 0.0 : singularValues(i) / denominator;
82  }
83 
85  // for(uint32_t i = 0; i < singularValues.rows(); ++i)
86  // {
87  // // damping is disabled due to damping factor lower than a const. limit
88  // singularValues(i) = (singularValues(i) < eps_truncation) ? 0.0 : 1.0 / singularValues(i);
89  // }
90  }
91 
92  Eigen::MatrixXd result = svd.matrixV() * singularValuesInv.asDiagonal() * svd.matrixU().transpose();
93 
94  return result;
95 }
96 
100 Eigen::MatrixXd PInvDirect::calculate(const Eigen::MatrixXd& jacobian) const
101 {
102  Eigen::MatrixXd result;
103  Eigen::MatrixXd jac_t = jacobian.transpose();
104  uint32_t rows = jacobian.rows();
105  uint32_t cols = jacobian.cols();
106 
107  if (cols >= rows)
108  {
109  result = jac_t * (jacobian * jac_t).inverse();
110  }
111  else
112  {
113  result = (jac_t * jacobian).inverse() * jac_t;
114  }
115 
116  return result;
117 }
118 
122 Eigen::MatrixXd PInvDirect::calculate(const TwistControllerParams& params,
124  const Eigen::MatrixXd& jacobian) const
125 {
126  Eigen::MatrixXd result;
127  Eigen::MatrixXd jac_t = jacobian.transpose();
128  uint32_t rows = jacobian.rows();
129  uint32_t cols = jacobian.cols();
130  if (params.damping_method == LEAST_SINGULAR_VALUE)
131  {
132  ROS_ERROR("PInvDirect does not support SVD. Use PInvBySVD class instead!");
133  }
134 
135  Eigen::MatrixXd lambda = db->getDampingFactor(Eigen::VectorXd::Zero(1, 1), jacobian);
136  if (cols >= rows)
137  {
138  Eigen::MatrixXd ident = Eigen::MatrixXd::Identity(rows, rows);
139  Eigen::MatrixXd temp = jacobian * jac_t + lambda * ident;
140  result = jac_t * temp.inverse();
141  }
142  else
143  {
144  Eigen::MatrixXd ident = Eigen::MatrixXd::Identity(cols, cols);
145  Eigen::MatrixXd temp = jac_t * jacobian + lambda * ident;
146  result = temp.inverse() * jac_t;
147  }
148 
149  return result;
150 }
result
virtual Eigen::MatrixXd calculate(const Eigen::MatrixXd &jacobian) const
virtual Eigen::MatrixXd calculate(const Eigen::MatrixXd &jacobian) const
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
#define ROS_ERROR(...)


cob_twist_controller
Author(s): Felix Messmer , Marco Bezzon , Christoph Mark , Francisco Moreno
autogenerated on Thu Apr 8 2021 02:40:00