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
00019 #include "constrained_ik/constrained_ik.h"
00020 #include "constrained_ik/constraints/avoid_singularities.h"
00021 #include "ros/ros.h"
00022
00023 namespace constrained_ik
00024 {
00025 namespace constraints
00026 {
00027
00028 using namespace Eigen;
00029
00030
00031 AvoidSingularities::AvoidSingularities() : Constraint(),
00032 weight_(1.0),
00033 enable_threshold_(.01),
00034 ignore_threshold_(1e-5),
00035 smallest_sv_(0.0),
00036 avoidance_enabled_(false)
00037 {
00038 }
00039
00040 Eigen::VectorXd AvoidSingularities::calcError()
00041 {
00042 size_t n(avoidance_enabled_? numJoints():0);
00043 VectorXd err(n);
00044 if (avoidance_enabled_)
00045 {
00046 for (size_t jntIdx=0; jntIdx<n; ++jntIdx)
00047 {
00048 err(jntIdx) = (Ui_.transpose() * jacobianPartialDerivative(jntIdx) * Vi_)(0);
00049 }
00050 err *= (weight_*smallest_sv_);
00051 err = err.cwiseMax(VectorXd::Constant(n,.25));
00052 }
00053 return err;
00054 }
00055
00056 Eigen::MatrixXd AvoidSingularities::calcJacobian()
00057 {
00058 size_t n(avoidance_enabled_? numJoints():0);
00059 MatrixXd J = MatrixXd::Identity(n,n);
00060 J *= (weight_*smallest_sv_);
00061 return J;
00062 }
00063
00064 Eigen::MatrixXd AvoidSingularities::jacobianPartialDerivative(size_t jntIdx, double eps)
00065 {
00066 MatrixXd jacobian_increment;
00067 Eigen::VectorXd joints = state_.joints;
00068 joints(jntIdx) += eps;
00069
00070 if (!ik_->getKin().checkJoints(joints))
00071 {
00072 eps = -eps;
00073 joints(jntIdx) += 2*eps;
00074 }
00075 if (!ik_->getKin().calcJacobian(joints, jacobian_increment))
00076 ROS_WARN("Could not calculate jacobian in AvoidSingularities");
00077 return (jacobian_increment-jacobian_orig_)/eps;
00078 }
00079
00080 void AvoidSingularities::update(const SolverState &state)
00081 {
00082 Constraint::update(state);
00083 size_t n = numJoints();
00084
00085 ik_->getKin().calcJacobian(state_.joints, jacobian_orig_);
00086 Eigen::JacobiSVD<MatrixXd> svd(jacobian_orig_, Eigen::ComputeThinU | Eigen::ComputeThinV);
00087 Ui_ = svd.matrixU().col(n-1);
00088 Vi_ = svd.matrixV().col(n-1);
00089 smallest_sv_ = svd.singularValues().tail(1)(0);
00090 avoidance_enabled_ = smallest_sv_ < enable_threshold_ && smallest_sv_ > ignore_threshold_;
00091 if (avoidance_enabled_)
00092 {
00093 ROS_INFO_STREAM("Sing. avoidance with s=" << svd.singularValues().tail(1));
00094 }
00095
00096 }
00097
00098 }
00099 }
00100