Esempio n. 1
0
TEST_F(TestTransitionWrapper, wrapper) {
  {
    rclcpp_lifecycle::Transition t(12, "no_states_set");
    EXPECT_EQ(12, t.id());
    EXPECT_STREQ("no_states_set", t.label().c_str());
  }

  {
    std::string transition_name = "no_states_set";
    rclcpp_lifecycle::Transition t(12, transition_name);
    transition_name = "not_no_states_set";
    EXPECT_EQ(12, t.id());
    EXPECT_STREQ("no_states_set", t.label().c_str());
  }

  {
    rclcpp_lifecycle::State start_state(1, "start_state");
    rclcpp_lifecycle::State goal_state(2, "goal_state");

    rclcpp_lifecycle::Transition t(
      12,
      "from_start_to_goal",
      std::move(start_state),
      std::move(goal_state));

    EXPECT_EQ(12, t.id());
    EXPECT_FALSE(t.label().empty());
    EXPECT_STREQ("from_start_to_goal", t.label().c_str());
  }
}
void MotionPlanningFrame::computeLoadQueryButtonClicked()
{
  if (planning_scene_storage_)
  {
    QList<QTreeWidgetItem *> sel = ui_->planning_scene_tree->selectedItems();
    if (!sel.empty())
    {
      QTreeWidgetItem *s = sel.front();
      if (s->type() == ITEM_TYPE_QUERY)
      {
        std::string scene = s->parent()->text(0).toStdString();
        std::string query_name = s->text(0).toStdString();
        moveit_warehouse::MotionPlanRequestWithMetadata mp;
        bool got_q = false;
        try
        {
          got_q = planning_scene_storage_->getPlanningQuery(mp, scene, query_name);
        }
        catch (std::runtime_error &ex)
        {
          ROS_ERROR("%s", ex.what());
        }
        
        if (got_q)
        {
          robot_state::RobotStatePtr start_state(new robot_state::RobotState(*planning_display_->getQueryStartState()));
          robot_state::robotStateMsgToRobotState(planning_display_->getPlanningSceneRO()->getTransforms(), mp->start_state, *start_state);
          planning_display_->setQueryStartState(*start_state);
          
          robot_state::RobotStatePtr goal_state(new robot_state::RobotState(*planning_display_->getQueryGoalState()));
          for (std::size_t i = 0 ; i < mp->goal_constraints.size() ; ++i)
            if (mp->goal_constraints[i].joint_constraints.size() > 0)
            {
              std::map<std::string, double> vals;
              for (std::size_t j = 0 ; j < mp->goal_constraints[i].joint_constraints.size() ; ++j)
                vals[mp->goal_constraints[i].joint_constraints[j].joint_name] = mp->goal_constraints[i].joint_constraints[j].position;
              goal_state->setVariablePositions(vals);
              break;
            }
          planning_display_->setQueryGoalState(*goal_state);
        }
        else
          ROS_ERROR("Failed to load planning query '%s'. Has the message format changed since the query was saved?", query_name.c_str());
      }
    }
  }
}
void EpicNavigationNodeOMPL::initAlg()
{
    // Only initialize the algorithm if all necessary variables have been defined.
    if (!goal_assigned || !start_assigned || occupancy_grid == nullptr) {
        return;
    }

    // Setup the OMPL state space.
    ompl::base::RealVectorBounds ompl_bounds(2);
    ompl_bounds.setLow(0, 0.0);
    ompl_bounds.setHigh(0, height);
    ompl_bounds.setLow(1, 0.0);
    ompl_bounds.setHigh(1, width);

    ompl::base::StateSpacePtr ompl_space(new ompl::base::RealVectorStateSpace(2));
    ompl_space->as<ompl::base::RealVectorStateSpace>()->setBounds(ompl_bounds);

    // The state validity checker holds the map representation so we can check if a cell is valid or not.
    ompl::base::SpaceInformationPtr ompl_space_info(new ompl::base::SpaceInformation(ompl_space));
    ompl_space_info->setStateValidityChecker(ompl::base::StateValidityCheckerPtr(
                            new EpicNavigationNodeOMPLStateValidityChecker(ompl_space_info, occupancy_grid)));
    ompl_space_info->setup();

    // We relinquish control of the occupancy_grid. It will be managed by the EpicNavigatioNodeOMPLStateValidityChecker object.
    occupancy_grid = nullptr;

    // Create the problem definition.
    ompl::base::ScopedState<> start_state(ompl_space);
    start_state->as<ompl::base::RealVectorStateSpace::StateType>()->values[0] = start_location.second;
    start_state->as<ompl::base::RealVectorStateSpace::StateType>()->values[1] = start_location.first;

    ompl::base::ScopedState<> goal_state(ompl_space);
    goal_state->as<ompl::base::RealVectorStateSpace::StateType>()->values[0] = goal_location.second;
    goal_state->as<ompl::base::RealVectorStateSpace::StateType>()->values[1] = goal_location.first;

    ompl::base::ProblemDefinitionPtr ompl_problem_def(new ompl::base::ProblemDefinition(ompl_space_info));
    ompl_problem_def->setOptimizationObjective(omplGetPathLengthObjective(ompl_space_info));

    if (algorithm == EPIC_ALGORITHM_RRT_CONNECT) {
        ompl_planner = ompl::base::PlannerPtr(new ompl::geometric::RRTConnect(ompl_space_info));
    } else {
    }

    init_alg = true;
}
Esempio n. 4
0
bool
SSLPathPlanner::doPlanForRobot (const int& id/*, bool& is_stop*/)
{
  //  is_send_plan = true;
  tmp_robot_id_queried = id;

  State* tmp_start = manifold->allocState ();
  tmp_start->as<RealVectorStateManifold::StateType> ()->values[0] = team_state_[id].pose.x;
  tmp_start->as<RealVectorStateManifold::StateType> ()->values[1] = team_state_[id].pose.y;

  PathGeometric direct_path (planner_setup->getSpaceInformation ());
  direct_path.states.push_back (manifold->allocState ());
  manifold->copyState (direct_path.states[0], tmp_start);

  State* tmp_goal = manifold->allocState ();

  tmp_goal->as<RealVectorStateManifold::StateType> ()->values[0] = pose_control.pose[id].pose.x;
  tmp_goal->as<RealVectorStateManifold::StateType> ()->values[1] = pose_control.pose[id].pose.y;
  //  std::cout<<pose_control.pose[id].pose.x<<"\t"<<pose_control.pose[id].pose.y<<std::endl;

  direct_path.states.push_back (manifold->allocState ());
  manifold->copyState (direct_path.states[1], tmp_goal);

  Point_2 p_start (team_state_[id].pose.x, team_state_[id].pose.y);
  Point_2 p_goal (pose_control.pose[id].pose.x, pose_control.pose[id].pose.y);

  //too close to the target point, no need for planning, just take it as a next_target_pose
  if (sqrt (getSquaredDistance (p_start, p_goal)) < VERY_CRITICAL_DIST)
  {
    next_target_poses[id].x = pose_control.pose[id].pose.x;
    next_target_poses[id].y = pose_control.pose[id].pose.y;
    next_target_poses[id].theta = pose_control.pose[id].pose.theta;
    return true;
  }

  //  manifold->printState (direct_path.states[0], std::cout);
  //  manifold->printState (direct_path.states[1], std::cout);

  //direct path is available, no need for planning
  //  if (direct_path.check ())
  if (!doesIntersectObstacles (id, p_start, p_goal))
  {
    //    std::cout << "direct path is AVAILABLE for robot " << id << std::endl;

    if (solution_data_for_robots[id].size () > direct_path.states.size ())
    {
      for (uint32_t i = direct_path.states.size (); i < solution_data_for_robots[id].size (); i++)
        manifold->freeState (solution_data_for_robots[id][i]);
      solution_data_for_robots[id].resize (direct_path.states.size ());
    }
    else if (solution_data_for_robots[id].size () < direct_path.states.size ())
    {
      for (uint32_t i = solution_data_for_robots[id].size (); i < direct_path.states.size (); i++)
        solution_data_for_robots[id].push_back (manifold->allocState ());
    }
    for (uint32_t i = 0; i < direct_path.states.size (); i++)
      manifold->copyState (solution_data_for_robots[id][i], direct_path.states[i]);

    manifold->freeState (tmp_start);
    manifold->freeState (tmp_goal);

    next_target_poses[id].x = pose_control.pose[id].pose.x;
    next_target_poses[id].y = pose_control.pose[id].pose.y;
    next_target_poses[id].theta = pose_control.pose[id].pose.theta;
    //    std::cout<<next_target_poses[id].x<<"\t"<<next_target_poses[id].y<<std::endl;

    return true;
  }
  manifold->freeState (tmp_start);
  manifold->freeState (tmp_goal);
  //  std::cout << "direct path is NOT AVAILABLE for robot " << id << ", doing planning" << std::endl;
  //direct path is not available, DO PLAN if the earlier plan is invalidated!

  //earlier plan is still valid
  if (checkPlanForRobot (id))
    return true;
  else if (is_plan_done[id])
    return false;

  //earlier plan is not valid anymore, replan
  planner_setup->clear ();
  planner_setup->clearStartStates ();

  ScopedState<RealVectorStateManifold> start_state (manifold);
  ScopedState<RealVectorStateManifold> goal_state (manifold);

  start_state->values[0] = team_state_[id].pose.x;
  start_state->values[1] = team_state_[id].pose.y;

  goal_state->values[0] = pose_control.pose[id].pose.x;
  goal_state->values[1] = pose_control.pose[id].pose.y;

  planner_setup->setStartAndGoalStates (start_state, goal_state);
  planner_setup->getProblemDefinition ()->fixInvalidInputStates (ssl::config::ROBOT_BOUNDING_RADIUS / 2.0,
                                                                 ssl::config::ROBOT_BOUNDING_RADIUS / 2.0, 100);
  bool solved = planner_setup->solve (0.100);//100msec

  if (solved)
  {
    planner_setup->simplifySolution ();

    PathGeometric* path;
    path = &planner_setup->getSolutionPath ();

    //    PathSimplifier p (planner_setup->getSpaceInformation ());
    //    p.reduceVertices (*path, 1000);

    if (solution_data_for_robots[id].size () < path->states.size ())
    {
      for (unsigned int i = solution_data_for_robots[id].size (); i < path->states.size (); i++)
        solution_data_for_robots[id].push_back (manifold->allocState ());
    }
    else if (solution_data_for_robots[id].size () > path->states.size ())
    {
      for (unsigned int i = path->states.size (); i < solution_data_for_robots[id].size (); i++)
        manifold->freeState (solution_data_for_robots[id][i]);
      //drop last elements that are already being freed
      solution_data_for_robots[id].resize (path->states.size ());
    }

    for (unsigned int i = 0; i < path->states.size (); i++)
      manifold->copyState (solution_data_for_robots[id][i], path->states[i]);

    //leader-follower approach based segment enlargement
    //pick next location
    Point_2 curr_point (path->states[0]->as<RealVectorStateManifold::StateType> ()->values[0], path->states[0]->as<
        RealVectorStateManifold::StateType> ()->values[1]);

    for (uint32_t i = 1; i < path->states.size (); i++)
    {
      Point_2 next_point (path->states[i]->as<RealVectorStateManifold::StateType> ()->values[0], path->states[i]->as<
          RealVectorStateManifold::StateType> ()->values[1]);
      if (!doesIntersectObstacles (id, curr_point, next_point))
      {
        next_target_poses[id].x = path->states[i]->as<RealVectorStateManifold::StateType> ()->values[0];
        next_target_poses[id].y = path->states[i]->as<RealVectorStateManifold::StateType> ()->values[1];
        next_target_poses[id].theta = pose_control.pose[id].pose.theta;
      }
      else
        break;
    }
    //    next_target_poses[id].x = path->states[1]->as<RealVectorStateManifold::StateType> ()->values[0];
    //    next_target_poses[id].y = path->states[1]->as<RealVectorStateManifold::StateType> ()->values[1];

    //    planner_data_for_robots[id].clear ();
    //    planner_data_for_robots[id] = planner_setup->getPlannerData ();
  }
  return solved;
}
Esempio n. 5
0
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;
}
Esempio n. 6
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;
}
Esempio n. 7
0
  void FootstepPlanner::planCB(
    const jsk_footstep_msgs::PlanFootstepsGoal::ConstPtr& goal)
  {
    boost::mutex::scoped_lock lock(mutex_);
    latest_header_ = goal->goal_footstep.header;
    JSK_ROS_INFO("planCB");
    // check message sanity
    if (goal->initial_footstep.footsteps.size() == 0) {
      JSK_ROS_ERROR("no initial footstep is specified");
      as_.setPreempted();
      return;
    }
    if (goal->goal_footstep.footsteps.size() != 2) {
      JSK_ROS_ERROR("Need to specify 2 goal footsteps");
      as_.setPreempted();
      return;
    }
    if (use_pointcloud_model_ && !pointcloud_model_) {
      JSK_ROS_ERROR("No pointcloud model is yet available");
      as_.setPreempted();
      return;
    }
    //ros::WallDuration timeout(goal->timeout.expectedCycleTime().toSec());
    ros::WallDuration timeout(10.0);
    Eigen::Vector3f footstep_size(footstep_size_x_, footstep_size_y_, 0.000001);
    ////////////////////////////////////////////////////////////////////
    // set start state
    // 0 is always start
    Eigen::Affine3f start_pose;
    tf::poseMsgToEigen(goal->initial_footstep.footsteps[0].pose, start_pose);
    FootstepState::Ptr start(FootstepState::fromROSMsg(
                               goal->initial_footstep.footsteps[0],
                               footstep_size,
                               Eigen::Vector3f(resolution_x_,
                                               resolution_y_,
                                               resolution_theta_)));
    graph_->setStartState(start);
    if (project_start_state_) {
      if (!graph_->projectStart()) {
        JSK_ROS_ERROR("Failed to project start state");
        publishText(pub_text_,
                    "Failed to project start",
                    ERROR);

        as_.setPreempted();
        return;
      }
    }

    ////////////////////////////////////////////////////////////////////
    // set goal state
    jsk_footstep_msgs::Footstep left_goal, right_goal;
    for (size_t i = 0; i < goal->goal_footstep.footsteps.size(); i++) {
      FootstepState::Ptr goal_state(FootstepState::fromROSMsg(
                                      goal->goal_footstep.footsteps[i],
                                      footstep_size,
                                      Eigen::Vector3f(resolution_x_,
                                                      resolution_y_,
                                                      resolution_theta_)));
      if (goal_state->getLeg() == jsk_footstep_msgs::Footstep::LEFT) {
        graph_->setLeftGoalState(goal_state);
        left_goal = goal->goal_footstep.footsteps[i];
      }
      else if (goal_state->getLeg() == jsk_footstep_msgs::Footstep::RIGHT) {
        graph_->setRightGoalState(goal_state);
        right_goal = goal->goal_footstep.footsteps[i];
      }
      else {
        JSK_ROS_ERROR("unknown goal leg");
        as_.setPreempted();
        return;
      }
    }
    if (project_goal_state_) {
      if (!graph_->projectGoal()) {
        JSK_ROS_ERROR("Failed to project goal");
        as_.setPreempted();
        publishText(pub_text_,
                    "Failed to project goal",
                    ERROR);
        return;
      }
    }
    // set parameters
    if (use_transition_limit_) {
      graph_->setTransitionLimit(
        TransitionLimitXYZRPY::Ptr(new TransitionLimitXYZRPY(
                                     transition_limit_x_,
                                     transition_limit_y_,
                                     transition_limit_z_,
                                     transition_limit_roll_,
                                     transition_limit_pitch_,
                                     transition_limit_yaw_)));
    }
    else {
      graph_->setTransitionLimit(TransitionLimitXYZRPY::Ptr());
    }
    graph_->setLocalXMovement(local_move_x_);
    graph_->setLocalYMovement(local_move_y_);
    graph_->setLocalThetaMovement(local_move_theta_);
    graph_->setLocalXMovementNum(local_move_x_num_);
    graph_->setLocalYMovementNum(local_move_y_num_);
    graph_->setLocalThetaMovementNum(local_move_theta_num_);
    graph_->setPlaneEstimationMaxIterations(plane_estimation_max_iterations_);
    graph_->setPlaneEstimationMinInliers(plane_estimation_min_inliers_);
    graph_->setPlaneEstimationOutlierThreshold(plane_estimation_outlier_threshold_);
    graph_->setSupportCheckXSampling(support_check_x_sampling_);
    graph_->setSupportCheckYSampling(support_check_y_sampling_);
    graph_->setSupportCheckVertexNeighborThreshold(support_check_vertex_neighbor_threshold_);
    // Solver setup
    FootstepAStarSolver<FootstepGraph> solver(graph_,
                                              close_list_x_num_,
                                              close_list_y_num_,
                                              close_list_theta_num_,
                                              profile_period_,
                                              cost_weight_,
                                              heuristic_weight_);
    if (heuristic_ == "step_cost") {
      solver.setHeuristic(boost::bind(&FootstepPlanner::stepCostHeuristic, this, _1, _2));
    }
    else if (heuristic_ == "zero") {
      solver.setHeuristic(boost::bind(&FootstepPlanner::zeroHeuristic, this, _1, _2));
    }
    else if (heuristic_ == "straight") {
      solver.setHeuristic(boost::bind(&FootstepPlanner::straightHeuristic, this, _1, _2));
    }
    else if (heuristic_ == "straight_rotation") {
      solver.setHeuristic(boost::bind(&FootstepPlanner::straightRotationHeuristic, this, _1, _2));
    }
    else {
      JSK_ROS_ERROR("Unknown heuristics");
      as_.setPreempted();
      return;
    }
    solver.setProfileFunction(boost::bind(&FootstepPlanner::profile, this, _1, _2));
    ros::WallTime start_time = ros::WallTime::now();
    std::vector<SolverNode<FootstepState, FootstepGraph>::Ptr> path = solver.solve(timeout);
    ros::WallTime end_time = ros::WallTime::now();
    double planning_duration = (end_time - start_time).toSec();
    JSK_ROS_INFO_STREAM("took " << planning_duration << " sec");
    JSK_ROS_INFO_STREAM("path: " << path.size());
    if (path.size() == 0) {
      JSK_ROS_ERROR("Failed to plan path");
      publishText(pub_text_,
                  "Failed to plan",
                  ERROR);
      as_.setPreempted();
      return;
    }
    // Convert path to FootstepArray
    jsk_footstep_msgs::FootstepArray ros_path;
    ros_path.header = goal->goal_footstep.header;
    for (size_t i = 0; i < path.size(); i++) {
      ros_path.footsteps.push_back(*path[i]->getState()->toROSMsg());
    }
    // finalize path
    if (path[path.size() - 1]->getState()->getLeg() == jsk_footstep_msgs::Footstep::LEFT) {
      ros_path.footsteps.push_back(right_goal);
      ros_path.footsteps.push_back(left_goal);
    }
    else if (path[path.size() - 1]->getState()->getLeg() == jsk_footstep_msgs::Footstep::RIGHT) {
      ros_path.footsteps.push_back(left_goal);
      ros_path.footsteps.push_back(right_goal);
    }
    result_.result = ros_path;
    as_.setSucceeded(result_);

    pcl::PointCloud<pcl::PointNormal> close_list_cloud, open_list_cloud;
    solver.openListToPointCloud(open_list_cloud);
    solver.closeListToPointCloud(close_list_cloud);
    publishPointCloud(close_list_cloud, pub_close_list_, goal->goal_footstep.header);
    publishPointCloud(open_list_cloud, pub_open_list_, goal->goal_footstep.header);
    publishText(pub_text_,
                (boost::format("Planning took %f sec\n%lu path\nopen list: %lu\nclose list:%lu")
                 % planning_duration % path.size()
                 % open_list_cloud.points.size()
                 % close_list_cloud.points.size()).str(),
                OK);
  }
