kinematics_metrics.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 *
00003 * Software License Agreement (BSD License)
00004 *
00005 *  Copyright (c) 2012, Willow Garage, Inc.
00006 *  All rights reserved.
00007 *
00008 *  Redistribution and use in source and binary forms, with or without
00009 *  modification, are permitted provided that the following conditions
00010 *  are met:
00011 *
00012 *   * Redistributions of source code must retain the above copyright
00013 *     notice, this list of conditions and the following disclaimer.
00014 *   * Redistributions in binary form must reproduce the above
00015 *     copyright notice, this list of conditions and the following
00016 *     disclaimer in the documentation and/or other materials provided
00017 *     with the distribution.
00018 *   * Neither the name of the Willow Garage nor the names of its
00019 *     contributors may be used to endorse or promote products derived
00020 *     from this software without specific prior written permission.
00021 *
00022 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033 *  POSSIBILITY OF SUCH DAMAGE.
00034 *
00035 * Author: Sachin Chitta
00036 *********************************************************************/
00037 
00038 #include <moveit/kinematics_metrics/kinematics_metrics.h>
00039 #include <Eigen/Eigenvalues>
00040 #include <boost/math/constants/constants.hpp>
00041 
00042 namespace kinematics_metrics
00043 {
00044 
00045 Eigen::MatrixXd KinematicsMetrics::getJacobian(const robot_state::RobotState &kinematic_state,
00046                                                const robot_model::JointModelGroup *joint_model_group) const
00047 {
00048   Eigen::MatrixXd jacobian;
00049   Eigen::Vector3d reference_point_position(0.0, 0.0, 0.0);
00050   std::string link_name = joint_model_group->getLinkModelNames().back();
00051   kinematic_state.getJointStateGroup(joint_model_group->getName())->getJacobian(link_name, reference_point_position, jacobian);
00052   return jacobian;
00053 }
00054 
00055 double KinematicsMetrics::getJointLimitsPenalty(const robot_state::JointStateGroup* joint_state_group) const
00056 {
00057   if(fabs(penalty_multiplier_) <= boost::math::tools::epsilon<double>())
00058      return 1.0;
00059   double joint_limits_multiplier(1.0);
00060   const std::vector<robot_state::JointState*> &joint_state_vector = joint_state_group->getJointStateVector();
00061   for(std::size_t i=0; i < joint_state_group->getJointStateVector().size(); ++i)
00062   {
00063      if(joint_state_vector[i]->getType() == robot_model::JointModel::REVOLUTE)
00064     {
00065       const robot_model::RevoluteJointModel* revolute_model = dynamic_cast<const robot_model::RevoluteJointModel*> (joint_state_vector[i]->getJointModel());
00066       if(revolute_model->isContinuous())
00067         continue;
00068     }
00069     if(joint_state_vector[i]->getType() == robot_model::JointModel::PLANAR)
00070     {
00071       const std::vector<std::pair<double, double> >& planar_bounds = joint_state_vector[i]->getVariableBounds();
00072       if(planar_bounds[0].first == -std::numeric_limits<double>::max() || planar_bounds[0].second == std::numeric_limits<double>::max() ||
00073          planar_bounds[1].first == -std::numeric_limits<double>::max() || planar_bounds[1].second == std::numeric_limits<double>::max() ||
00074          planar_bounds[2].first == -boost::math::constants::pi<double>() || planar_bounds[2].second == boost::math::constants::pi<double>())
00075         continue;
00076     }
00077     if(joint_state_vector[i]->getType() == robot_model::JointModel::FLOATING)
00078     {
00079       //Joint limits are not well-defined for floating joints
00080       continue;
00081     }
00082     const std::vector<double>& joint_values = joint_state_vector[i]->getVariableValues();
00083     const std::vector<std::pair<double, double> >& bounds = joint_state_vector[i]->getVariableBounds();
00084     std::vector<double> lower_bounds, upper_bounds;
00085     for(std::size_t j=0; j < bounds.size(); ++j)
00086     {
00087       lower_bounds.push_back(bounds[j].first);
00088       upper_bounds.push_back(bounds[j].second);
00089     }
00090     double lower_bound_distance = joint_state_vector[i]->getJointModel()->distance(joint_values, lower_bounds);
00091     double upper_bound_distance = joint_state_vector[i]->getJointModel()->distance(joint_values, upper_bounds);
00092     double range = lower_bound_distance + upper_bound_distance;
00093     if(range <= boost::math::tools::epsilon<double>())
00094       continue;
00095     joint_limits_multiplier *= (lower_bound_distance * upper_bound_distance/(range*range));
00096   }
00097   return(1.0 - exp(-penalty_multiplier_*joint_limits_multiplier));
00098 }
00099 
00100 bool KinematicsMetrics::getManipulabilityIndex(const robot_state::RobotState &kinematic_state,
00101                                                const std::string &group_name,
00102                                                double &manipulability_index,
00103                                                bool translation) const
00104 {
00105   const robot_model::JointModelGroup *joint_model_group = kinematic_model_->getJointModelGroup(group_name);
00106   return getManipulabilityIndex(kinematic_state, joint_model_group, manipulability_index, translation);
00107 }
00108 
00109 bool KinematicsMetrics::getManipulabilityIndex(const robot_state::RobotState &kinematic_state,
00110                                                const robot_model::JointModelGroup *joint_model_group,
00111                                                double &manipulability_index,
00112                                                bool translation) const
00113 {
00114   if (!joint_model_group)
00115   {
00116     logError("Joint model group does not exist");
00117     return false;
00118   }
00119   Eigen::MatrixXd jacobian = getJacobian(kinematic_state, joint_model_group);
00120   // Get joint limits penalty
00121   double penalty = getJointLimitsPenalty(kinematic_state.getJointStateGroup(joint_model_group->getName()));
00122   if(translation)
00123   {
00124     Eigen::MatrixXd jacobian_2 = jacobian.topLeftCorner(3,jacobian.cols());
00125     Eigen::MatrixXd matrix = jacobian_2*jacobian_2.transpose();
00126     // Get manipulability index
00127     manipulability_index = penalty * sqrt(matrix.determinant());
00128   }
00129   else
00130   {
00131     Eigen::MatrixXd matrix = jacobian*jacobian.transpose();
00132     // Get manipulability index
00133     manipulability_index = penalty * sqrt(matrix.determinant());
00134   }
00135   return true;
00136 }
00137 
00138 bool KinematicsMetrics::getManipulabilityEllipsoid(const robot_state::RobotState &kinematic_state,
00139                                                    const std::string &group_name,
00140                                                    Eigen::MatrixXcd &eigen_values,
00141                                                    Eigen::MatrixXcd &eigen_vectors) const
00142 {
00143   const robot_model::JointModelGroup *joint_model_group = kinematic_model_->getJointModelGroup(group_name);
00144   return getManipulabilityEllipsoid(kinematic_state, joint_model_group, eigen_values, eigen_vectors);
00145 }
00146 
00147 bool KinematicsMetrics::getManipulabilityEllipsoid(const robot_state::RobotState &kinematic_state,
00148                                                    const robot_model::JointModelGroup *joint_model_group,
00149                                                    Eigen::MatrixXcd &eigen_values,
00150                                                    Eigen::MatrixXcd &eigen_vectors) const
00151 {
00152   if (!joint_model_group)
00153   {
00154     logError("Joint model group does not exist");
00155     return false;
00156   }
00157   Eigen::MatrixXd jacobian = getJacobian(kinematic_state, joint_model_group);
00158   Eigen::MatrixXd matrix = jacobian*jacobian.transpose();
00159   Eigen::EigenSolver<Eigen::MatrixXd> eigensolver(matrix.block(0, 0, 3, 3));
00160   eigen_values = eigensolver.eigenvalues();
00161   eigen_vectors = eigensolver.eigenvectors();
00162   return true;
00163 }
00164 
00165 bool KinematicsMetrics::getManipulability(const robot_state::RobotState &kinematic_state,
00166                                           const std::string &group_name,
00167                                           double &manipulability,
00168                                           bool translation) const
00169 {
00170   const robot_model::JointModelGroup *joint_model_group = kinematic_model_->getJointModelGroup(group_name);
00171   return getManipulability(kinematic_state, joint_model_group, manipulability, translation);
00172 }
00173 
00174 bool KinematicsMetrics::getManipulability(const robot_state::RobotState &kinematic_state,
00175                                           const robot_model::JointModelGroup *joint_model_group,
00176                                           double &manipulability,
00177                                           bool translation) const
00178 {
00179   if (!joint_model_group)
00180   {
00181     logError("Joint model group does not exist");
00182     return false;
00183   }
00184 
00185   // Get joint limits penalty
00186   double penalty = getJointLimitsPenalty(kinematic_state.getJointStateGroup(joint_model_group->getName()));
00187   if(translation)
00188   {
00189     Eigen::MatrixXd jacobian = getJacobian(kinematic_state, joint_model_group);
00190     Eigen::JacobiSVD<Eigen::MatrixXd> svdsolver(jacobian.topLeftCorner(3,jacobian.cols()));
00191     Eigen::MatrixXd singular_values = svdsolver.singularValues();
00192     for(unsigned int i=0; i < singular_values.rows(); ++i)
00193       logDebug("Singular value: %d %f",i,singular_values(i,0));
00194     manipulability = penalty * singular_values.minCoeff()/singular_values.maxCoeff();
00195   }
00196   else
00197   {
00198     Eigen::MatrixXd jacobian = getJacobian(kinematic_state, joint_model_group);
00199     Eigen::JacobiSVD<Eigen::MatrixXd> svdsolver(jacobian);
00200     Eigen::MatrixXd singular_values = svdsolver.singularValues();
00201     for(unsigned int i=0; i < singular_values.rows(); ++i)
00202       logDebug("Singular value: %d %f",i,singular_values(i,0));
00203     manipulability = penalty * singular_values.minCoeff()/singular_values.maxCoeff();
00204   }
00205   return true;
00206 }
00207 
00208 } // namespace


moveit_core
Author(s): Ioan Sucan , Sachin Chitta , Acorn Pooley
autogenerated on Mon Oct 6 2014 02:24:47