inverse_jacobian_calculation.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 
00018 #include <ros/ros.h>
00019 #include <Eigen/Core>
00020 #include <Eigen/SVD>
00021 
00022 #include <cob_twist_controller/inverse_jacobian_calculations/inverse_jacobian_calculation.h>
00023 
00028 Eigen::MatrixXd PInvBySVD::calculate(const Eigen::MatrixXd& jacobian) const
00029 {
00030     Eigen::JacobiSVD<Eigen::MatrixXd> svd(jacobian, Eigen::ComputeThinU | Eigen::ComputeThinV);
00031     double eps_truncation = DIV0_SAFE;  // prevent division by 0.0
00032     Eigen::VectorXd singularValues = svd.singularValues();
00033     Eigen::VectorXd singularValuesInv = Eigen::VectorXd::Zero(singularValues.rows());
00034 
00035     // small change to ref: here quadratic damping due to Control of Redundant Robot Manipulators : R.V. Patel, 2005, Springer [Page 13-14]
00036     for (uint32_t i = 0; i < singularValues.rows(); ++i)
00037     {
00038         double denominator = singularValues(i) * singularValues(i);
00039         // singularValuesInv(i) = (denominator < eps_truncation) ? 0.0 : singularValues(i) / denominator;
00040         singularValuesInv(i) = (singularValues(i) < eps_truncation) ? 0.0 : singularValues(i) / denominator;
00041     }
00042     Eigen::MatrixXd result = svd.matrixV() * singularValuesInv.asDiagonal() * svd.matrixU().transpose();
00043 
00044     return result;
00045 }
00046 
00051 Eigen::MatrixXd PInvBySVD::calculate(const TwistControllerParams& params,
00052                                      boost::shared_ptr<DampingBase> db,
00053                                      const Eigen::MatrixXd& jacobian) const
00054 {
00055     Eigen::JacobiSVD<Eigen::MatrixXd> svd(jacobian, Eigen::ComputeThinU | Eigen::ComputeThinV);
00056     double eps_truncation = params.eps_truncation;
00057     Eigen::VectorXd singularValues = svd.singularValues();
00058     Eigen::VectorXd singularValuesInv = Eigen::VectorXd::Zero(singularValues.rows());
00059     Eigen::MatrixXd lambda = db->getDampingFactor(singularValues, jacobian);
00060 
00061     if (params.numerical_filtering)
00062     {
00063         // Formula 20 Singularity-robust Task-priority Redundandancy Resolution
00064         // Sum part
00065         for (uint32_t i = 0; i < singularValues.rows()-1; ++i)
00066         {
00067             // pow(beta, 2) << pow(lambda, 2)
00068             singularValuesInv(i) = singularValues(i) / (pow(singularValues(i), 2) + pow(params.beta, 2));
00069         }
00070         // Formula 20 - additional part - numerical filtering for least singular value m
00071         uint32_t m = singularValues.rows()-1;
00072         singularValuesInv(m) = singularValues(m) / (pow(singularValues(m), 2) + pow(params.beta, 2) + lambda(m, m));
00073     }
00074     else
00075     {
00076         // small change to ref: here quadratic damping due to Control of Redundant Robot Manipulators : R.V. Patel, 2005, Springer [Page 13-14]
00077         for (uint32_t i = 0; i < singularValues.rows(); ++i)
00078         {
00079             double denominator = (singularValues(i) * singularValues(i) + lambda(i, i) );
00080             // singularValuesInv(i) = (denominator < eps_truncation) ? 0.0 : singularValues(i) / denominator;
00081             singularValuesInv(i) = (singularValues(i) < eps_truncation) ? 0.0 : singularValues(i) / denominator;
00082         }
00083 
00085         // for(uint32_t i = 0; i < singularValues.rows(); ++i)
00086         // {
00087         //       // damping is disabled due to damping factor lower than a const. limit
00088         //       singularValues(i) = (singularValues(i) < eps_truncation) ? 0.0 : 1.0 / singularValues(i);
00089         // }
00090     }
00091 
00092     Eigen::MatrixXd result = svd.matrixV() * singularValuesInv.asDiagonal() * svd.matrixU().transpose();
00093 
00094     return result;
00095 }
00096 
00100 Eigen::MatrixXd PInvDirect::calculate(const Eigen::MatrixXd& jacobian) const
00101 {
00102     Eigen::MatrixXd result;
00103     Eigen::MatrixXd jac_t = jacobian.transpose();
00104     uint32_t rows = jacobian.rows();
00105     uint32_t cols = jacobian.cols();
00106 
00107     if (cols >= rows)
00108     {
00109         result = jac_t * (jacobian * jac_t).inverse();
00110     }
00111     else
00112     {
00113         result = (jac_t * jacobian).inverse() * jac_t;
00114     }
00115 
00116     return result;
00117 }
00118 
00122 Eigen::MatrixXd PInvDirect::calculate(const TwistControllerParams& params,
00123                                       boost::shared_ptr<DampingBase> db,
00124                                       const Eigen::MatrixXd& jacobian) const
00125 {
00126     Eigen::MatrixXd result;
00127     Eigen::MatrixXd jac_t = jacobian.transpose();
00128     uint32_t rows = jacobian.rows();
00129     uint32_t cols = jacobian.cols();
00130     if (params.damping_method == LEAST_SINGULAR_VALUE)
00131     {
00132         ROS_ERROR("PInvDirect does not support SVD. Use PInvBySVD class instead!");
00133     }
00134 
00135     Eigen::MatrixXd lambda = db->getDampingFactor(Eigen::VectorXd::Zero(1, 1), jacobian);
00136     if (cols >= rows)
00137     {
00138         Eigen::MatrixXd ident = Eigen::MatrixXd::Identity(rows, rows);
00139         Eigen::MatrixXd temp = jacobian * jac_t + lambda * ident;
00140         result = jac_t * temp.inverse();
00141     }
00142     else
00143     {
00144         Eigen::MatrixXd ident = Eigen::MatrixXd::Identity(cols, cols);
00145         Eigen::MatrixXd temp = jac_t * jacobian + lambda * ident;
00146         result = temp.inverse() * jac_t;
00147     }
00148 
00149     return result;
00150 }


cob_twist_controller
Author(s): Felix Messmer , Marco Bezzon , Christoph Mark , Francisco Moreno
autogenerated on Thu Jun 6 2019 21:19:26