Go to the documentation of this file.00001
00027 #ifndef AVOID_OBSTACLES_H_
00028 #define AVOID_OBSTACLES_H_
00029
00030 #include "constrained_ik/constraint.h"
00031 #include "constrained_ik/constrained_ik.h"
00032 #include <industrial_collision_detection/collision_detection/collision_common.h>
00033 #include <vector>
00034 #include <algorithm>
00035 #include <kdl/chain.hpp>
00036 #include <kdl/chainjnttojacsolver.hpp>
00037
00038 namespace constrained_ik
00039 {
00040 namespace constraints
00041 {
00042
00050 class AvoidObstacles: public Constraint
00051 {
00052 protected:
00054 struct LinkAvoidance
00055 {
00056 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00061 LinkAvoidance(std::string link_name);
00062
00063 LinkAvoidance();
00064
00065 virtual ~LinkAvoidance() {delete jac_solver_;}
00066
00067 double weight_;
00068 double min_distance_;
00069 double avoidance_distance_;
00070 double amplitude_;
00071 int num_robot_joints_;
00072 int num_obstacle_joints_;
00073 std::string link_name_;
00074 KDL::Chain avoid_chain_;
00075 int num_inboard_joints_;
00076 KDL::Vector link_point_;
00077 KDL::ChainJntToJacSolver * jac_solver_;
00078 KDL::Vector obstacle_point_;
00079 };
00080
00081 std::map<std::string, LinkAvoidance> links_;
00082 std::vector<std::string> link_names_;
00083 std::set<const robot_model::LinkModel *> link_models_;
00084 double distance_threshold_;
00091 LinkAvoidance* getLinkData(const std::string link_name)
00092 {
00093 std::map<std::string, LinkAvoidance>::iterator it;
00094 it = links_.find(link_name);
00095 if(it != links_.end())
00096 {
00097 return &(it->second);
00098 }
00099 else
00100 {
00101 ROS_WARN_STREAM("Failed to retrieve avoidance data for link: " << link_name);
00102 return NULL;
00103 }
00104 }
00105
00111 const LinkAvoidance * const getLinkData(const std::string link_name) const
00112 {
00113 std::map<std::string, LinkAvoidance>::const_iterator it;
00114 it = links_.find(link_name);
00115 if(it != links_.end())
00116 {
00117 return &(it->second);
00118 }
00119 else
00120 {
00121 ROS_WARN_STREAM("Failed to retrieve avoidance data for link: " << link_name);
00122 return NULL;
00123 }
00124 }
00125
00126 public:
00127 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00129 struct AvoidObstaclesData: public ConstraintData
00130 {
00131 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00132 const constraints::AvoidObstacles* parent_;
00133 collision_detection::DistanceResult distance_res_;
00134 collision_detection::DistanceMap distance_map_;
00135 collision_detection::DistanceInfoMap distance_info_map_;
00138 AvoidObstaclesData(const constrained_ik::SolverState &state, const constraints::AvoidObstacles* parent);
00139 };
00140
00141 AvoidObstacles() {}
00142
00148 void init(const Constrained_IK * ik) override;
00149
00151 constrained_ik::ConstraintResults evalConstraint(const SolverState &state) const override;
00152
00154 void loadParameters(const XmlRpc::XmlRpcValue &constraint_xml) override;
00155
00162 virtual Eigen::MatrixXd calcJacobian(const AvoidObstaclesData &cdata, const LinkAvoidance &link) const;
00163
00171 virtual Eigen::VectorXd calcError(const AvoidObstaclesData &cdata, const LinkAvoidance &link) const;
00172
00180 virtual bool checkStatus(const AvoidObstaclesData &cdata, const LinkAvoidance &link) const;
00181
00187 virtual double getWeight(const std::string &link_name) const
00188 {
00189 LinkAvoidance *link;
00190 if(getLinkData(link_name))
00191 return link->weight_;
00192 else
00193 return -1.0;
00194 }
00195
00201 virtual void setWeight(const std::string &link_name, const double &weight)
00202 {
00203 LinkAvoidance* link = getLinkData(link_name);
00204 if(link)
00205 link->weight_ = weight;
00206 }
00207
00213 virtual double getMinDistance(const std::string &link_name) const
00214 {
00215 const LinkAvoidance * const link = getLinkData(link_name);
00216 if(link)
00217 return link->min_distance_;
00218 else
00219 return -1.0;
00220 }
00221
00227 virtual void setMinDistance(const std::string &link_name, const double &min_distance)
00228 {
00229 LinkAvoidance* link = getLinkData(link_name);
00230 if(link)
00231 link->min_distance_ = min_distance;
00232 }
00233
00239 virtual double getAmplitude(const std::string &link_name) const
00240 {
00241 const LinkAvoidance * const link = getLinkData(link_name);
00242 if(link)
00243 return link->amplitude_;
00244 else
00245 return -1.0;
00246 }
00247
00253 virtual void setAmplitude(const std::string &link_name, const double &litude)
00254 {
00255 LinkAvoidance* link = getLinkData(link_name);
00256 if(link)
00257 link->amplitude_ = amplitude;
00258 }
00259
00265 virtual double getAvoidanceDistance(const std::string &link_name) const
00266 {
00267 const LinkAvoidance * const link = getLinkData(link_name);
00268 if(link)
00269 return link->avoidance_distance_;
00270 else
00271 return -1.0;
00272 }
00273
00279 virtual void setAvoidanceDistance(const std::string &link_name, const double &avoidance_distance)
00280 {
00281 LinkAvoidance* link = getLinkData(link_name);
00282 if(link)
00283 {
00284 link->avoidance_distance_ = avoidance_distance;
00285 updateDistanceThreshold();
00286 }
00287 }
00288
00293 virtual std::vector<std::string> getAvoidanceLinkNames() const
00294 {
00295 return link_names_;
00296 }
00297
00302 virtual void setAvoidanceLinks(const std::vector<std::string> &link_names)
00303 {
00304 link_names_ = link_names;
00305 links_.clear();
00306
00307 for (std::vector<std::string>::const_iterator it = link_names.begin(); it < link_names.end(); ++it)
00308 {
00309 links_.insert(std::make_pair(*it, LinkAvoidance(*it)));
00310 updateDistanceThreshold();
00311 }
00312 }
00313
00318 virtual void addAvoidanceLink(const std::string &link_name)
00319 {
00320 if (std::find(link_names_.begin(), link_names_.end(), link_name) == link_names_.end())
00321 {
00322 links_.insert(std::make_pair(link_name, LinkAvoidance(link_name)));
00323 link_names_.push_back(link_name);
00324 updateDistanceThreshold();
00325 }
00326 else
00327 {
00328 ROS_WARN("Tried to add an avoidance link that already exist.");
00329 }
00330 }
00331
00335 virtual void updateDistanceThreshold()
00336 {
00337 distance_threshold_ = 0;
00338 for (std::map<std::string, LinkAvoidance>::const_iterator it = links_.begin(); it != links_.end(); it++)
00339 {
00340 if (it->second.avoidance_distance_ > distance_threshold_)
00341 {
00342 distance_threshold_ = it->second.avoidance_distance_;
00343 }
00344 }
00345 }
00346
00347 };
00348
00349 }
00350 }
00351 #endif