avoid_singularities.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (Apache License)
00003  *
00004  * Copyright (c) 2013, Southwest Research Institute
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  *   http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
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 // initialize limits/tolerances to default values
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);    // number of columns = joints
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);    // number of columns = joints
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 //    ROS_INFO_STREAM(smallest_sv_);
00096 }
00097 
00098 } // namespace constraints
00099 } // namespace constrained_ik
00100 


constrained_ik
Author(s): Chris Lewis , Jeremy Zoss , Dan Solomon
autogenerated on Mon Oct 6 2014 00:52:26