obstacle_distance_gradient.cpp
Go to the documentation of this file.
00001 
00027 #include <stomp_moveit/cost_functions/obstacle_distance_gradient.h>
00028 #include <ros/console.h>
00029 #include <pluginlib/class_list_macros.h>
00030 #include <moveit/robot_state/conversions.h>
00031 
00032 PLUGINLIB_EXPORT_CLASS(stomp_moveit::cost_functions::ObstacleDistanceGradient,stomp_moveit::cost_functions::StompCostFunction)
00033 static const double LONGEST_VALID_JOINT_MOVE = 0.01;
00034 
00035 namespace stomp_moveit
00036 {
00037 namespace cost_functions
00038 {
00039 
00040 ObstacleDistanceGradient::ObstacleDistanceGradient() :
00041     name_("ObstacleDistanceGradient"),
00042     robot_state_()
00043 {
00044 
00045 }
00046 
00047 ObstacleDistanceGradient::~ObstacleDistanceGradient()
00048 {
00049 
00050 }
00051 
00052 bool ObstacleDistanceGradient::initialize(moveit::core::RobotModelConstPtr robot_model_ptr,
00053                                           const std::string& group_name, XmlRpc::XmlRpcValue& config)
00054 {
00055   robot_model_ptr_ = robot_model_ptr;
00056   group_name_ = group_name;
00057   collision_request_.distance = true;
00058   collision_request_.group_name = group_name;
00059   collision_request_.cost = false;
00060   collision_request_.max_contacts = 1;
00061   collision_request_.max_contacts_per_pair = 1;
00062   collision_request_.contacts = false;
00063   collision_request_.verbose = false;
00064   return configure(config);
00065 }
00066 
00067 bool ObstacleDistanceGradient::configure(const XmlRpc::XmlRpcValue& config)
00068 {
00069 
00070   try
00071   {
00072     // check parameter presence
00073     auto members = {"cost_weight" ,"max_distance"};
00074     for(auto& m : members)
00075     {
00076       if(!config.hasMember(m))
00077       {
00078         ROS_ERROR("%s failed to find the '%s' parameter",getName().c_str(),m);
00079         return false;
00080       }
00081     }
00082 
00083     XmlRpc::XmlRpcValue c = config;
00084     max_distance_ = static_cast<double>(c["max_distance"]);
00085     cost_weight_ = static_cast<double>(c["cost_weight"]);
00086     longest_valid_joint_move_ = c.hasMember("longest_valid_joint_move") ? static_cast<double>(c["longest_valid_joint_move"]):LONGEST_VALID_JOINT_MOVE;
00087 
00088     if(!c.hasMember("longest_valid_joint_move"))
00089     {
00090       ROS_WARN("%s using default value for 'longest_valid_joint_move' of %f",getName().c_str(),longest_valid_joint_move_);
00091     }
00092   }
00093   catch(XmlRpc::XmlRpcException& e)
00094   {
00095     ROS_ERROR("%s failed to parse configuration parameters",name_.c_str());
00096     return false;
00097   }
00098 
00099   return true;
00100 }
00101 
00102 bool ObstacleDistanceGradient::setMotionPlanRequest(const planning_scene::PlanningSceneConstPtr& planning_scene,
00103                                                     const moveit_msgs::MotionPlanRequest &req,
00104                                                     const stomp_core::StompConfiguration &config,
00105                                                     moveit_msgs::MoveItErrorCodes& error_code)
00106 {
00107   using namespace moveit::core;
00108 
00109   planning_scene_ = planning_scene;
00110   plan_request_ = req;
00111   error_code.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
00112 
00113   // storing robot state
00114   robot_state_.reset(new RobotState(robot_model_ptr_));
00115 
00116   if(!robotStateMsgToRobotState(req.start_state,*robot_state_,true))
00117   {
00118     ROS_ERROR("%s Failed to get current robot state from request",getName().c_str());
00119     return false;
00120   }
00121 
00122   // copying into intermediate robot states
00123   for(auto& rs : intermediate_coll_states_)
00124   {
00125     rs.reset(new RobotState(*robot_state_));
00126   }
00127 
00128   return true;
00129 }
00130 
00131 bool ObstacleDistanceGradient::computeCosts(const Eigen::MatrixXd& parameters, std::size_t start_timestep,
00132                                             std::size_t num_timesteps, int iteration_number, int rollout_number,
00133                                             Eigen::VectorXd& costs, bool& validity)
00134 {
00135 
00136   if(!robot_state_)
00137   {
00138     ROS_ERROR("%s Robot State has not been updated",getName().c_str());
00139     return false;
00140   }
00141 
00142 
00143 
00144   // allocating
00145   costs = Eigen::VectorXd::Zero(num_timesteps);
00146   const moveit::core::JointModelGroup* joint_group = robot_model_ptr_->getJointModelGroup(group_name_);
00147 
00148   if(parameters.cols()<start_timestep + num_timesteps)
00149   {
00150     ROS_ERROR_STREAM("Size in the 'parameters' matrix is less than required");
00151     return false;
00152   }
00153 
00154   // request the distance at each state
00155   double dist;
00156   bool skip_next_check = false;
00157   validity = true;
00158   for (auto t=start_timestep; t<start_timestep + num_timesteps; ++t)
00159   {
00160 
00161     if(!skip_next_check)
00162     {
00163       collision_result_.clear();
00164       robot_state_->setJointGroupPositions(joint_group,parameters.col(t));
00165       robot_state_->update();
00166       collision_result_.distance = max_distance_;
00167 
00168       planning_scene_->checkSelfCollision(collision_request_,collision_result_,*robot_state_,planning_scene_->getAllowedCollisionMatrix());
00169       dist = collision_result_.collision ? -1.0 :collision_result_.distance ;
00170 
00171       if(dist >= max_distance_)
00172       {
00173         costs(t) = 0; // away from obstacle
00174       }
00175       else if(dist < 0)
00176       {
00177         costs(t) = 1.0; // in collision
00178         validity = false;
00179       }
00180       else
00181       {
00182         costs(t) = (max_distance_ - dist)/max_distance_;
00183       }
00184     }
00185 
00186     skip_next_check = false;
00187 
00188     // check intermediate poses to the next position (skip the last one)
00189     if(t  < start_timestep + num_timesteps - 1)
00190     {
00191       if(!checkIntermediateCollisions(parameters.col(t),parameters.col(t+1),longest_valid_joint_move_))
00192       {
00193         costs(t) = 1.0;
00194         costs(t+1) = 1.0;
00195         validity = false;
00196         skip_next_check = true;
00197       }
00198       else
00199       {
00200         skip_next_check = false;
00201       }
00202     }
00203 
00204   }
00205 
00206   return true;
00207 }
00208 
00209 bool ObstacleDistanceGradient::checkIntermediateCollisions(const Eigen::VectorXd& start,
00210                                                            const Eigen::VectorXd& end,double longest_valid_joint_move)
00211 {
00212   Eigen::VectorXd diff = end - start;
00213   int num_intermediate = std::ceil(((diff.cwiseAbs())/longest_valid_joint_move).maxCoeff()) - 1;
00214   if(num_intermediate < 1.0)
00215   {
00216     // no interpolation needed
00217     return true;
00218   }
00219 
00220   // grabbing states
00221   auto& start_state = intermediate_coll_states_[0];
00222   auto& mid_state = intermediate_coll_states_[1];
00223   auto& end_state = intermediate_coll_states_[2];
00224 
00225   if(!start_state || !mid_state || !end_state)
00226   {
00227     ROS_ERROR("%s intermediate states not initialized",getName().c_str());
00228     return false;
00229   }
00230 
00231   // setting up collision
00232   auto req = collision_request_;
00233   req.distance = false;
00234   collision_detection::CollisionResult res;
00235   const moveit::core::JointModelGroup* joint_group = robot_model_ptr_->getJointModelGroup(group_name_);
00236   start_state->setJointGroupPositions(joint_group,start);
00237   end_state->setJointGroupPositions(joint_group,end);
00238 
00239   // checking intermediate states
00240   double dt = 1.0/static_cast<double>(num_intermediate);
00241   double interval = 0.0;
00242   for(std::size_t i = 1; i < num_intermediate;i++)
00243   {
00244     interval = i*dt;
00245     start_state->interpolate(*end_state,interval,*mid_state) ;
00246     if(planning_scene_->isStateColliding(*mid_state))
00247     {
00248       return false;
00249     }
00250   }
00251 
00252   return true;
00253 }
00254 
00255 void ObstacleDistanceGradient::done(bool success,int total_iterations,double final_cost,const Eigen::MatrixXd& parameters)
00256 {
00257   robot_state_.reset();
00258 }
00259 
00260 } /* namespace cost_functions */
00261 } /* namespace stomp_moveit */


stomp_moveit
Author(s): Jorge Nicho
autogenerated on Sat Jun 8 2019 19:24:01