int main(int argc, char **argv) { ros::init (argc, argv, "move_group_tutorial"); ros::AsyncSpinner spinner(1); spinner.start(); ros::NodeHandle node_handle("move_group"); // BEGIN_TUTORIAL // Start // ^^^^^ // Setting up to start using a planner is pretty easy. Planners are // setup as plugins in MoveIt! and you can use the ROS pluginlib // interface to load any planner that you want to use. Before we // can load the planner, we need two objects, a RobotModel // and a PlanningScene. // We will start by instantiating a // `RobotModelLoader`_ // object, which will look up // the robot description on the ROS parameter server and construct a // :moveit_core:`RobotModel` for us to use. // // .. _RobotModelLoader: http://docs.ros.org/api/moveit_ros_planning/html/classrobot__model__loader_1_1RobotModelLoader.html robot_model_loader::RobotModelLoader robot_model_loader("robot_description"); robot_model::RobotModelPtr robot_model = robot_model_loader.getModel(); // Using the :moveit_core:`RobotModel`, we can construct a // :planning_scene:`PlanningScene` that maintains the state of // the world (including the robot). planning_scene::PlanningScenePtr planning_scene(new planning_scene::PlanningScene(robot_model)); // We will now construct a loader to load a planner, by name. // Note that we are using the ROS pluginlib library here. boost::scoped_ptr<pluginlib::ClassLoader<planning_interface::PlannerManager> > planner_plugin_loader; planning_interface::PlannerManagerPtr planner_instance; std::string planner_plugin_name; // We will get the name of planning plugin we want to load // from the ROS param server, and then load the planner // making sure to catch all exceptions. if (!node_handle.getParam("planning_plugin", planner_plugin_name)) ROS_FATAL_STREAM("Could not find planner plugin name"); try { planner_plugin_loader.reset(new pluginlib::ClassLoader<planning_interface::PlannerManager>("moveit_core", "planning_interface::PlannerManager")); } catch(pluginlib::PluginlibException& ex) { ROS_FATAL_STREAM("Exception while creating planning plugin loader " << ex.what()); } try { planner_instance.reset(planner_plugin_loader->createUnmanagedInstance(planner_plugin_name)); if (!planner_instance->initialize(robot_model, node_handle.getNamespace())) ROS_FATAL_STREAM("Could not initialize planner instance"); ROS_INFO_STREAM("Using planning interface '" << planner_instance->getDescription() << "'"); } catch(pluginlib::PluginlibException& ex) { const std::vector<std::string> &classes = planner_plugin_loader->getDeclaredClasses(); std::stringstream ss; for (std::size_t i = 0 ; i < classes.size() ; ++i) ss << classes[i] << " "; ROS_ERROR_STREAM("Exception while loading planner '" << planner_plugin_name << "': " << ex.what() << std::endl << "Available plugins: " << ss.str()); } /* Sleep a little to allow time to startup rviz, etc. */ // ros::WallDuration sleep_time(15.0); ros::WallDuration sleep_time(1); sleep_time.sleep(); // Pose Goal // ^^^^^^^^^ // We will now create a motion plan request for the right arm of the PR2 // specifying the desired pose of the end-effector as input. planning_interface::MotionPlanRequest req; planning_interface::MotionPlanResponse res; geometry_msgs::PoseStamped pose; pose.header.frame_id = "base"; pose.pose.position.x = 0.3; pose.pose.position.y = 0.0; pose.pose.position.z = 0.3; pose.pose.orientation.w = 1.0; // A tolerance of 0.01 m is specified in position // and 0.01 radians in orientation std::vector<double> tolerance_pose(3, 0.01); std::vector<double> tolerance_angle(3, 0.01); // We will create the request as a constraint using a helper function available // from the // `kinematic_constraints`_ // package. // // .. _kinematic_constraints: http://docs.ros.org/api/moveit_core/html/namespacekinematic__constraints.html#a88becba14be9ced36fefc7980271e132 req.group_name = "manipulator"; moveit_msgs::Constraints pose_goal = kinematic_constraints::constructGoalConstraints("tool0", pose, tolerance_pose, tolerance_angle); req.goal_constraints.push_back(pose_goal); // We now construct a planning context that encapsulate the scene, // the request and the response. We call the planner using this // planning context planning_interface::PlanningContextPtr context = planner_instance->getPlanningContext(planning_scene, req, res.error_code_); context->solve(res); if(res.error_code_.val != res.error_code_.SUCCESS) { ROS_ERROR("Could not compute plan successfully: %d", (int) res.error_code_.val); return 0; } // Visualize the result // ^^^^^^^^^^^^^^^^^^^^ ros::Publisher display_publisher = node_handle.advertise<moveit_msgs::DisplayTrajectory>("/move_group/display_planned_path", 1, true); moveit_msgs::DisplayTrajectory display_trajectory; /* Visualize the trajectory */ ROS_INFO("Visualizing the trajectory"); moveit_msgs::MotionPlanResponse response; res.getMessage(response); display_trajectory.trajectory_start = response.trajectory_start; display_trajectory.trajectory.push_back(response.trajectory); display_publisher.publish(display_trajectory); sleep_time.sleep(); // Joint Space Goals // ^^^^^^^^^^^^^^^^^ /* First, set the state in the planning scene to the final state of the last plan */ robot_state::RobotState& robot_state = planning_scene->getCurrentStateNonConst(); planning_scene->setCurrentState(response.trajectory_start); #if 0 const robot_state::JointModelGroup* joint_model_group = robot_state.getJointModelGroup("manipulator"); robot_state.setJointGroupPositions(joint_model_group, response.trajectory.joint_trajectory.points.back().positions); // Now, setup a joint space goal robot_state::RobotState goal_state(robot_model); std::vector<double> joint_values(7, 0.0); joint_values[0] = -2.0; joint_values[3] = -0.2; joint_values[5] = -0.15; goal_state.setJointGroupPositions(joint_model_group, joint_values); moveit_msgs::Constraints joint_goal = kinematic_constraints::constructGoalConstraints(goal_state, joint_model_group); req.goal_constraints.clear(); req.goal_constraints.push_back(joint_goal); // Call the planner and visualize the trajectory /* Re-construct the planning context */ context = planner_instance->getPlanningContext(planning_scene, req, res.error_code_); /* Call the Planner */ context->solve(res); /* Check that the planning was successful */ if(res.error_code_.val != res.error_code_.SUCCESS) { ROS_ERROR("Could not compute plan successfully"); return 0; } /* Visualize the trajectory */ ROS_INFO("Visualizing the trajectory"); res.getMessage(response); display_trajectory.trajectory_start = response.trajectory_start; display_trajectory.trajectory.push_back(response.trajectory); /* Now you should see two planned trajectories in series*/ display_publisher.publish(display_trajectory); /* We will add more goals. But first, set the state in the planning scene to the final state of the last plan */ robot_state.setJointGroupPositions(joint_model_group, response.trajectory.joint_trajectory.points.back().positions); /* Now, we go back to the first goal*/ req.goal_constraints.clear(); req.goal_constraints.push_back(pose_goal); context = planner_instance->getPlanningContext(planning_scene, req, res.error_code_); context->solve(res); res.getMessage(response); display_trajectory.trajectory.push_back(response.trajectory); display_publisher.publish(display_trajectory); // Adding Path Constraints // ^^^^^^^^^^^^^^^^^^^^^^^ // Let's add a new pose goal again. This time we will also add a path constraint to the motion. /* Let's create a new pose goal */ pose.pose.position.x = 0.65; pose.pose.position.y = -0.2; pose.pose.position.z = -0.1; moveit_msgs::Constraints pose_goal_2 = kinematic_constraints::constructGoalConstraints("tool0", pose, tolerance_pose, tolerance_angle); /* First, set the state in the planning scene to the final state of the last plan */ robot_state.setJointGroupPositions(joint_model_group, response.trajectory.joint_trajectory.points.back().positions); /* Now, let's try to move to this new pose goal*/ req.goal_constraints.clear(); req.goal_constraints.push_back(pose_goal_2); /* But, let's impose a path constraint on the motion. Here, we are asking for the end-effector to stay level*/ geometry_msgs::QuaternionStamped quaternion; quaternion.header.frame_id = "torso_lift_link"; quaternion.quaternion.w = 1.0; req.path_constraints = kinematic_constraints::constructGoalConstraints("tool0", quaternion); // Imposing path constraints requires the planner to reason in the space of possible positions of the end-effector // (the workspace of the robot) // because of this, we need to specify a bound for the allowed planning volume as well; // Note: a default bound is automatically filled by the WorkspaceBounds request adapter (part of the OMPL pipeline, // but that is not being used in this example). // We use a bound that definitely includes the reachable space for the arm. This is fine because sampling is not done in this volume // when planning for the arm; the bounds are only used to determine if the sampled configurations are valid. req.workspace_parameters.min_corner.x = req.workspace_parameters.min_corner.y = req.workspace_parameters.min_corner.z = -2.0; req.workspace_parameters.max_corner.x = req.workspace_parameters.max_corner.y = req.workspace_parameters.max_corner.z = 2.0; // Call the planner and visualize all the plans created so far. context = planner_instance->getPlanningContext(planning_scene, req, res.error_code_); context->solve(res); res.getMessage(response); display_trajectory.trajectory.push_back(response.trajectory); // Now you should see four planned trajectories in series display_publisher.publish(display_trajectory); #endif //END_TUTORIAL sleep_time.sleep(); ROS_INFO("Done"); planner_instance.reset(); return 0; }
int main(int argc, char **argv) { /*Initialise Variables*/ CAPTURE_MOVEMENT=false;//know when you have reach the maximum of points to handle //Creating the joint_msg_leap joint_msg_leap.name.resize(8); joint_msg_leap.position.resize(8); joint_msg_leap.name[0]="arm_1_joint"; joint_msg_leap.name[1]="arm_2_joint"; joint_msg_leap.name[2]="arm_3_joint"; joint_msg_leap.name[3]="arm_4_joint"; joint_msg_leap.name[4]="arm_5_joint"; joint_msg_leap.name[5]="arm_6_joint"; joint_msg_leap.name[6]="base_joint_gripper_left"; joint_msg_leap.name[7]="base_joint_gripper_right"; aux_enter=1; FIRST_VALUE=true;//Help knowing Initial Position of the hand int arm_trajectory_point=1; collision_detection::CollisionRequest collision_request; collision_detection::CollisionResult collision_result; /*Finish Variables Initialitation*/ //ROS DECLARATION ros::init(argc, argv,"listener"); if (argc != 2) { ROS_WARN("WARNING: you should specify number of points to capture"); } else { count=atoi(argv[1]); ROS_INFO ("Number of points /n%d", count); } //Create an object of the LeapMotionListener Class LeapMotionListener leapmotionlistener; leapmotionlistener.Configure(count); //ros::NodeHandle node_handle; ros::NodeHandle node_handle("~"); // start a ROS spinning thread ros::AsyncSpinner spinner(1); spinner.start(); //we need this for leap ros::Rate r(1); //robo_pub = n.advertise<sensor_msgs::JointState>("joint_leap", 100); //Creating a Robot Model robot_model_loader::RobotModelLoader robot_model_loader("robot_description"); robot_model::RobotModelPtr robot_model = robot_model_loader.getModel(); //Initialise PlanningSceneMonitorPtr /* MOVEIT Setup*/ // ^^^^^ moveit::planning_interface::MoveGroup group("arm"); group.setPlanningTime(0.5); moveit::planning_interface::MoveGroup::Plan my_plan; // We will use the :planning_scene_interface:`PlanningSceneInterface` // class to deal directly with the world. moveit::planning_interface::PlanningSceneInterface planning_scene_interface; /* Adding/Removing Objects and Attaching/Detaching Objects*/ ROS_INFO("CREATING PLANNING_SCENE PUBLISHER"); ros::Publisher planning_scene_diff_publisher = node_handle.advertise<moveit_msgs::PlanningScene>("/planning_scene", 1); while(planning_scene_diff_publisher.getNumSubscribers() < 1) { ros::WallDuration sleep_t(0.5); sleep_t.sleep(); } ROS_INFO("CREATING COLLISION OBJECT"); moveit_msgs::AttachedCollisionObject attached_object; attached_object.link_name = ""; /* The header must contain a valid TF frame*/ attached_object.object.header.frame_id = "gripper_left"; /* The id of the object */ attached_object.object.id = "box"; /* A default pose */ geometry_msgs::Pose posebox; posebox.orientation.w = 1.0; /* Define a box to be attached */ shape_msgs::SolidPrimitive primitive; primitive.type = primitive.BOX; primitive.dimensions.resize(3); primitive.dimensions[0] = 0.1; primitive.dimensions[1] = 0.1; primitive.dimensions[2] = 0.1; attached_object.object.primitives.push_back(primitive); attached_object.object.primitive_poses.push_back(posebox); attached_object.object.operation = attached_object.object.ADD; ROS_INFO("ADDING COLLISION OBJECT TO THE WORLD"); moveit_msgs::PlanningScene planning_scene_msg; planning_scene_msg.world.collision_objects.push_back(attached_object.object); planning_scene_msg.is_diff = true; planning_scene_diff_publisher.publish(planning_scene_msg); //sleep_time.sleep(); /* First, define the REMOVE object message*/ moveit_msgs::CollisionObject remove_object; remove_object.id = "box"; remove_object.header.frame_id = "odom_combined"; remove_object.operation = remove_object.REMOVE; /* Carry out the REMOVE + ATTACH operation */ ROS_INFO("Attaching the object to the right wrist and removing it from the world."); planning_scene_msg.world.collision_objects.clear(); planning_scene_msg.world.collision_objects.push_back(remove_object); planning_scene_msg.robot_state.attached_collision_objects.push_back(attached_object); planning_scene_diff_publisher.publish(planning_scene_msg); //sleep_time.sleep(); // Create a publisher for visualizing plans in Rviz. ros::Publisher display_publisher = node_handle.advertise<moveit_msgs::DisplayTrajectory>("/move_group/display_planned_path", 1, true); planning_scene::PlanningScenePtr planning_scene(new planning_scene::PlanningScene(robot_model,collision_detection::WorldPtr(new collision_detection::World()))); //Creating planning_scene_monitor boost::shared_ptr<tf::TransformListener> tf(new tf::TransformListener(ros::Duration(2.0))); planning_scene_monitor::PlanningSceneMonitorPtr planning_scene_monitor(new planning_scene_monitor::PlanningSceneMonitor(planning_scene,"robot_description", tf)); planning_scene_monitor->startSceneMonitor(); //planning_scene_monitor->initialize(planning_scene); planning_pipeline::PlanningPipeline *planning_pipeline= new planning_pipeline::PlanningPipeline(robot_model,node_handle,"planning_plugin", "request_adapters"); /* Sleep a little to allow time to startup rviz, etc. */ ros::WallDuration sleep_time(20.0); sleep_time.sleep(); /*end of MOVEIT Setup*/ // We can print the name of the reference frame for this robot. ROS_INFO("Reference frame: %s", group.getPlanningFrame().c_str()); // We can also print the name of the end-effector link for this group. ROS_INFO("Reference frame: %s", group.getEndEffectorLink().c_str()); // Planning to a Pose goal 1 // ^^^^^^^^^^^^^^^^^^^^^^^ // We can plan a motion for this group to a desired pose for the // end-effector ROS_INFO("Planning to INITIAL POSE"); planning_interface::MotionPlanRequest req; planning_interface::MotionPlanResponse res; geometry_msgs::PoseStamped pose; pose.header.frame_id = "/odom_combined"; pose.pose.position.x = 0; pose.pose.position.y = 0; pose.pose.position.z = 1.15; pose.pose.orientation.w = 1.0; std::vector<double> tolerance_pose(3, 0.01); std::vector<double> tolerance_angle(3, 0.01); old_pose=pose; // We will create the request as a constraint using a helper function available req.group_name = "arm"; moveit_msgs::Constraints pose_goal = kinematic_constraints::constructGoalConstraints("gripper_base_link", pose, tolerance_pose, tolerance_angle); req.goal_constraints.push_back(pose_goal); // Now, call the pipeline and check whether planning was successful. planning_pipeline->generatePlan(planning_scene, req, res); /* Check that the planning was successful */ if(res.error_code_.val != res.error_code_.SUCCESS) { ROS_ERROR("Could not compute plan successfully"); return 0; } // Visualize the result // ^^^^^^^^^^^^^^^^^^^^ /* Visualize the trajectory */ moveit_msgs::DisplayTrajectory display_trajectory; ROS_INFO("Visualizing the trajectory 1"); moveit_msgs::MotionPlanResponse response; res.getMessage(response); display_trajectory.trajectory_start = response.trajectory_start; display_trajectory.trajectory.push_back(response.trajectory); display_publisher.publish(display_trajectory); //sleep_time.sleep(); /* End Planning to a Pose goal 1*/ // First, set the state in the planning scene to the final state of the last plan robot_state::RobotState& robot_state = planning_scene->getCurrentStateNonConst(); //planning_scene->setCurrentState(response.trajectory_start); joint_model_group = robot_state.getJointModelGroup("arm"); robot_state.setJointGroupPositions(joint_model_group, response.trajectory.joint_trajectory.points.back().positions); spinner.stop(); /*Capturing Stage*/ /*****************/ ROS_INFO("PRESH ENTER TO START CAPTURING POINTS"); while (getline(std::cin,s)) { if ('\n' == getchar()) break; } /* SENSOR SUBSCRIBING */ //LEAP MOTION ROS_INFO("SUBSCRIBING LEAPMOTION"); ros::Subscriber leapsub = node_handle.subscribe("/leapmotion/data", 1000, &LeapMotionListener::leapmotionCallback, &leapmotionlistener); ros::Subscriber trajectorysub = node_handle.subscribe("/move_group/", 1000, &LeapMotionListener::leapmotionCallback, &leapmotionlistener); while(!CAPTURE_MOVEMENT==true) { ros::spinOnce(); } leapsub.shutdown(); ROS_INFO("CAPTURING POINTS FINISH...PROCESSING POINTS"); // End of Capturing Stage /* Start Creating Arm Trajectory*/ /**********************************/ ROS_INFO("START CREATING ARM TRAJECTORY"); for (unsigned i=0; i<trajectory_hand.size(); i++) { //First we set the initial Position of the Hand if (FIRST_VALUE) { dataLastHand_.palmpos.x=trajectory_hand.at(i).palmpos.x; dataLastHand_.palmpos.y=trajectory_hand.at(i).palmpos.y; dataLastHand_.palmpos.z=trajectory_hand.at(i).palmpos.z; FIRST_VALUE=0; ROS_INFO("ORIGINAL POSITION OF THE HAND SET TO \n X: %f\n Y: %f\n Z: %f\n ",trajectory_hand.at(i).palmpos.x,trajectory_hand.at(i).palmpos.y,trajectory_hand.at(i).palmpos.z); sleep(2); } else { // Both limits for x,y,z to avoid small changes Updifferencex=dataLastHand_.palmpos.x+10; Downdifferencex=dataLastHand_.palmpos.x-10; Updifferencez=dataLastHand_.palmpos.z+10; Downdifferencez=dataLastHand_.palmpos.z-20; Updifferencey=dataLastHand_.palmpos.y+20; Downdifferencey=dataLastHand_.palmpos.y-20; if ((trajectory_hand.at(i).palmpos.x<Downdifferencex)||(trajectory_hand.at(i).palmpos.x>Updifferencex)||(trajectory_hand.at(i).palmpos.y<Downdifferencey)||(trajectory_hand.at(i).palmpos.y>Updifferencey)||(trajectory_hand.at(i).palmpos.z<Downdifferencez)||(trajectory_hand.at(i).palmpos.z>Updifferencez)) { ros::AsyncSpinner spinner(1); spinner.start(); ROS_INFO("TRYING TO ADD POINT %d TO TRAJECTORY",arm_trajectory_point); // Cartesian Paths // ^^^^^^^^^^^^^^^ // You can plan a cartesian path directly by specifying a list of waypoints // for the end-effector to go through. Note that we are starting // from the new start state above. The initial pose (start state) does not // need to be added to the waypoint list. pose.header.frame_id = "/odom_combined"; pose.pose.orientation.w = 1.0; pose.pose.position.y +=(trajectory_hand.at(i).palmpos.x-dataLastHand_.palmpos.x)/500 ; pose.pose.position.z +=(trajectory_hand.at(i).palmpos.y-dataLastHand_.palmpos.y)/1000 ; if(pose.pose.position.z>Uplimitez) pose.pose.position.z=Uplimitez; pose.pose.position.x +=-(trajectory_hand.at(i).palmpos.z-dataLastHand_.palmpos.z)/500 ; ROS_INFO("END EFFECTOR POSITION \n X: %f\n Y: %f\n Z: %f\n", pose.pose.position.x,pose.pose.position.y,pose.pose.position.z); ROS_INFO("Palmpos \n X: %f\n Y: %f\n Z: %f\n ",trajectory_hand.at(i).palmpos.x,trajectory_hand.at(i).palmpos.y,trajectory_hand.at(i).palmpos.z); // We will create the request as a constraint using a helper function available ROS_INFO("1"); pose_goal= kinematic_constraints::constructGoalConstraints("gripper_base_link", pose, tolerance_pose, tolerance_angle); ROS_INFO("2"); req.goal_constraints.push_back(pose_goal); // Now, call the pipeline and check whether planning was successful. planning_pipeline->generatePlan(planning_scene, req, res); ROS_INFO("3"); if(res.error_code_.val != res.error_code_.SUCCESS) { ROS_ERROR("Could not compute plan successfully"); pose=old_pose; } else { // Now when we plan a trajectory it will avoid the obstacle res.getMessage(response); collision_result.clear(); collision_detection::AllowedCollisionMatrix acm = planning_scene->getAllowedCollisionMatrix(); robot_state::RobotState copied_state = planning_scene->getCurrentState(); planning_scene->checkCollision(collision_request, collision_result, copied_state, acm); ROS_INFO_STREAM("Collision Test "<< (collision_result.collision ? "in" : "not in")<< " collision"); arm_trajectory_point++; // Visualize the trajectory ROS_INFO("VISUALIZING NEW POINT"); //req.goal_constraints.clear(); display_trajectory.trajectory_start = response.trajectory_start; ROS_INFO("AXIS 1 NEXT TRAJECTORY IS %f\n",response.trajectory_start.joint_state.position[1] ); display_trajectory.trajectory.push_back(response.trajectory); // Now you should see two planned trajectories in series display_publisher.publish(display_trajectory); planning_scene->setCurrentState(response.trajectory_start); if (planning_scene_monitor->updatesScene(planning_scene)) { ROS_INFO("CHANGING STATE"); planning_scene_monitor->updateSceneWithCurrentState(); } else { ROS_ERROR("NOT POSSIBLE TO CHANGE THE SCENE"); } robot_state.setJointGroupPositions(joint_model_group, response.trajectory.joint_trajectory.points.back().positions); req.goal_constraints.clear(); old_pose=pose; dataLastHand_.palmpos.x=trajectory_hand.at(i).palmpos.x; dataLastHand_.palmpos.y=trajectory_hand.at(i).palmpos.y; dataLastHand_.palmpos.z=trajectory_hand.at(i).palmpos.z; } //sleep(2); spinner.stop(); } } } //ros::Subscriber myogestsub = n.subscribe("/myo_gest", 1000, myogestCallback); return 0; }
int main(int argc, char **argv) { ros::init (argc, argv, "motion_planning"); ros::AsyncSpinner spinner(1); spinner.start(); ros::NodeHandle node_handle("/move_group"); // ros::NodeHandle node_handle("~"); /* SETUP A PLANNING SCENE*/ /* Load the robot model */ robot_model_loader::RobotModelLoader robot_model_loader("robot_description"); /* Get a shared pointer to the model */ robot_model::RobotModelPtr robot_model = robot_model_loader.getModel(); /* Construct a planning scene - NOTE: this is for illustration purposes only. The recommended way to construct a planning scene is to use the planning_scene_monitor to construct it for you.*/ planning_scene::PlanningScenePtr planning_scene(new planning_scene::PlanningScene(robot_model)); /* SETUP THE PLANNER*/ boost::scoped_ptr<pluginlib::ClassLoader<planning_interface::PlannerManager> > planner_plugin_loader; planning_interface::PlannerManagerPtr planner_instance; std::string planner_plugin_name; /* Get the name of the planner we want to use */ if (!node_handle.getParam("planning_plugin", planner_plugin_name)) ROS_FATAL_STREAM("Could not find planner plugin name"); /* Make sure to catch all exceptions */ try { planner_plugin_loader.reset(new pluginlib::ClassLoader<planning_interface::PlannerManager>("moveit_core", "planning_interface::PlannerManager")); } catch(pluginlib::PluginlibException& ex) { ROS_FATAL_STREAM("Exception while creating planning plugin loader " << ex.what()); } try { planner_instance.reset(planner_plugin_loader->createUnmanagedInstance(planner_plugin_name)); if (!planner_instance->initialize(robot_model, node_handle.getNamespace())) ROS_FATAL_STREAM("Could not initialize planner instance"); ROS_INFO_STREAM("Using planning interface '" << planner_instance->getDescription() << "'"); } catch(pluginlib::PluginlibException& ex) { const std::vector<std::string> &classes = planner_plugin_loader->getDeclaredClasses(); std::stringstream ss; for (std::size_t i = 0 ; i < classes.size() ; ++i) ss << classes[i] << " "; ROS_ERROR_STREAM("Exception while loading planner '" << planner_plugin_name << "': " << ex.what() << std::endl << "Available plugins: " << ss.str()); } /* Sleep a little to allow time to startup rviz, etc. */ ros::WallDuration sleep_time(1.0); sleep_time.sleep(); /* CREATE A MOTION PLAN REQUEST FOR THE RIGHT ARM OF THE PR2 */ /* We will ask the end-effector of the PR2 to go to a desired location */ planning_interface::MotionPlanRequest req; planning_interface::MotionPlanResponse res; /* A desired pose */ geometry_msgs::PoseStamped pose; pose.header.frame_id = "base_link"; pose.pose.position.x = 0.3; pose.pose.position.y = -0.3; pose.pose.position.z = 0.7; pose.pose.orientation.x = 0.62478; pose.pose.orientation.y = 0.210184; pose.pose.orientation.z = -0.7107 ; pose.pose.orientation.w = 0.245722; /* A desired tolerance */ std::vector<double> tolerance_pose(3, 0.1); std::vector<double> tolerance_angle(3, 0.1); // std::vector<double> tolerance_pose(3, 0.01); // std::vector<double> tolerance_angle(3, 0.01); ROS_INFO("marker4"); /*Create the request */ req.group_name = "manipulator"; moveit_msgs::Constraints pose_goal = kinematic_constraints::constructGoalConstraints("wrist_3_link", pose, tolerance_pose, tolerance_angle); req.goal_constraints.push_back(pose_goal); ROS_INFO("marker5"); /* Construct the planning context */ planning_interface::PlanningContextPtr context = planner_instance->getPlanningContext(planning_scene, req, res.error_code_); ROS_INFO("marker6"); /* CALL THE PLANNER */ // context->solve(res); // ROS_INFO("marker7"); /* Check that the planning was successful */ if(res.error_code_.val != res.error_code_.SUCCESS) { ROS_ERROR("Could not compute plan successfully"); return 0; } /* Visualize the generated plan */ /* Publisher for display */ ros::Publisher display_publisher = node_handle.advertise<moveit_msgs::DisplayTrajectory>("/move_group/display_planned_path", 1, true); moveit_msgs::DisplayTrajectory display_trajectory; /* Visualize the trajectory */ ROS_INFO("Visualizing the trajectory"); moveit_msgs::MotionPlanResponse response; res.getMessage(response); display_trajectory.trajectory_start = response.trajectory_start; display_trajectory.trajectory.push_back(response.trajectory); display_publisher.publish(display_trajectory); sleep_time.sleep(); /* NOW TRY A JOINT SPACE GOAL */ /* First, set the state in the planning scene to the final state of the last plan */ robot_state::RobotState& robot_state = planning_scene->getCurrentStateNonConst(); planning_scene->setCurrentState(response.trajectory_start); robot_state::JointStateGroup* joint_state_group = robot_state.getJointStateGroup("manipulator"); joint_state_group->setVariableValues(response.trajectory.joint_trajectory.points.back().positions); /* Now, setup a joint space goal*/ robot_state::RobotState goal_state(robot_model); robot_state::JointStateGroup* goal_group = goal_state.getJointStateGroup("manipulator"); std::vector<double> joint_values(7, 0.0); // joint_values[0] = 2.0; joint_values[2] = 1.6; // joint_values[5] = -0.15; goal_group->setVariableValues(joint_values); moveit_msgs::Constraints joint_goal = kinematic_constraints::constructGoalConstraints(goal_group); req.goal_constraints.clear(); req.goal_constraints.push_back(joint_goal); /* Construct the planning context */ context = planner_instance->getPlanningContext(planning_scene, req, res.error_code_); /* Call the Planner */ context->solve(res); /* Check that the planning was successful */ if(res.error_code_.val != res.error_code_.SUCCESS) { ROS_ERROR("Could not compute plan successfully"); return 0; } /* Visualize the trajectory */ ROS_INFO("Visualizing the trajectory"); res.getMessage(response); display_trajectory.trajectory_start = response.trajectory_start; display_trajectory.trajectory.push_back(response.trajectory); //Now you should see two planned trajectories in series display_publisher.publish(display_trajectory); /* Now, let's try to go back to the first goal*/ /* First, set the state in the planning scene to the final state of the last plan */ joint_state_group->setVariableValues(response.trajectory.joint_trajectory.points.back().positions); /* Now, we go back to the first goal*/ req.goal_constraints.clear(); req.goal_constraints.push_back(pose_goal); context = planner_instance->getPlanningContext(planning_scene, req, res.error_code_); context->solve(res); res.getMessage(response); display_trajectory.trajectory.push_back(response.trajectory); display_publisher.publish(display_trajectory); /* Let's create a new pose goal */ pose.pose.position.x = 0.65; pose.pose.position.y = -0.2; pose.pose.position.z = -0.1; moveit_msgs::Constraints pose_goal_2 = kinematic_constraints::constructGoalConstraints("wrist_3_link", pose, tolerance_pose, tolerance_angle); /* First, set the state in the planning scene to the final state of the last plan */ joint_state_group->setVariableValues(response.trajectory.joint_trajectory.points.back().positions); /* Now, let's try to move to this new pose goal*/ req.goal_constraints.clear(); req.goal_constraints.push_back(pose_goal_2); /* But, let's impose a path constraint on the motion. Here, we are asking for the end-effector to stay level*/ geometry_msgs::QuaternionStamped quaternion; quaternion.header.frame_id = "base_link"; quaternion.quaternion.w = 1.0; req.path_constraints = kinematic_constraints::constructGoalConstraints("wrist_3_link", quaternion); // imposing path constraints requires the planner to reason in the space of possible positions of the end-effector // (the workspace of the robot) // because of this, we need to specify a bound for the allowed planning volume as well; // Note: a default bound is automatically filled by the WorkspaceBounds request adapter (part of the OMPL pipeline, // but that is not being used in this example). // We use a bound that definitely includes the reachable space for the arm. This is fine because sampling is not done in this volume // when planning for the arm; the bounds are only used to determine if the sampled configurations are valid. req.workspace_parameters.min_corner.x = req.workspace_parameters.min_corner.y = -2.0; req.workspace_parameters.min_corner.z = 0.2; req.workspace_parameters.max_corner.x = req.workspace_parameters.max_corner.y = req.workspace_parameters.max_corner.z = 2.0; context = planner_instance->getPlanningContext(planning_scene, req, res.error_code_); context->solve(res); res.getMessage(response); display_trajectory.trajectory.push_back(response.trajectory); //Now you should see four planned trajectories in series display_publisher.publish(display_trajectory); sleep_time.sleep(); ROS_INFO("Done"); planner_instance.reset(); return 0; }