Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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;
00032 Eigen::VectorXd singularValues = svd.singularValues();
00033 Eigen::VectorXd singularValuesInv = Eigen::VectorXd::Zero(singularValues.rows());
00034
00035
00036 for (uint32_t i = 0; i < singularValues.rows(); ++i)
00037 {
00038 double denominator = singularValues(i) * singularValues(i);
00039
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
00064
00065 for (uint32_t i = 0; i < singularValues.rows()-1; ++i)
00066 {
00067
00068 singularValuesInv(i) = singularValues(i) / (pow(singularValues(i), 2) + pow(params.beta, 2));
00069 }
00070
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
00077 for (uint32_t i = 0; i < singularValues.rows(); ++i)
00078 {
00079 double denominator = (singularValues(i) * singularValues(i) + lambda(i, i) );
00080
00081 singularValuesInv(i) = (singularValues(i) < eps_truncation) ? 0.0 : singularValues(i) / denominator;
00082 }
00083
00085
00086
00087
00088
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 }