avoid_joint_limits.cpp
Go to the documentation of this file.
00001 /*
00002  * avoid_joint_limits.cpp
00003  *
00004  *  Created on: Sep 23, 2013
00005  *      Author: dsolomon
00006  */
00007 /*
00008  * Software License Agreement (Apache License)
00009  *
00010  * Copyright (c) 2013, Southwest Research Institute
00011  *
00012  * Licensed under the Apache License, Version 2.0 (the "License");
00013  * you may not use this file except in compliance with the License.
00014  * You may obtain a copy of the License at
00015  *
00016  *   http://www.apache.org/licenses/LICENSE-2.0
00017  *
00018  * Unless required by applicable law or agreed to in writing, software
00019  * distributed under the License is distributed on an "AS IS" BASIS,
00020  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00021  * See the License for the specific language governing permissions and
00022  * limitations under the License.
00023  */
00024 
00025 #include "constrained_ik/constraints/avoid_joint_limits.h"
00026 #include "constrained_ik/constrained_ik.h"
00027 #include <ros/ros.h>
00028 
00029 namespace constrained_ik
00030 {
00031 namespace constraints
00032 {
00033 
00034 using namespace Eigen;
00035 using namespace std;
00036 
00037 Eigen::VectorXd AvoidJointLimits::calcError()
00038 {
00039   size_t nRows = limited_joints_.size();
00040   VectorXd error(nRows);
00041 
00042   for (int ii=0; ii<nRows; ++ii)
00043   {
00044     size_t jntIdx = limited_joints_[ii];
00045     int velSign;
00046     const LimitsT &lim = limits_[jntIdx];
00047     double limit;
00048     if (nearLowerLimit(jntIdx))
00049     {
00050         velSign = 1; // lower limit: positive velocity
00051         limit = lim.min_pos;
00052     }
00053     else
00054     {
00055         velSign = -1;   //upper limit, negative velocity
00056         limit = lim.max_pos;
00057     }
00058 
00059     error(ii) = velSign * weight_ * lim.cubicVelRamp(state_.joints[jntIdx], limit);
00060 
00061     if (debug_)
00062     {
00063         ROS_WARN_STREAM("iteration " << state_.iter << std::endl <<
00064                          "Joint position: " << state_.joints(jntIdx) << " / " << limit << std::endl <<
00065                          "velocity error: " << error(ii) << " / " << lim.e/2.0);
00066     }
00067   }
00068   return error;
00069 }
00070 
00071 Eigen::MatrixXd AvoidJointLimits::calcJacobian()
00072 {
00073   size_t nRows = limited_joints_.size();
00074   MatrixXd jacobian(nRows, numJoints());
00075 
00076   for (int ii=0; ii<nRows; ++ii)
00077   {
00078     size_t jntIdx = limited_joints_[ii];
00079 
00080     VectorXd tmpRow = VectorXd::Zero(numJoints());
00081     tmpRow(jntIdx) = 1.0;
00082 
00083     jacobian.row(ii) = tmpRow * weight_;
00084   }
00085 
00086   return jacobian;
00087 }
00088 
00089 bool AvoidJointLimits::checkStatus() const
00090 {
00091     size_t n = state_.joints.size();
00092     for (size_t ii = 0; ii<n; ++ii)
00093         if (state_.joints[ii] > limits_[ii].max_pos || state_.joints[ii] < limits_[ii].min_pos)
00094             return false;
00095     return true;
00096 }
00097 
00098 void AvoidJointLimits::init(const Constrained_IK *ik)
00099 {
00100   Constraint::init(ik);
00101 
00102   // initialize joint/thresholding limits
00103   MatrixXd joint_limits = ik->getKin().getLimits();
00104   for (size_t ii=0; ii<numJoints(); ++ii)
00105     limits_.push_back( LimitsT(joint_limits(ii,0), joint_limits(ii,1), threshold_ ) );
00106 }
00107 
00108 bool AvoidJointLimits::nearLowerLimit(size_t idx)
00109 {
00110   if (idx >= state_.joints.size() || idx >= limits_.size() )
00111     return false;
00112 
00113   return state_.joints(idx) < limits_[idx].lower_thresh;
00114 }
00115 bool AvoidJointLimits::nearUpperLimit(size_t idx)
00116 {
00117   if (idx >= state_.joints.size() || idx >= limits_.size() )
00118     return false;
00119 
00120   return state_.joints(idx) > limits_[idx].upper_thresh;
00121 }
00122 
00123 void AvoidJointLimits::reset()
00124 {
00125   limited_joints_.clear();
00126 }
00127 
00128 // TODO: Move this to a common "utils" file
00129 template<class T>
00130 std::ostream& operator<< (std::ostream& os, const std::vector<T>& v)
00131 {
00132   if (!v.empty())
00133   {
00134     copy(v.begin(), v.end()-1, std::ostream_iterator<T>(os, ", "));
00135     os << v.back();  // no comma after last element
00136   }
00137   return os;
00138 }
00139 
00140 void AvoidJointLimits::update(const SolverState &state)
00141 {
00142   if (!initialized_) return;
00143   Constraint::update(state);
00144   limited_joints_.clear();
00145 
00146   // check for limited joints
00147   for (size_t ii=0; ii<numJoints(); ++ii)
00148     if ( nearLowerLimit(ii) || nearUpperLimit(ii) )
00149       limited_joints_.push_back(ii);
00150 
00151   // print debug message, if enabled
00152   if (debug_ && !limited_joints_.empty())
00153     ROS_WARN_STREAM(limited_joints_.size() << " joint limits active: " << limited_joints_);
00154 }
00155 
00156 AvoidJointLimits::LimitsT::LimitsT(double minPos, double maxPos, double threshold)
00157 {
00158   min_pos = minPos;
00159   max_pos = maxPos;
00160 
00161 //  range = maxPos - minPos;
00162 
00163   //threshold given as a percentage of range. Translate to actual joint distance
00164   e = threshold * (maxPos - minPos); //range;
00165   lower_thresh = minPos + e;
00166   upper_thresh = maxPos - e;
00167 
00168   /* For d = distance from limit: velocity v = k(d-e)^3, where e is distance from threshold to limit.
00169    * k is chosen such that v_max = v[d=0] = e/2 --> k = 1/(2e^2)
00170    */
00171   k3 = 1.0/(2 * e * e);
00172 }
00173 
00174 double AvoidJointLimits::LimitsT::cubicVelRamp(double angle, double limit) const
00175 {
00176     double d = std::abs(angle - limit); // distance from limit
00177     return k3 * std::pow(e-d,3);
00178 }
00179 
00180 } /* namespace jla_ik */
00181 } /* namespace constrained_ik */


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