avoid_joint_limits.cpp
Go to the documentation of this file.
00001 
00030 #include "constrained_ik/constraints/avoid_joint_limits.h"
00031 #include "constrained_ik/constrained_ik.h"
00032 #include <ros/ros.h>
00033 #include <pluginlib/class_list_macros.h>
00034 PLUGINLIB_EXPORT_CLASS(constrained_ik::constraints::AvoidJointLimits, constrained_ik::Constraint)
00035 
00036 const double DEFAULT_THRESHOLD = 0.05; 
00037 const double DEFAULT_WEIGHT = 1.0; 
00039 namespace constrained_ik
00040 {
00041 namespace constraints
00042 {
00043 
00044 using namespace Eigen;
00045 using namespace std;
00046 
00047 AvoidJointLimits::AvoidJointLimits(): Constraint(), weight_(DEFAULT_WEIGHT), threshold_(DEFAULT_THRESHOLD) {}
00048 
00049 constrained_ik::ConstraintResults AvoidJointLimits::evalConstraint(const SolverState &state) const
00050 {
00051   constrained_ik::ConstraintResults output;
00052   AvoidJointLimits::AvoidJointLimitsData cdata(state, this);
00053 
00054   output.error = calcError(cdata);
00055   output.jacobian = calcJacobian(cdata);
00056   output.status = checkStatus(cdata);
00057 
00058   return output;
00059 }
00060 
00061 Eigen::VectorXd AvoidJointLimits::calcError(const AvoidJointLimits::AvoidJointLimitsData &cdata) const
00062 {
00063   size_t nRows = cdata.limited_joints_.size();
00064   VectorXd error(nRows);
00065 
00066   for (int ii=0; ii<nRows; ++ii)
00067   {
00068     size_t jntIdx = cdata.limited_joints_[ii];
00069     int velSign;
00070     const LimitsT &lim = limits_[jntIdx];
00071     double limit;
00072     if (cdata.nearLowerLimit(jntIdx))
00073     {
00074         velSign = 1; // lower limit: positive velocity
00075         limit = lim.min_pos;
00076     }
00077     else
00078     {
00079         velSign = -1;   //upper limit, negative velocity
00080         limit = lim.max_pos;
00081     }
00082 
00083     error(ii) = velSign * weight_ * lim.cubicVelRamp(cdata.state_.joints[jntIdx], limit);
00084 
00085     if (debug_)
00086     {
00087         ROS_WARN_STREAM("iteration " << cdata.state_.iter << std::endl <<
00088                          "Joint position: " << cdata.state_.joints(jntIdx) << " / " << limit << std::endl <<
00089                          "velocity error: " << error(ii));
00090     }
00091   }
00092   return error;
00093 }
00094 
00095 Eigen::MatrixXd AvoidJointLimits::calcJacobian(const AvoidJointLimits::AvoidJointLimitsData &cdata) const
00096 {
00097   size_t nRows = cdata.limited_joints_.size();
00098   MatrixXd jacobian(nRows, numJoints());
00099 
00100   for (int ii=0; ii<nRows; ++ii)
00101   {
00102     size_t jntIdx = cdata.limited_joints_[ii];
00103 
00104     VectorXd tmpRow = VectorXd::Zero(numJoints());
00105     tmpRow(jntIdx) = 1.0;
00106 
00107     jacobian.row(ii) = tmpRow * weight_;
00108   }
00109 
00110   return jacobian;
00111 }
00112 
00113 void AvoidJointLimits::init(const Constrained_IK *ik)
00114 {
00115   Constraint::init(ik);
00116 
00117   // initialize joint/thresholding limits
00118   MatrixXd joint_limits = ik->getKin().getLimits();
00119   for (size_t ii=0; ii<numJoints(); ++ii)
00120     limits_.push_back( LimitsT(joint_limits(ii,0), joint_limits(ii,1), threshold_ ) );
00121 }
00122 
00123 void AvoidJointLimits::loadParameters(const XmlRpc::XmlRpcValue &constraint_xml)
00124 {
00125   XmlRpc::XmlRpcValue local_xml = constraint_xml;
00126   double threshold;
00127   if (getParam(local_xml, "threshold", threshold))
00128   {
00129     setThreshold(threshold);
00130   }
00131   else
00132   {
00133     ROS_WARN("Avoid Joint Limits: Unable to retrieve threshold member, default parameter will be used.");
00134   }
00135 
00136   double weight;
00137   if (getParam(local_xml, "weights", weight))
00138   {
00139     setWeight(weight);
00140   }
00141   else
00142   {
00143     ROS_WARN("Avoid Joint Limits: Unable to retrieve weights member, default parameter will be used.");
00144   }
00145 
00146   bool debug;
00147   if (getParam(local_xml, "debug", debug))
00148   {
00149     setDebug(debug);
00150   }
00151   else
00152   {
00153     ROS_WARN("Avoid Joint Limits: Unable to retrieve debug member, default parameter will be used.");
00154   }
00155 }
00156 
00161 template<class T>
00162 std::ostream& operator<< (std::ostream& os, const std::vector<T>& v)
00163 {
00164   if (!v.empty())
00165   {
00166     copy(v.begin(), v.end()-1, std::ostream_iterator<T>(os, ", "));
00167     os << v.back();  // no comma after last element
00168   }
00169   return os;
00170 }
00171 
00172 AvoidJointLimits::AvoidJointLimitsData::AvoidJointLimitsData(const SolverState &state, const constraints::AvoidJointLimits *parent): ConstraintData(state)
00173 {
00174   if (!parent->initialized_) return;
00175   parent_ = parent;
00176 
00177   // check for limited joints
00178   for (size_t ii=0; ii<parent_->numJoints(); ++ii)
00179     if ( nearLowerLimit(ii) || nearUpperLimit(ii) )
00180       limited_joints_.push_back(ii);
00181 
00182   // print debug message, if enabled
00183   if (parent_->debug_ && !limited_joints_.empty())
00184     ROS_WARN_STREAM(limited_joints_.size() << " joint limits active: " << limited_joints_);
00185 }
00186 
00187 bool AvoidJointLimits::AvoidJointLimitsData::nearLowerLimit(size_t idx) const
00188 {
00189   if (idx >= state_.joints.size() || idx >= parent_->limits_.size() )
00190     return false;
00191 
00192   return state_.joints(idx) < parent_->limits_[idx].lower_thresh;
00193 }
00194 
00195 bool AvoidJointLimits::AvoidJointLimitsData::nearUpperLimit(size_t idx) const
00196 {
00197   if (idx >= state_.joints.size() || idx >= parent_->limits_.size() )
00198     return false;
00199 
00200   return state_.joints(idx) > parent_->limits_[idx].upper_thresh;
00201 }
00202 
00203 
00204 AvoidJointLimits::LimitsT::LimitsT(double minPos, double maxPos, double threshold)
00205 {
00206   min_pos = minPos;
00207   max_pos = maxPos;
00208 
00209   //threshold given as a percentage of range. Translate to actual joint distance
00210   e = threshold * (maxPos - minPos); //range;
00211   lower_thresh = minPos + e;
00212   upper_thresh = maxPos - e;
00213 
00214   /* For d = distance from limit: velocity v = k(d-e)^3, where e is distance from threshold to limit.
00215    * k is chosen such that v_max = v[d=0] = e/2 --> k = 1/(2e^2)
00216    */
00217   k3 = 1.0/(2 * e * e);
00218 }
00219 
00220 double AvoidJointLimits::LimitsT::cubicVelRamp(double angle, double limit) const
00221 {
00222     double d = std::abs(angle - limit); // distance from limit
00223     return k3 * std::pow(e-d,3);
00224 }
00225 
00226 } /* namespace constraint */
00227 } /* namespace constrained_ik */


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