ompl_ros_joint_planner.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2008, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of Willow Garage, Inc. nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00037 #include <ompl_ros_interface/planners/ompl_ros_joint_planner.h>
00038 
00039 namespace ompl_ros_interface
00040 {
00041 
00042 bool OmplRosJointPlanner::initializePlanningStateSpace(ompl::base::StateSpacePtr &state_space)
00043 {
00044   //Setup the corresponding ompl state space
00045   state_space = ompl_ros_interface::jointGroupToOmplStateSpacePtr(physical_joint_group_,
00046                                                                         ompl_state_to_kinematic_state_mapping_,
00047                                                                         kinematic_state_to_ompl_state_mapping_);
00048   if(!state_space)
00049   {
00050     ROS_ERROR("Could not set up the ompl state space from group %s",group_name_.c_str());
00051     return false;
00052   }
00053   std::string physical_group_name = physical_joint_group_->getName();
00054   if(node_handle_.hasParam(physical_group_name+"/tip_name"))
00055   {
00056     node_handle_.getParam(physical_group_name+"/tip_name",end_effector_name_);
00057     ROS_DEBUG("Group: %s, End effector: %s",physical_group_name.c_str(),end_effector_name_.c_str());
00058     if(node_handle_.hasParam(physical_group_name+"/kinematics_solver"))
00059     {
00060       node_handle_.getParam(physical_group_name+"/kinematics_solver",kinematics_solver_name_);
00061       ROS_DEBUG("Kinematics solver: %s",kinematics_solver_name_.c_str());
00062       ROS_DEBUG("Created new ik sampler: %s",kinematics_solver_name_.c_str());
00063       if(!ik_sampler_.initialize(state_space_,kinematics_solver_name_,physical_group_name,end_effector_name_,collision_models_interface_))
00064       {
00065         ROS_ERROR("Could not set IK sampler for pose goal");
00066       }
00067       else
00068         ik_sampler_available_ = true;
00069     }
00070   }
00071 
00072   return true;
00073 }
00074 
00075 bool OmplRosJointPlanner::isRequestValid(arm_navigation_msgs::GetMotionPlan::Request &request,
00076                                          arm_navigation_msgs::GetMotionPlan::Response &response)
00077 {
00078   if(request.motion_plan_request.group_name != group_name_)
00079   {
00080     ROS_ERROR("Invalid group name: %s",request.motion_plan_request.group_name.c_str());
00081     response.error_code.val = response.error_code.INVALID_GROUP_NAME;
00082     return false;
00083   }
00084   for (unsigned int i = 0 ; i < request.motion_plan_request.goal_constraints.position_constraints.size() ; ++i)
00085   {
00086     if (!(request.motion_plan_request.goal_constraints.position_constraints[i].link_name == end_effector_name_))
00087     {
00088       response.error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::INVALID_LINK_NAME;
00089       ROS_ERROR("Cartesian goals for link %s are the only ones that can be processed", end_effector_name_.c_str());
00090       return false;      
00091     }
00092   }
00093   for (unsigned int i = 0 ; i < request.motion_plan_request.goal_constraints.orientation_constraints.size() ; ++i)
00094   {
00095     if (!(request.motion_plan_request.goal_constraints.orientation_constraints[i].link_name == end_effector_name_))
00096     {
00097       response.error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::INVALID_LINK_NAME;
00098       ROS_ERROR("Cartesian goals for link %s are the only ones that can be processed", end_effector_name_.c_str());
00099       return false;      
00100     }
00101   }
00102   if(!request.motion_plan_request.goal_constraints.position_constraints.empty()
00103      && !request.motion_plan_request.goal_constraints.orientation_constraints.empty())
00104   {
00105     if(request.motion_plan_request.goal_constraints.position_constraints.size() != request.motion_plan_request.goal_constraints.orientation_constraints.size())
00106     {
00107       ROS_ERROR("Can only deal with requests that have the same number of position and orientation constraints");
00108       response.error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::INVALID_GOAL_POSITION_CONSTRAINTS;
00109       return false;
00110     }
00111   }
00112   if(request.motion_plan_request.allowed_planning_time.toSec() <= 0.0)
00113   {
00114     response.error_code.val = arm_navigation_msgs::ArmNavigationErrorCodes::INVALID_TIMEOUT;
00115     ROS_ERROR("Request does not specify correct allowed planning time %f",request.motion_plan_request.allowed_planning_time.toSec());
00116     return false;
00117   }
00118   return true;
00119 }
00120 
00121 bool OmplRosJointPlanner::setGoal(arm_navigation_msgs::GetMotionPlan::Request &request,
00122                                   arm_navigation_msgs::GetMotionPlan::Response &response)
00123 {
00124 
00125   if(!request.motion_plan_request.goal_constraints.joint_constraints.empty() 
00126      && request.motion_plan_request.goal_constraints.position_constraints.empty() 
00127      && request.motion_plan_request.goal_constraints.orientation_constraints.empty())
00128   {
00129     ROS_DEBUG("Joint space goal");
00130     return setJointGoal(request,response);
00131   }
00132   else if(!request.motion_plan_request.goal_constraints.position_constraints.empty()
00133           && !request.motion_plan_request.goal_constraints.orientation_constraints.empty())
00134   {
00135     ROS_DEBUG("Pose goal");
00136     return setPoseGoal(request,response);
00137   }
00138   else 
00139   {
00140     ROS_ERROR("Cannot handle request since its not a joint goal or fully specified pose goal (with position and orientation constraints");
00141     return false;
00142   }
00143 }
00144 
00145 bool OmplRosJointPlanner::setStart(arm_navigation_msgs::GetMotionPlan::Request &request,
00146                                     arm_navigation_msgs::GetMotionPlan::Response &response)
00147 {
00148   ompl::base::ScopedState<ompl::base::CompoundStateSpace> start(state_space_);
00149   ROS_DEBUG("Start");
00150   if(!ompl_ros_interface::kinematicStateGroupToOmplState(physical_joint_state_group_,
00151                                                          kinematic_state_to_ompl_state_mapping_,
00152                                                          start))
00153   {
00154     ROS_ERROR("Could not set start state");
00155     return false;
00156   }
00157 
00158   ompl_ros_interface::OmplRosJointStateValidityChecker *my_checker = dynamic_cast<ompl_ros_interface::OmplRosJointStateValidityChecker*>(state_validity_checker_.get());  
00159   if(!my_checker->isStateValid(start.get()))
00160   {
00161     response.error_code = my_checker->getLastErrorCode();
00162     if(response.error_code.val == response.error_code.PATH_CONSTRAINTS_VIOLATED)
00163       response.error_code.val = response.error_code.START_STATE_VIOLATES_PATH_CONSTRAINTS;
00164     else if(response.error_code.val == response.error_code.COLLISION_CONSTRAINTS_VIOLATED)
00165       response.error_code.val = response.error_code.START_STATE_IN_COLLISION;
00166     ROS_ERROR("Start state is invalid. Reason: %s",arm_navigation_msgs::armNavigationErrorCodeToString(response.error_code).c_str());
00167     return false;
00168   }
00169   planner_->getProblemDefinition()->clearStartStates(); 
00170   planner_->addStartState(start);
00171   return true;
00172 }
00173 
00174 bool OmplRosJointPlanner::setJointGoal(arm_navigation_msgs::GetMotionPlan::Request &request,
00175                                         arm_navigation_msgs::GetMotionPlan::Response &response)
00176 {
00177   ompl::base::ScopedState<ompl::base::CompoundStateSpace> goal(state_space_);
00178   ompl::base::GoalPtr goal_states(new ompl::base::GoalStates(planner_->getSpaceInformation()));
00179   unsigned int dimension = physical_joint_state_group_->getDimension();
00180   unsigned int num_goals = request.motion_plan_request.goal_constraints.joint_constraints.size()/dimension;
00181   if(!(num_goals*dimension == request.motion_plan_request.goal_constraints.joint_constraints.size()))
00182   {
00183     if(request.motion_plan_request.goal_constraints.joint_constraints.size() < dimension)
00184     {
00185       response.error_code.val = response.error_code.PLANNING_FAILED;
00186       ROS_ERROR_STREAM("Joint space goal specification did not specify goal for all joints in group expected " << dimension <<" but got " << request.motion_plan_request.goal_constraints.joint_constraints.size() );   
00187       return false;
00188     }
00189     else
00190       num_goals = 1;
00191   }
00192   for(unsigned int i=0; i < num_goals; i++)
00193   {
00194     std::vector<arm_navigation_msgs::JointConstraint> joint_constraints;
00195     for(unsigned int j=0; j < dimension; j++)
00196       joint_constraints.push_back(request.motion_plan_request.goal_constraints.joint_constraints[i*dimension+j]);
00197     if(!ompl_ros_interface::jointConstraintsToOmplState(joint_constraints,goal))
00198     {
00199       response.error_code.val = response.error_code.PLANNING_FAILED;
00200       ROS_ERROR("Could not convert joint space constraints to ompl state");     
00201       return false;
00202     }
00203     goal_states->as<ompl::base::GoalStates>()->addState(goal.get());
00204   }
00205   ompl_ros_interface::OmplRosJointStateValidityChecker *my_checker = dynamic_cast<ompl_ros_interface::OmplRosJointStateValidityChecker*>(state_validity_checker_.get());  
00206   if(num_goals == 1 && !my_checker->isStateValid(goal.get()))
00207   {
00208     response.error_code = my_checker->getLastErrorCode();
00209     if(response.error_code.val == response.error_code.PATH_CONSTRAINTS_VIOLATED)
00210       response.error_code.val = response.error_code.GOAL_VIOLATES_PATH_CONSTRAINTS;
00211     else if(response.error_code.val == response.error_code.COLLISION_CONSTRAINTS_VIOLATED)
00212       response.error_code.val = response.error_code.GOAL_IN_COLLISION;
00213     ROS_ERROR("Joint space goal is invalid. Reason: %s",arm_navigation_msgs::armNavigationErrorCodeToString(response.error_code).c_str());
00214     return false;
00215   }  
00216   ROS_INFO_STREAM("Setting " << num_goals << " goals");
00217   planner_->setGoal(goal_states);    
00218   return true;
00219 }
00220 
00221 bool OmplRosJointPlanner::setPoseGoal(arm_navigation_msgs::GetMotionPlan::Request &request,
00222                                        arm_navigation_msgs::GetMotionPlan::Response &response)
00223 {
00224   if(!ik_sampler_available_)
00225   {
00226     ROS_ERROR("Cannot solve for pose goals since an ik sampler has not been defined");
00227     response.error_code.val = response.error_code.PLANNING_FAILED;
00228     return false;
00229   }
00230   ik_sampler_.configureOnRequest(request,response,100);
00231   ompl::base::GoalPtr goal;
00232   goal.reset(new ompl::base::GoalLazySamples(planner_->getSpaceInformation(),boost::bind(&OmplRosIKSampler::sampleGoals,&ik_sampler_,_1,_2)));
00233   planner_->setGoal(goal);
00234   return true;
00235 }
00236 
00237 bool OmplRosJointPlanner::initializeStateValidityChecker(ompl_ros_interface::OmplRosStateValidityCheckerPtr &state_validity_checker)
00238 {
00239   state_validity_checker.reset(new ompl_ros_interface::OmplRosJointStateValidityChecker(planner_->getSpaceInformation().get(),
00240                                                                                         collision_models_interface_,
00241                                                                                         ompl_state_to_kinematic_state_mapping_));
00242     return true;
00243 }
00244 
00245 arm_navigation_msgs::RobotTrajectory OmplRosJointPlanner::getSolutionPath()
00246 {
00247   arm_navigation_msgs::RobotTrajectory robot_trajectory;
00248   ompl::geometric::PathGeometric solution = planner_->getSolutionPath();
00249   solution.interpolate();
00250   omplPathGeometricToRobotTrajectory(solution,robot_trajectory);
00251   return robot_trajectory;
00252 }
00253 
00254 
00255 }


ompl_ros_interface
Author(s): Sachin Chitta
autogenerated on Mon Dec 2 2013 12:38:54