Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
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
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 }