MoveItPlanner.cpp
Go to the documentation of this file.
00001 #include <moveit_planning_helper/MoveItPlanner.h>
00002 #include <convenience_ros_functions/RobotInfo.h>
00003 #include <geometric_shapes/solid_primitive_dims.h>
00004 
00005 #define ALLOWED_PLANNING_TIME 3
00006 #define ALLOWED_PLANNING_TIME_PATH_CONSTRAINTS 60
00007 #define ALLOWED_PLANNING_ATTEMPTS 10
00008 
00009 using moveit_planning_helper::MoveItPlanner;
00010 using convenience_ros_functions::RobotInfo;
00011 using convenience_ros_functions::ROSFunctions;
00012 
00013 
00014 MoveItPlanner::MoveItPlanner(ros::NodeHandle& n,
00015     const std::string& _moveit_motion_plan_service,
00016     const std::string& _moveit_check_state_validity_service):
00017     node(n),
00018     moveit_motion_plan_service(_moveit_motion_plan_service),
00019     moveit_check_state_validity_service(_moveit_check_state_validity_service)
00020 {
00021     init();
00022 }
00023 
00024 MoveItPlanner::~MoveItPlanner()
00025 {
00026     shutdown();
00027 }
00028 
00029 bool MoveItPlanner::init(){
00030     ROS_INFO("Initialising MoveItPlanner");
00031     ROSFunctions::initSingleton();
00032     state_validity_client=node.serviceClient<moveit_msgs::GetStateValidity>(moveit_check_state_validity_service);
00033     motion_plan_client = node.serviceClient<moveit_msgs::GetMotionPlan>(moveit_motion_plan_service);
00034     return true;
00035 }
00036 
00037 void MoveItPlanner::shutdown(){
00038     motion_plan_client.shutdown();
00039     state_validity_client.shutdown();
00040     ROS_INFO("Shutting down MoveItPlanner.");
00041 }
00042 
00043 
00044 moveit_msgs::MoveItErrorCodes MoveItPlanner::requestTrajectory(
00045         const geometry_msgs::PoseStamped& arm_base_pose, 
00046         float arm_reach_span,
00047     const std::string& planning_group, 
00048         const moveit_msgs::Constraints& goal_constraints,
00049     const moveit_msgs::Constraints * path_constraints,  
00050         const sensor_msgs::JointState& start_state,
00051     moveit_msgs::RobotTrajectory& result_traj) {
00052 
00053         moveit_msgs::WorkspaceParameters wspace;
00054         if (!makeWorkspace(arm_base_pose,arm_reach_span,wspace)) {
00055                 ROS_ERROR("Could not create MoveIt workspace");
00056                 ROS_ERROR_STREAM("Origin pose: "<<arm_base_pose);
00057                 ROS_ERROR_STREAM("Arm reach span: "<<arm_reach_span);
00058                 moveit_msgs::MoveItErrorCodes ret;
00059                 ret.val=moveit_msgs::MoveItErrorCodes::FAILURE;
00060                 return ret;
00061         }
00062         // ROS_INFO_STREAM("Using workspace: "<<wspace);
00063     // ROS_INFO_STREAM("Requesting trajectory from state: "<<start_state);
00064 
00065         std::vector<moveit_msgs::Constraints> constr;
00066         constr.push_back(goal_constraints);
00067         moveit_msgs::MoveItErrorCodes error_code=requestTrajectory(planning_group, constr, start_state, wspace, NULL, path_constraints,result_traj);
00068         
00069         return error_code;
00070 }
00071 
00072 
00073 moveit_msgs::MoveItErrorCodes MoveItPlanner::requestTrajectoryForMobileRobot(
00074         const geometry_msgs::PoseStamped& start_pose, 
00075         const geometry_msgs::PoseStamped& target_pose, 
00076         float arm_reach_span, const std::string& planning_group, 
00077         const moveit_msgs::Constraints& goal_constraints,
00078     const moveit_msgs::Constraints * path_constraints,  
00079         const sensor_msgs::JointState& start_state,
00080     const std::string& virtual_joint_name,
00081     const std::string& target_frame_virtual_joint,
00082     moveit_msgs::RobotTrajectory& result_traj) {
00083 
00084         moveit_msgs::WorkspaceParameters wspace;
00085         if (!makeWorkspace(start_pose,target_pose,arm_reach_span,wspace)) {
00086                 ROS_ERROR("Could not create MoveIt workspace");
00087                 ROS_ERROR_STREAM("Start pose: "<<start_pose);
00088                 ROS_ERROR_STREAM("Target: "<<target_pose);
00089                 moveit_msgs::MoveItErrorCodes ret;
00090                 ret.val=moveit_msgs::MoveItErrorCodes::FAILURE;
00091                 return ret;
00092         }
00093 
00094         sensor_msgs::MultiDOFJointState * virtualJointState=NULL;
00095         if (!virtual_joint_name.empty()) {
00096                 virtualJointState = new sensor_msgs::MultiDOFJointState();
00097                 ROS_INFO_STREAM("Transforming virtual joint pose to '"<<target_frame_virtual_joint<<"'");
00098                 *virtualJointState=RobotInfo::getVirtualJointState(start_pose, virtual_joint_name, target_frame_virtual_joint); 
00099         }
00100 
00101 
00102         //ROS_INFO("Made workspace: "); ROS_INFO_STREAM(wspace);
00103 
00104         std::vector<moveit_msgs::Constraints> constr;
00105         constr.push_back(goal_constraints);
00106         moveit_msgs::MoveItErrorCodes error_code=requestTrajectory(planning_group, constr, start_state, wspace, virtualJointState, path_constraints,result_traj);
00107         
00108         if (virtualJointState) delete virtualJointState;
00109         
00110         return error_code;
00111 }
00112 
00113 
00114 moveit_msgs::MoveItErrorCodes MoveItPlanner::requestTrajectory(const std::string& group_name, 
00115         const std::vector<moveit_msgs::Constraints>& goal_constraints, 
00116         const sensor_msgs::JointState& from_state, 
00117         const moveit_msgs::WorkspaceParameters& wspace,
00118         const sensor_msgs::MultiDOFJointState *mdjs,
00119     const moveit_msgs::Constraints* path_constraints,
00120     moveit_msgs::RobotTrajectory& result){
00121 
00122         moveit_msgs::MotionPlanResponse response;
00123 
00124         //---- construct robot state
00125         moveit_msgs::RobotState robotState;
00126         robotState.is_diff=false;
00127         robotState.joint_state=from_state;
00128 
00129         if (mdjs) robotState.multi_dof_joint_state=*mdjs;
00130 
00131         //the actual motion plan will also do this check and return proper error code
00132         if (!isValidState(robotState,group_name)) {
00133                 ROS_ERROR("MoveItPlanner: Invalid robot state, can't do planning");
00134                 moveit_msgs::MoveItErrorCodes ret;
00135                 ret.val=moveit_msgs::MoveItErrorCodes::INVALID_ROBOT_STATE;
00136                 return ret;
00137         }
00138 
00139         //---- send request     
00140         
00141         moveit_msgs::MotionPlanRequest request;
00142         request.goal_constraints=goal_constraints;
00143         request.group_name=group_name;
00144         request.start_state=robotState;
00145         request.workspace_parameters=wspace;    
00146                 
00147         request.planner_id="RRTConnectkConfigDefault";
00148         
00149         //request.trajectory_constraints=...
00150         request.num_planning_attempts=ALLOWED_PLANNING_ATTEMPTS;
00151         request.allowed_planning_time=ALLOWED_PLANNING_TIME;
00152 
00153         if (path_constraints) {
00154                 //ROS_WARN_STREAM("Path constraints "<<*path_constraints);
00155                 request.path_constraints=*path_constraints;
00156                 request.allowed_planning_time=ALLOWED_PLANNING_TIME_PATH_CONSTRAINTS;
00157         }
00158 
00159         //ROS_INFO_STREAM("Received final moveIt! request: "<<std::endl<<request);
00160 
00161 
00162         response=sendServiceRequest(request);
00163 
00164         if (response.error_code.val == moveit_msgs::MoveItErrorCodes::SUCCESS) {
00165                 result=response.trajectory;
00166         }/*else{
00167                 ROS_ERROR("ReachPlan: Could not get Reaching plan from MoveIt. Error code=%i",response.error_code.val);
00168         }*/
00169 
00170         //ROS_INFO("trajectory size: %lu ", response.trajectory.joint_trajectory.points.size() );
00171         return response.error_code;
00172 }
00173 
00174 
00175 moveit_msgs::MotionPlanResponse MoveItPlanner::sendServiceRequest(moveit_msgs::MotionPlanRequest& request) {
00176         moveit_msgs::GetMotionPlan mp_srv;
00177         mp_srv.request.motion_plan_request = request;
00178         ROS_DEBUG("Sending planning request");
00179         if (!motion_plan_client.exists()) {
00180                 ROS_ERROR("Service %s does not exist, can't get motion plan",motion_plan_client.getService().c_str());
00181                 mp_srv.response.motion_plan_response.error_code.val=moveit_msgs::MoveItErrorCodes::FAILURE;
00182         }else{
00183                 bool success=motion_plan_client.call(mp_srv);
00184                 //if (!success) ROS_ERROR("Motion planning failure: error_code %i ", mp_srv.response.motion_plan_response.error_code.val); 
00185         }
00186         return mp_srv.response.motion_plan_response;
00187 }
00188 
00189 double pickMin(const double pos, const double rel, const double extend){
00190         double m=std::min(pos,rel+pos);
00191         return m-extend;
00192 }
00193 
00194 double pickMax(const double pos, const double rel, const double extend){
00195         double m=std::max(pos,rel+pos);
00196         return m+extend;
00197 }
00198 
00199 
00200 bool MoveItPlanner::makeWorkspace(const geometry_msgs::PoseStamped& from,
00201     const geometry_msgs::PoseStamped& to, 
00202         float arm_reach_span, moveit_msgs::WorkspaceParameters& wspace) const{
00203 
00204         static const float maxWait=2.0;
00205         static const bool latestTime=false;
00206         static const bool printErrors=true;
00207         geometry_msgs::Pose rel;
00208         int err=ROSFunctions::Singleton()->relativePose(from,to,rel,latestTime,maxWait,printErrors);
00209         if (err < 0) {
00210                 ROS_ERROR("Can't make MoveIt! workspace because transform between frames not possible. Error code %i",err);
00211                 //ROS_ERROR_STREAM(from);
00212                 //ROS_ERROR_STREAM(to);
00213                 return false;
00214         }
00215 
00216         wspace.header=from.header;
00217         wspace.min_corner.x= pickMin(from.pose.position.x, rel.position.x,arm_reach_span);
00218         wspace.min_corner.y= pickMin(from.pose.position.y, rel.position.y,arm_reach_span);
00219         wspace.min_corner.z= pickMin(from.pose.position.z, rel.position.z,arm_reach_span);
00220         wspace.max_corner.x= pickMax(from.pose.position.x, rel.position.x,arm_reach_span);
00221         wspace.max_corner.y= pickMax(from.pose.position.y, rel.position.y,arm_reach_span);
00222         wspace.max_corner.z= pickMax(from.pose.position.z, rel.position.z,arm_reach_span);
00223         return true;
00224 }
00225 
00226 bool MoveItPlanner::makeWorkspace(const geometry_msgs::PoseStamped& from,
00227         float arm_reach_span, 
00228     moveit_msgs::WorkspaceParameters& wspace) const {
00229 
00230         wspace.header=from.header;
00231         wspace.min_corner.x= from.pose.position.x-fabs(arm_reach_span);
00232         wspace.min_corner.y= from.pose.position.y-fabs(arm_reach_span);
00233         wspace.min_corner.z= from.pose.position.z-fabs(arm_reach_span);
00234         wspace.max_corner.x= from.pose.position.x+fabs(arm_reach_span);
00235         wspace.max_corner.y= from.pose.position.y+fabs(arm_reach_span);
00236         wspace.max_corner.z= from.pose.position.z+fabs(arm_reach_span);
00237         return true;
00238 }
00239 
00240 
00241 bool MoveItPlanner::isValidState(const moveit_msgs::RobotState& robotState, const std::string& group)
00242 {
00243         //confirm valid robot state:
00244         moveit_msgs::GetStateValidity::Request get_state_validity_request;
00245         moveit_msgs::GetStateValidity::Response get_state_validity_response;
00246         get_state_validity_request.robot_state = robotState;
00247         get_state_validity_request.group_name = group;
00248 
00249         // Service client for checking state validity 
00250         ROS_DEBUG("checking state validity..");
00251         if (!state_validity_client.exists()) {
00252                 ROS_ERROR("MoveIt! state valididty client not connected");
00253                 return false;
00254         }
00255         if (!state_validity_client.call(get_state_validity_request, get_state_validity_response))
00256     {
00257         ROS_ERROR("Failed to call MoveIt! state validity service");
00258         return false;
00259     }
00260         if(get_state_validity_response.valid) {
00261                 //ROS_INFO("State is valid");
00262                 //std::cout<<get_state_validity_response<<std::endl;
00263                 //std::cout<<"-----------"<<std::endl;
00264                 //std::cout<<robotState<<std::endl;
00265                 return true;
00266                 
00267         } else {
00268                 ROS_ERROR("State is invalid");
00269                 std::cout<<get_state_validity_response<<std::endl;
00270                 //std::cout<<"-----------"<<std::endl;
00271                 //std::cout<<robotState<<std::endl;
00272                 return false;
00273         }
00274         return false;
00275 }
00276 
00277 
00278 
00279 
00280 shape_msgs::SolidPrimitive getCone(const double& height, const double& radius){
00281         shape_msgs::SolidPrimitive bv;
00282         bv.type = shape_msgs::SolidPrimitive::CONE;
00283         bv.dimensions.resize(geometric_shapes::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::CONE>::value);
00284         bv.dimensions[shape_msgs::SolidPrimitive::CONE_HEIGHT] = height;
00285         bv.dimensions[shape_msgs::SolidPrimitive::CONE_RADIUS] = radius;
00286         return bv;
00287 
00288 }
00289 
00290 
00291 
00292 
00293 shape_msgs::SolidPrimitive getCylinder(const double& height, const double& radius){
00294         shape_msgs::SolidPrimitive bv;
00295         bv.type = shape_msgs::SolidPrimitive::CYLINDER;
00296         bv.dimensions.resize(geometric_shapes::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::CYLINDER>::value);
00297         bv.dimensions[shape_msgs::SolidPrimitive::CYLINDER_HEIGHT] = height;
00298         bv.dimensions[shape_msgs::SolidPrimitive::CYLINDER_RADIUS] = radius;
00299         return bv;
00300 
00301 }
00302 
00303 
00304 shape_msgs::SolidPrimitive getBox(const double& x,const  double& y,const  double& z){
00305         shape_msgs::SolidPrimitive bv;
00306         bv.type = shape_msgs::SolidPrimitive::BOX;
00307         bv.dimensions.resize(geometric_shapes::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::BOX>::value);
00308         bv.dimensions[shape_msgs::SolidPrimitive::BOX_X] = x;
00309         bv.dimensions[shape_msgs::SolidPrimitive::BOX_Y] = y;
00310         bv.dimensions[shape_msgs::SolidPrimitive::BOX_Z] = z;
00311         return bv;
00312 
00313 }
00314 shape_msgs::SolidPrimitive getSphere(const double& radius){
00315         shape_msgs::SolidPrimitive bv;
00316         bv.type = shape_msgs::SolidPrimitive::SPHERE;
00317         bv.dimensions.resize(geometric_shapes::SolidPrimitiveDimCount<shape_msgs::SolidPrimitive::SPHERE>::value);
00318         bv.dimensions[shape_msgs::SolidPrimitive::SPHERE_RADIUS] = radius;
00319         return bv;
00320 }
00321 
00322 
00323 moveit_msgs::PositionConstraint MoveItPlanner::getBoxConstraint(const std::string &link_name,
00324         const geometry_msgs::PoseStamped& boxOrigin, const double& x, const double& y, const double& z) {
00325         
00326         moveit_msgs::PositionConstraint pc;
00327         pc.link_name = link_name;
00328         pc.target_point_offset.x = 0;
00329         pc.target_point_offset.y = 0;
00330         pc.target_point_offset.z = 0;
00331         
00332         pc.header=boxOrigin.header;
00333         
00334         pc.constraint_region.primitives.resize(1);
00335         shape_msgs::SolidPrimitive &bv = pc.constraint_region.primitives[0];
00336         bv=getBox(x,y,z);
00337 
00338         pc.constraint_region.primitive_poses.resize(1);
00339         geometry_msgs::Pose& pose=pc.constraint_region.primitive_poses[0];
00340         pose=boxOrigin.pose;    
00341 
00342         pc.weight=1.0;
00343 
00344         return pc;
00345 }
00346 
00347 
00348 moveit_msgs::Constraints MoveItPlanner::getJointConstraint(const sensor_msgs::JointState& js, const float& joint_tolerance){
00349         moveit_msgs::Constraints c;
00350         for (int i=0; i<js.name.size(); ++i){
00351                 moveit_msgs::JointConstraint jc;
00352                 jc.joint_name=js.name[i];
00353                 jc.position=js.position[i];
00354                 jc.tolerance_above=joint_tolerance;
00355                 jc.tolerance_below=joint_tolerance;
00356                 jc.weight=1.0;
00357                 c.joint_constraints.push_back(jc);
00358         }
00359         return c;
00360 
00361 }
00362 
00363 
00364 moveit_msgs::OrientationConstraint MoveItPlanner::getOrientationConstraint(const std::string& link_name,
00365     const geometry_msgs::QuaternionStamped& quat, 
00366         const float& x_tolerance,
00367         const float& y_tolerance,
00368         const float& z_tolerance) { 
00369         moveit_msgs::OrientationConstraint ocm;
00370         ocm.link_name = link_name;
00371         ocm.header = quat.header;
00372         ocm.orientation = quat.quaternion;
00373         ocm.absolute_x_axis_tolerance = x_tolerance;
00374         ocm.absolute_y_axis_tolerance = y_tolerance;
00375         ocm.absolute_z_axis_tolerance = z_tolerance;
00376         ocm.weight = 1.0;
00377         return ocm;
00378 }
00379 
00380 moveit_msgs::PositionConstraint MoveItPlanner::getSpherePoseConstraint(
00381                 const std::string &link_name, 
00382                 const geometry_msgs::PoseStamped &target_pose, 
00383                 float maxArmReachDistance) {
00384 
00385         //ROS_INFO_STREAM("Combined path: "<<std::endl<<target_pose<<std::endl<<target_pose2);
00386         //ROS_INFO_STREAM("Combined path: "<<_target_pose<<", dir "<<_target1_to_target2);
00387 
00388         moveit_msgs::PositionConstraint pc;
00389         pc.link_name = link_name;
00390         pc.weight=1.0;
00391         pc.target_point_offset.x = 0;
00392         pc.target_point_offset.y = 0;
00393         pc.target_point_offset.z = 0;
00394         pc.header=target_pose.header;
00395         
00396         pc.constraint_region.primitives.resize(1);
00397         pc.constraint_region.primitive_poses.resize(1);
00398         
00399         shape_msgs::SolidPrimitive &bv = pc.constraint_region.primitives[0];
00400         geometry_msgs::Pose& pose=pc.constraint_region.primitive_poses[0];
00401 
00402         geometry_msgs::Pose sphereOrigin=target_pose.pose;
00403         pose=sphereOrigin;      
00404         bv=getSphere(maxArmReachDistance);
00405         return pc;
00406 }
00407 
00408 
00409 
00410 moveit_msgs::Constraints MoveItPlanner::getPoseConstraint(const std::string &link_name,
00411     const geometry_msgs::PoseStamped &pose, double tolerance_pos, double tolerance_angle, int type) {
00412 
00413         moveit_msgs::Constraints goal;
00414 
00415         if (type<=1) {  
00416                 goal.position_constraints.resize(1);
00417                 moveit_msgs::PositionConstraint &pcm = goal.position_constraints[0];
00418                 pcm.link_name = link_name;
00419                 pcm.target_point_offset.x = 0;
00420                 pcm.target_point_offset.y = 0;
00421                 pcm.target_point_offset.z = 0;
00422                 pcm.constraint_region.primitives.resize(1);
00423                 shape_msgs::SolidPrimitive &bv = pcm.constraint_region.primitives[0];
00424                 bv=getSphere(tolerance_pos);
00425 
00426                 pcm.header = pose.header;
00427                 pcm.constraint_region.primitive_poses.resize(1);
00428                 pcm.constraint_region.primitive_poses[0].position = pose.pose.position;
00429 
00430                 // orientation of constraint region does not affect anything, since it is a sphere
00431                 pcm.constraint_region.primitive_poses[0].orientation.x = 0.0;
00432                 pcm.constraint_region.primitive_poses[0].orientation.y = 0.0;
00433                 pcm.constraint_region.primitive_poses[0].orientation.z = 0.0;
00434                 pcm.constraint_region.primitive_poses[0].orientation.w = 1.0;
00435                 pcm.weight = 1.0;
00436         }
00437         
00438         if ((type==1) || (type==2)){
00439                 goal.orientation_constraints.resize(1);
00440                 moveit_msgs::OrientationConstraint &ocm = goal.orientation_constraints[0];
00441                 ocm.link_name = link_name;
00442                 ocm.header = pose.header;
00443                 ocm.orientation = pose.pose.orientation;
00444                 ocm.absolute_x_axis_tolerance = tolerance_angle;
00445                 ocm.absolute_y_axis_tolerance = tolerance_angle;
00446                 ocm.absolute_z_axis_tolerance = tolerance_angle;
00447                 ocm.weight = 1.0;
00448         }/*else{
00449                 ROS_WARN("An unsupported constraint type was passed into MoveItPlanner::getPoseConstraint: %i",type);
00450         }*/
00451         return goal;
00452 }
00453 


moveit_planning_helper
Author(s): Jennifer Buehler
autogenerated on Sat Mar 2 2019 03:50:54