avoid_singularities.cpp
Go to the documentation of this file.
00001 
00029 #include "constrained_ik/constrained_ik.h"
00030 #include "constrained_ik/constraints/avoid_singularities.h"
00031 #include "ros/ros.h"
00032 #include <pluginlib/class_list_macros.h>
00033 PLUGINLIB_EXPORT_CLASS(constrained_ik::constraints::AvoidSingularities, constrained_ik::Constraint)
00034 
00035 const double DEFAULT_WEIGHT = 1.0; 
00036 const double DEFAULT_ENABLE_THRESHOLD = 0.01; 
00037 const double DEFAULT_IGNORE_THRESHOLD = 1e-5; 
00039 namespace constrained_ik
00040 {
00041 namespace constraints
00042 {
00043 
00044 using namespace Eigen;
00045 
00046 // initialize limits/tolerances to default values
00047 AvoidSingularities::AvoidSingularities() : Constraint(),
00048                                             weight_(DEFAULT_WEIGHT),
00049                                             enable_threshold_(DEFAULT_ENABLE_THRESHOLD),
00050                                             ignore_threshold_(DEFAULT_IGNORE_THRESHOLD)
00051 {
00052 }
00053 
00054 constrained_ik::ConstraintResults AvoidSingularities::evalConstraint(const SolverState &state) const
00055 {
00056   constrained_ik::ConstraintResults output;
00057   AvoidSingularities::AvoidSingularitiesData cdata(state, this);
00058 
00059   output.error = calcError(cdata);
00060   output.jacobian = calcJacobian(cdata);
00061   output.status = checkStatus(cdata);
00062 
00063   return output;
00064 }
00065 
00066 Eigen::VectorXd AvoidSingularities::calcError(const AvoidSingularities::AvoidSingularitiesData &cdata) const
00067 {
00068     size_t n(cdata.avoidance_enabled_? numJoints():0);    // number of columns = joints
00069     VectorXd err(n);
00070     if (cdata.avoidance_enabled_)
00071     {
00072         for (size_t jntIdx=0; jntIdx<n; ++jntIdx)
00073         {
00074             err(jntIdx) = (cdata.Ui_.transpose() * jacobianPartialDerivative(cdata, jntIdx) * cdata.Vi_)(0);
00075         }
00076         err *= (weight_*cdata.smallest_sv_);
00077         err = err.cwiseMax(VectorXd::Constant(n,.25));
00078     }
00079     return err;
00080 }
00081 
00082 Eigen::MatrixXd AvoidSingularities::calcJacobian(const AvoidSingularities::AvoidSingularitiesData &cdata) const
00083 {
00084     size_t n(cdata.avoidance_enabled_? numJoints():0);    // number of columns = joints
00085     MatrixXd  J = MatrixXd::Identity(n,n);
00086     J *= (weight_*cdata.smallest_sv_);
00087     return J;
00088 }
00089 
00090 Eigen::MatrixXd AvoidSingularities::jacobianPartialDerivative(const AvoidSingularities::AvoidSingularitiesData &cdata, size_t jntIdx, double eps) const
00091 {
00092     MatrixXd jacobian_increment;
00093     Eigen::VectorXd joints = cdata.state_.joints;
00094     joints(jntIdx) += eps;
00095 
00096     if (!ik_->getKin().checkJoints(joints))
00097     {
00098         eps = -eps;
00099         joints(jntIdx) += 2*eps;
00100     }
00101     if (!ik_->getKin().calcJacobian(joints, jacobian_increment))
00102         ROS_WARN("Could not calculate jacobian in AvoidSingularities");
00103     return (jacobian_increment-cdata.jacobian_orig_)/eps;
00104 }
00105 
00106 void AvoidSingularities::loadParameters(const XmlRpc::XmlRpcValue &constraint_xml)
00107 {
00108   XmlRpc::XmlRpcValue local_xml = constraint_xml;
00109   if (!getParam(local_xml, "enable_threshold", enable_threshold_))
00110   {
00111     ROS_WARN("Avoid Singularities: Unable to retrieve enable_threshold member, default parameter will be used.");
00112   }
00113 
00114   if (!getParam(local_xml, "ignore_threshold", ignore_threshold_))
00115   {
00116     ROS_WARN("Avoid Singularities: Unable to retrieve ignore_threshold member, default parameter will be used.");
00117   }
00118 
00119   if (!getParam(local_xml, "weights", weight_))
00120   {
00121     ROS_WARN("Avoid Singularities: Unable to retrieve weights member, default parameter will be used.");
00122   }
00123 
00124   if (!getParam(local_xml, "debug", debug_))
00125   {
00126     ROS_WARN("Avoid Singularities: Unable to retrieve debug member, default parameter will be used.");
00127   }
00128 }
00129 
00130 AvoidSingularities::AvoidSingularitiesData::AvoidSingularitiesData(const SolverState &state, const constraints::AvoidSingularities *parent): ConstraintData(state)
00131 {
00132   if (!parent->initialized_) return;
00133   parent_ = parent;
00134 
00135   parent_->ik_->getKin().calcJacobian(state_.joints, jacobian_orig_);
00136   Eigen::JacobiSVD<MatrixXd> svd(jacobian_orig_, Eigen::ComputeThinU | Eigen::ComputeThinV);
00137   Ui_ = svd.matrixU().rightCols(1);
00138   Vi_ = svd.matrixV().rightCols(1);
00139   smallest_sv_ = svd.singularValues().tail(1)(0);
00140   avoidance_enabled_ =  smallest_sv_ < parent_->enable_threshold_ && smallest_sv_ > parent_->ignore_threshold_;
00141   if (avoidance_enabled_)
00142     ROS_INFO_STREAM("Sing. avoidance with s=" << svd.singularValues().tail(1));
00143 }
00144 
00145 } // namespace constraints
00146 } // namespace constrained_ik
00147 


constrained_ik
Author(s): Chris Lewis , Jeremy Zoss , Dan Solomon
autogenerated on Sat Jun 8 2019 19:23:45