TEST_F(Pr2SBPLPlannerTester, ManyPlan) 
{
  planning_scene::PlanningScenePtr ps(new planning_scene::PlanningScene());
  ps->setActiveCollisionDetector(collision_detection::CollisionDetectorAllocatorHybridROS::create());
  ps->configure(rml_->getURDF(), rml_->getSRDF());
  ASSERT_TRUE(ps->isConfigured());
  ps->getAllowedCollisionMatrixNonConst() = *acm_;

  planning_models::RobotState *::JointStateGroup* start_jsg = ps->getCurrentState().getJointStateGroup("right_arm");
  planning_models::RobotState *goal_state(ps->getCurrentState());
  planning_models::RobotState *::JointStateGroup* goal_jsg = goal_state.getJointStateGroup("right_arm");
  
  sbpl_interface::SBPLInterface sbpl_planner(ps->getRobotModel());

  moveit_msgs::GetMotionPlan::Request mplan_req;
  mplan_req.motion_plan_request.group_name = "right_arm";
  mplan_req.motion_plan_request.num_planning_attempts = 5;
  mplan_req.motion_plan_request.allowed_planning_time = ros::Duration(5.0);
  const std::vector<std::string>& joint_names = ps->getRobotModel()->getJointModelGroup("right_arm")->getJointModelNames();
  mplan_req.motion_plan_request.goal_constraints.resize(1);
  mplan_req.motion_plan_request.goal_constraints[0].joint_constraints.resize(joint_names.size());
  for(unsigned int i = 0; i < joint_names.size(); i++)
  {
    mplan_req.motion_plan_request.goal_constraints[0].joint_constraints[i].joint_name = joint_names[i];
    mplan_req.motion_plan_request.goal_constraints[0].joint_constraints[i].position = 0.0;
    mplan_req.motion_plan_request.goal_constraints[0].joint_constraints[i].tolerance_above = 0.001;
    mplan_req.motion_plan_request.goal_constraints[0].joint_constraints[i].tolerance_below = 0.001;
    mplan_req.motion_plan_request.goal_constraints[0].joint_constraints[i].weight = 1.0;
  }

  unsigned int comp_trials = 0;
  unsigned int succ_trials = 0;
  double max_planning_time = 0.0;
  double total_planning_time = 0.0;
  while(comp_trials < NUM_TRIALS) {
    while(1) {
      start_jsg->setToRandomValues();
      goal_jsg->setToRandomValues();
      std::vector<double> goal_vals;
      goal_jsg->getGroupStateValues(goal_vals);
      for(unsigned int i = 0; i < joint_names.size(); i++) {
        mplan_req.motion_plan_request.goal_constraints[0].joint_constraints[i].position = goal_vals[i];
      }
      std::vector<double> start_vals;
      start_jsg->getGroupStateValues(start_vals);
      for(unsigned int i = 0; i < start_vals.size(); i++) {
        std::cerr << "Start joint " << i << " val " << start_vals[i] << std::endl;
      }
      for(unsigned int i = 0; i < goal_vals.size(); i++) {
        std::cerr << "Goal joint " << i << " val " << goal_vals[i] << std::endl;
      }
      moveit_msgs::GetMotionPlan::Response mplan_res;
      if(sbpl_planner.solve(ps,
                            mplan_req,
                            mplan_res)) {
        comp_trials++;
        succ_trials++;
        if(sbpl_planner.getLastPlanningStatistics().total_planning_time_.toSec() > max_planning_time) {
          max_planning_time = sbpl_planner.getLastPlanningStatistics().total_planning_time_.toSec();
        }
        ASSERT_LT(sbpl_planner.getLastPlanningStatistics().total_planning_time_.toSec(), 5.0);
        total_planning_time += sbpl_planner.getLastPlanningStatistics().total_planning_time_.toSec();
        break;
      } else {
        if(mplan_res.error_code.val != moveit_msgs::MoveItErrorCodes::GOAL_IN_COLLISION &&
           mplan_res.error_code.val != moveit_msgs::MoveItErrorCodes::START_STATE_IN_COLLISION) {
          std::cerr << "Bad error code " << mplan_res.error_code.val << std::endl;
          comp_trials++;
          break;
        } else {
          //std::cerr << "Something in collision" << std::endl;
        }
      }
    }
  }

  std::cerr << "Average planning time " << total_planning_time/(comp_trials*1.0) << " max " << max_planning_time << std::endl;
  EXPECT_EQ(succ_trials, comp_trials);

  //ASSERT_EQ(mplan_res.error_code.val, mplan_res.error_code.SUCCESS);
  //EXPECT_GT(mplan_res.trajectory.joint_trajectory.points.size(), 0);
}