move_group.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2012, Willow Garage, Inc.
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 
00035 /* Author: Ioan Sucan */
00036 
00037 #include <stdexcept>
00038 #include <moveit/warehouse/constraints_storage.h>
00039 #include <moveit/kinematic_constraints/utils.h>
00040 #include <moveit/move_group/capability_names.h>
00041 #include <moveit/move_group_pick_place_capability/capability_names.h>
00042 #include <moveit/move_group_interface/move_group.h>
00043 #include <moveit/planning_scene_monitor/current_state_monitor.h>
00044 #include <moveit/trajectory_execution_manager/trajectory_execution_manager.h>
00045 #include <moveit/common_planning_interface_objects/common_objects.h>
00046 #include <moveit/robot_state/conversions.h>
00047 #include <moveit_msgs/MoveGroupAction.h>
00048 #include <moveit_msgs/PickupAction.h>
00049 #include <moveit_msgs/PlaceAction.h>
00050 #include <moveit_msgs/ExecuteKnownTrajectory.h>
00051 #include <moveit_msgs/QueryPlannerInterfaces.h>
00052 #include <moveit_msgs/GetCartesianPath.h>
00053 
00054 #include <actionlib/client/simple_action_client.h>
00055 #include <eigen_conversions/eigen_msg.h>
00056 #include <std_msgs/String.h>
00057 #include <tf/transform_listener.h>
00058 #include <tf/transform_datatypes.h>
00059 #include <tf_conversions/tf_eigen.h>
00060 #include <ros/console.h>
00061 #include <ros/ros.h>
00062 
00063 namespace moveit
00064 {
00065 namespace planning_interface
00066 {
00067 
00068 const std::string MoveGroup::ROBOT_DESCRIPTION = "robot_description";    // name of the robot description (a param name, so it can be changed externally)
00069 
00070 namespace
00071 {
00072 
00073 enum ActiveTargetType
00074 {
00075   JOINT, POSE, POSITION, ORIENTATION
00076 };
00077 
00078 }
00079 
00080 class MoveGroup::MoveGroupImpl
00081 {
00082 public:
00083 
00084   MoveGroupImpl(const Options &opt, const boost::shared_ptr<tf::Transformer> &tf, const ros::Duration &wait_for_server) : opt_(opt), tf_(tf)
00085   {
00086     robot_model_ = opt.robot_model_ ? opt.robot_model_ : getSharedRobotModel(opt.robot_description_);
00087     if (!getRobotModel())
00088     {
00089       std::string error = "Unable to construct robot model. Please make sure all needed information is on the parameter server.";
00090       ROS_FATAL_STREAM(error);
00091       throw std::runtime_error(error);
00092     }
00093 
00094     if (!getRobotModel()->hasJointModelGroup(opt.group_name_))
00095     {
00096       std::string error = "Group '" + opt.group_name_ + "' was not found.";
00097       ROS_FATAL_STREAM(error);
00098       throw std::runtime_error(error);
00099     }
00100 
00101     joint_state_target_.reset(new robot_state::RobotState(getRobotModel()));
00102     joint_state_target_->setToDefaultValues();
00103     active_target_ = JOINT;
00104     can_look_ = false;
00105     can_replan_ = false;
00106     replan_delay_ = 2.0;
00107     goal_joint_tolerance_ = 1e-4;
00108     goal_position_tolerance_ = 1e-4; // 0.1 mm
00109     goal_orientation_tolerance_ = 1e-3; // ~0.1 deg
00110     planning_time_ = 5.0;
00111     initializing_constraints_ = false;
00112 
00113     const robot_model::JointModelGroup *joint_model_group = getRobotModel()->getJointModelGroup(opt.group_name_);
00114     if (joint_model_group)
00115     {
00116       if (joint_model_group->isChain())
00117         end_effector_link_ = joint_model_group->getLinkModelNames().back();
00118       pose_reference_frame_ = getRobotModel()->getModelFrame();
00119 
00120       trajectory_event_publisher_ = node_handle_.advertise<std_msgs::String>(trajectory_execution_manager::TrajectoryExecutionManager::EXECUTION_EVENT_TOPIC, 1, false);
00121 
00122       current_state_monitor_ = getSharedStateMonitor(robot_model_, tf_);
00123 
00124       move_action_client_.reset(new actionlib::SimpleActionClient<moveit_msgs::MoveGroupAction>(move_group::MOVE_ACTION, false));
00125       waitForAction(move_action_client_, wait_for_server, move_group::MOVE_ACTION);
00126 
00127       pick_action_client_.reset(new actionlib::SimpleActionClient<moveit_msgs::PickupAction>(move_group::PICKUP_ACTION, false));
00128       waitForAction(pick_action_client_, wait_for_server, move_group::PICKUP_ACTION);
00129 
00130       place_action_client_.reset(new actionlib::SimpleActionClient<moveit_msgs::PlaceAction>(move_group::PLACE_ACTION, false));
00131       waitForAction(place_action_client_, wait_for_server, move_group::PLACE_ACTION);
00132 
00133       execute_service_ = node_handle_.serviceClient<moveit_msgs::ExecuteKnownTrajectory>(move_group::EXECUTE_SERVICE_NAME);
00134       query_service_ = node_handle_.serviceClient<moveit_msgs::QueryPlannerInterfaces>(move_group::QUERY_PLANNERS_SERVICE_NAME);
00135       cartesian_path_service_ = node_handle_.serviceClient<moveit_msgs::GetCartesianPath>(move_group::CARTESIAN_PATH_SERVICE_NAME);
00136 
00137       ROS_INFO_STREAM("Ready to take MoveGroup commands for group " << opt.group_name_ << ".");
00138     }
00139     else
00140       ROS_ERROR("Unable to initialize MoveGroup interface.");
00141   }
00142 
00143   template<typename T>
00144   void waitForAction(const T &action, const ros::Duration &wait_for_server, const std::string &name)
00145   {
00146     ROS_DEBUG("Waiting for MoveGroup action server (%s)...", name.c_str());
00147 
00148     // in case ROS time is published, wait for the time data to arrive
00149     ros::Time start_time = ros::Time::now();
00150     while (start_time == ros::Time::now())
00151     {
00152       ros::WallDuration(0.01).sleep();
00153       ros::spinOnce();
00154     }
00155 
00156     // wait for the server (and spin as needed)
00157     if (wait_for_server == ros::Duration(0, 0))
00158     {
00159       while (node_handle_.ok() && !action->isServerConnected())
00160       {
00161         ros::WallDuration(0.02).sleep();
00162         ros::spinOnce();
00163       }
00164     }
00165     else
00166     {
00167       ros::Time final_time = ros::Time::now() + wait_for_server;
00168       while (node_handle_.ok() && !action->isServerConnected() && final_time > ros::Time::now())
00169       {
00170         ros::WallDuration(0.02).sleep();
00171         ros::spinOnce();
00172       }
00173     }
00174 
00175     if (!action->isServerConnected())
00176       throw std::runtime_error("Unable to connect to action server within allotted time");
00177     else
00178       ROS_DEBUG("Connected to '%s'", name.c_str());
00179   }
00180 
00181   ~MoveGroupImpl()
00182   {
00183     if (constraints_init_thread_)
00184       constraints_init_thread_->join();
00185   }
00186 
00187   const boost::shared_ptr<tf::Transformer>& getTF() const
00188   {
00189     return tf_;
00190   }
00191 
00192   const Options& getOptions() const
00193   {
00194     return opt_;
00195   }
00196 
00197   const robot_model::RobotModelConstPtr& getRobotModel() const
00198   {
00199     return robot_model_;
00200   }
00201 
00202   bool getInterfaceDescription(moveit_msgs::PlannerInterfaceDescription &desc)
00203   {
00204     moveit_msgs::QueryPlannerInterfaces::Request req;
00205     moveit_msgs::QueryPlannerInterfaces::Response res;
00206     if (query_service_.call(req, res))
00207       if (!res.planner_interfaces.empty())
00208       {
00209         desc = res.planner_interfaces.front();
00210         return true;
00211       }
00212     return false;
00213   }
00214 
00215   void setPlannerId(const std::string &planner_id)
00216   {
00217     planner_id_ = planner_id;
00218   }
00219 
00220   robot_state::JointStateGroup* getJointStateTarget()
00221   {
00222     return joint_state_target_->getJointStateGroup(opt_.group_name_);
00223   }
00224 
00225   void setStartState(const robot_state::RobotState &start_state)
00226   {
00227     considered_start_state_.reset(new robot_state::RobotState(start_state));
00228   }
00229 
00230   void setStartStateToCurrentState()
00231   {
00232     considered_start_state_.reset();
00233   }
00234 
00235   void setEndEffectorLink(const std::string &end_effector)
00236   {
00237     end_effector_link_ = end_effector;
00238   }
00239 
00240   void clearPoseTarget(const std::string &end_effector_link)
00241   {
00242     pose_targets_.erase(end_effector_link);
00243   }
00244 
00245   void clearPoseTargets()
00246   {
00247     pose_targets_.clear();
00248   }
00249 
00250   const std::string &getEndEffectorLink() const
00251   {
00252     return end_effector_link_;
00253   }
00254 
00255   const std::string& getEndEffector() const
00256   {
00257     if (!end_effector_link_.empty())
00258     {
00259       const std::vector<std::string> &possible_eefs = getRobotModel()->getJointModelGroup(opt_.group_name_)->getAttachedEndEffectorNames();
00260       for (std::size_t i = 0 ; i < possible_eefs.size() ; ++i)
00261         if (getRobotModel()->getEndEffector(possible_eefs[i])->hasLinkModel(end_effector_link_))
00262           return possible_eefs[i];
00263     }
00264     static std::string empty;
00265     return empty;
00266   }
00267 
00268   bool setPoseTargets(const std::vector<geometry_msgs::PoseStamped> &poses, const std::string &end_effector_link)
00269   {
00270     const std::string &eef = end_effector_link.empty() ? end_effector_link_ : end_effector_link;
00271     if (eef.empty())
00272     {
00273       ROS_ERROR("No end-effector to set the pose for");
00274       return false;
00275     }
00276     else
00277     {
00278       pose_targets_[eef] = poses;
00279       // make sure we don't store an actual stamp, since that will become stale can potentially cause tf errors
00280       std::vector<geometry_msgs::PoseStamped> &stored_poses = pose_targets_[eef];
00281       for (std::size_t i = 0 ; i < stored_poses.size() ; ++i)
00282         stored_poses[i].header.stamp = ros::Time(0);
00283     }
00284     return true;
00285   }
00286 
00287   bool hasPoseTarget(const std::string &end_effector_link) const
00288   {
00289     const std::string &eef = end_effector_link.empty() ? end_effector_link_ : end_effector_link;
00290     return pose_targets_.find(eef) != pose_targets_.end();
00291   }
00292 
00293   const geometry_msgs::PoseStamped& getPoseTarget(const std::string &end_effector_link) const
00294   {
00295     const std::string &eef = end_effector_link.empty() ? end_effector_link_ : end_effector_link;
00296 
00297     // if multiple pose targets are set, return the first one
00298     std::map<std::string, std::vector<geometry_msgs::PoseStamped> >::const_iterator jt = pose_targets_.find(eef);
00299     if (jt != pose_targets_.end())
00300       if (!jt->second.empty())
00301         return jt->second.at(0);
00302 
00303     // or return an error
00304     static const geometry_msgs::PoseStamped unknown;
00305     ROS_ERROR("Pose for end effector '%s' not known.", eef.c_str());
00306     return unknown;
00307   }
00308 
00309   const std::vector<geometry_msgs::PoseStamped>& getPoseTargets(const std::string &end_effector_link) const
00310   {
00311     const std::string &eef = end_effector_link.empty() ? end_effector_link_ : end_effector_link;
00312 
00313     std::map<std::string, std::vector<geometry_msgs::PoseStamped> >::const_iterator jt = pose_targets_.find(eef);
00314     if (jt != pose_targets_.end())
00315       if (!jt->second.empty())
00316         return jt->second;
00317 
00318     // or return an error
00319     static const std::vector<geometry_msgs::PoseStamped> empty;
00320     ROS_ERROR("Poses for end effector '%s' are not known.", eef.c_str());
00321     return empty;
00322   }
00323 
00324   void setPoseReferenceFrame(const std::string &pose_reference_frame)
00325   {
00326     pose_reference_frame_ = pose_reference_frame;
00327   }
00328 
00329   void setSupportSurfaceName(const std::string &support_surface)
00330   {
00331     support_surface_ = support_surface;
00332   }
00333 
00334   const std::string& getPoseReferenceFrame() const
00335   {
00336     return pose_reference_frame_;
00337   }
00338 
00339   void setTargetType(ActiveTargetType type)
00340   {
00341     active_target_ = type;
00342   }
00343 
00344   ActiveTargetType getTargetType() const
00345   {
00346     return active_target_;
00347   }
00348 
00349   bool getCurrentState(robot_state::RobotStatePtr &current_state)
00350   {
00351     if (!current_state_monitor_)
00352     {
00353       ROS_ERROR("Unable to get current robot state");
00354       return false;
00355     }
00356 
00357     // if needed, start the monitor and wait up to 1 second for a full robot state
00358     if (!current_state_monitor_->isActive())
00359       current_state_monitor_->startStateMonitor();
00360 
00361     if (!current_state_monitor_->waitForCurrentState(opt_.group_name_, 1.0))
00362       ROS_WARN("Joint values for monitored state are requested but the full state is not known");
00363 
00364     current_state = current_state_monitor_->getCurrentState();
00365     return true;
00366   }
00367 
00369   bool place(const std::string &object, const std::vector<geometry_msgs::PoseStamped> &poses)
00370   {
00371     std::vector<manipulation_msgs::PlaceLocation> locations;
00372     for (std::size_t i = 0; i < poses.size(); ++i)
00373     {
00374       manipulation_msgs::PlaceLocation location;
00375       location.approach.direction.vector.z = -1.0;
00376       location.retreat.direction.vector.x = -1.0;
00377       location.approach.direction.header.frame_id = getRobotModel()->getModelFrame();
00378       location.retreat.direction.header.frame_id = end_effector_link_;
00379 
00380       location.approach.min_distance = 0.1;
00381       location.approach.desired_distance = 0.2;
00382       location.retreat.min_distance = 0.0;
00383       location.retreat.desired_distance = 0.2;
00384       // location.post_place_posture is filled by the pick&place lib with the getDetachPosture from the AttachedBody
00385 
00386       location.place_pose = poses[i];
00387       locations.push_back(location);
00388     }
00389     ROS_DEBUG("Move group interface has %u place locations", (unsigned int) locations.size());
00390     return place(object, locations);
00391   }
00392 
00393   bool place(const std::string &object, const std::vector<manipulation_msgs::PlaceLocation> &locations)
00394   {
00395     if (!place_action_client_)
00396     {
00397       ROS_ERROR_STREAM("Place action client not found");
00398       return false;
00399     }
00400     if (!place_action_client_->isServerConnected())
00401     {
00402       ROS_ERROR_STREAM("Place action server not connected");
00403       return false;
00404     }
00405     moveit_msgs::PlaceGoal goal;
00406     constructGoal(goal, object);
00407     goal.place_locations = locations;
00408     goal.planning_options.plan_only = false;
00409     place_action_client_->sendGoal(goal);
00410     ROS_DEBUG("Sent place goal with %d locations", (int) goal.place_locations.size());
00411     if (!place_action_client_->waitForResult())
00412     {
00413       ROS_INFO_STREAM("Place action returned early");
00414     }
00415     if (place_action_client_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00416     {
00417       return true;
00418     }
00419     else
00420     {
00421       ROS_WARN_STREAM("Fail: " << place_action_client_->getState().toString() << ": " << place_action_client_->getState().getText());
00422       return false;
00423     }
00424   }
00425 
00426   bool pick(const std::string &object, const std::vector<manipulation_msgs::Grasp> &grasps)
00427   {
00428     if (!pick_action_client_)
00429     {
00430       ROS_ERROR_STREAM("Pick action client not found");
00431       return false;
00432     }
00433     if (!pick_action_client_->isServerConnected())
00434     {
00435       ROS_ERROR_STREAM("Pick action server not connected");
00436       return false;
00437     }
00438     moveit_msgs::PickupGoal goal;
00439     constructGoal(goal, object);
00440     goal.possible_grasps = grasps;
00441     goal.planning_options.plan_only = false;
00442     pick_action_client_->sendGoal(goal);
00443     if (!pick_action_client_->waitForResult())
00444     {
00445       ROS_INFO_STREAM("Pickup action returned early");
00446     }
00447     if (pick_action_client_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00448     {
00449       return true;
00450     }
00451     else
00452     {
00453       ROS_WARN_STREAM("Fail: " << pick_action_client_->getState().toString() << ": " << pick_action_client_->getState().getText());
00454       return false;
00455     }
00456   }
00457 
00458   bool plan(Plan &plan)
00459   {
00460     if (!move_action_client_)
00461       return false;
00462     if (!move_action_client_->isServerConnected())
00463       return false;
00464 
00465     moveit_msgs::MoveGroupGoal goal;
00466     constructGoal(goal);
00467     goal.planning_options.plan_only = true;
00468     goal.planning_options.look_around = false;
00469     goal.planning_options.replan = false;
00470     move_action_client_->sendGoal(goal);
00471     if (!move_action_client_->waitForResult())
00472     {
00473       ROS_INFO_STREAM("MoveGroup action returned early");
00474     }
00475     if (move_action_client_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00476     {
00477       plan.trajectory_ = move_action_client_->getResult()->planned_trajectory;
00478       plan.start_state_ = move_action_client_->getResult()->trajectory_start;
00479       return true;
00480     }
00481     else
00482     {
00483       ROS_WARN_STREAM("Fail: " << move_action_client_->getState().toString() << ": " << move_action_client_->getState().getText());
00484       return false;
00485     }
00486   }
00487 
00488   bool move(bool wait)
00489   {
00490     if (!move_action_client_)
00491       return false;
00492     if (!move_action_client_->isServerConnected())
00493       return false;
00494 
00495     moveit_msgs::MoveGroupGoal goal;
00496     constructGoal(goal);
00497     goal.planning_options.plan_only = false;
00498     goal.planning_options.look_around = can_look_;
00499     goal.planning_options.replan = can_replan_;
00500     goal.planning_options.replan_delay = replan_delay_;
00501 
00502     move_action_client_->sendGoal(goal);
00503     if (!wait)
00504       return true;
00505 
00506     if (!move_action_client_->waitForResult())
00507     {
00508       ROS_INFO_STREAM("MoveGroup action returned early");
00509     }
00510 
00511     if (move_action_client_->getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
00512       return true;
00513     else
00514     {
00515       ROS_INFO_STREAM(move_action_client_->getState().toString() << ": " << move_action_client_->getState().getText());
00516       return false;
00517     }
00518   }
00519 
00520   bool execute(const Plan &plan, bool wait)
00521   {
00522     moveit_msgs::ExecuteKnownTrajectory::Request req;
00523     moveit_msgs::ExecuteKnownTrajectory::Response res;
00524     req.trajectory = plan.trajectory_;
00525     req.wait_for_execution = wait;
00526     if (execute_service_.call(req, res))
00527       return res.error_code.val == moveit_msgs::MoveItErrorCodes::SUCCESS;
00528     else
00529       return false;
00530   }
00531 
00532   double computeCartesianPath(const std::vector<geometry_msgs::Pose> &waypoints, double step, double jump_threshold,
00533                   moveit_msgs::RobotTrajectory &msg, bool avoid_collisions)
00534   {
00535     moveit_msgs::GetCartesianPath::Request req;
00536     moveit_msgs::GetCartesianPath::Response res;
00537 
00538     if (considered_start_state_)
00539       robot_state::robotStateToRobotStateMsg(*considered_start_state_, req.start_state);
00540     req.group_name = opt_.group_name_;
00541     req.header.frame_id = getPoseReferenceFrame();
00542     req.header.stamp = ros::Time::now();
00543     req.waypoints = waypoints;
00544     req.max_step = step;
00545     req.jump_threshold = jump_threshold;
00546     req.avoid_collisions = avoid_collisions;
00547 
00548     if (cartesian_path_service_.call(req, res))
00549     {
00550       if (res.error_code.val == moveit_msgs::MoveItErrorCodes::SUCCESS)
00551       {
00552     msg = res.solution;
00553     return res.fraction;
00554       }
00555       else
00556     return -1.0;
00557     }
00558     else
00559       return -1.0;
00560   }
00561 
00562   void stop()
00563   {
00564     if (trajectory_event_publisher_)
00565     {
00566       std_msgs::String event;
00567       event.data = "stop";
00568       trajectory_event_publisher_.publish(event);
00569     }
00570   }
00571 
00572   double getGoalPositionTolerance() const
00573   {
00574     return goal_position_tolerance_;
00575   }
00576 
00577   double getGoalOrientationTolerance() const
00578   {
00579     return goal_orientation_tolerance_;
00580   }
00581 
00582   double getGoalJointTolerance() const
00583   {
00584     return goal_joint_tolerance_;
00585   }
00586 
00587   void setGoalJointTolerance(double tolerance)
00588   {
00589     goal_joint_tolerance_ = tolerance;
00590   }
00591 
00592   void setGoalPositionTolerance(double tolerance)
00593   {
00594     goal_position_tolerance_ = tolerance;
00595   }
00596 
00597   void setGoalOrientationTolerance(double tolerance)
00598   {
00599     goal_orientation_tolerance_ = tolerance;
00600   }
00601 
00602   void setPlanningTime(double seconds)
00603   {
00604     if (seconds > 0.0)
00605       planning_time_ = seconds;
00606   }
00607 
00608   double getPlanningTime() const
00609   {
00610     return planning_time_;
00611   }
00612 
00613   void allowLooking(bool flag)
00614   {
00615     can_look_ = flag;
00616     ROS_INFO("Looking around: %s", can_look_ ? "yes" : "no");
00617   }
00618 
00619   void allowReplanning(bool flag)
00620   {
00621     can_replan_ = flag;
00622     ROS_INFO("Replanning: %s", can_replan_ ? "yes" : "no");
00623   }
00624 
00625   void setReplanningDelay(double delay)
00626   {
00627     if (delay >= 0.0)
00628       replan_delay_ = delay;
00629   }
00630 
00631   double getReplanningDelay() const
00632   {
00633     return replan_delay_;
00634   }
00635 
00636   void constructGoal(moveit_msgs::MoveGroupGoal &goal_out)
00637   {
00638     moveit_msgs::MoveGroupGoal goal;
00639     goal.request.group_name = opt_.group_name_;
00640     goal.request.num_planning_attempts = 1;
00641     goal.request.allowed_planning_time = planning_time_;
00642     goal.request.planner_id = planner_id_;
00643     goal.request.workspace_parameters = workspace_parameters_;
00644 
00645     if (considered_start_state_)
00646       robot_state::robotStateToRobotStateMsg(*considered_start_state_, goal.request.start_state);
00647 
00648     if (active_target_ == JOINT)
00649     {
00650       goal.request.goal_constraints.resize(1);
00651       goal.request.goal_constraints[0] = kinematic_constraints::constructGoalConstraints(getJointStateTarget(), goal_joint_tolerance_);
00652     }
00653     else
00654       if (active_target_ == POSE || active_target_ == POSITION || active_target_ == ORIENTATION)
00655       {
00656         // find out how many goals are specified
00657         std::size_t goal_count = 0;
00658         for (std::map<std::string, std::vector<geometry_msgs::PoseStamped> >::const_iterator it = pose_targets_.begin() ;
00659              it != pose_targets_.end() ; ++it)
00660           goal_count = std::max(goal_count, it->second.size());
00661 
00662         // start filling the goals;
00663         // each end effector has a number of possible poses (K) as valid goals
00664         // but there could be multiple end effectors specified, so we want each end effector
00665         // to reach the goal that corresponds to the goals of the other end effectors
00666         goal.request.goal_constraints.resize(goal_count);
00667 
00668         for (std::map<std::string, std::vector<geometry_msgs::PoseStamped> >::const_iterator it = pose_targets_.begin() ;
00669              it != pose_targets_.end() ; ++it)
00670         {
00671           for (std::size_t i = 0 ; i < it->second.size() ; ++i)
00672           {
00673             moveit_msgs::Constraints c = kinematic_constraints::constructGoalConstraints(it->first, it->second[i], goal_position_tolerance_, goal_orientation_tolerance_);
00674             if (active_target_ == ORIENTATION)
00675               c.position_constraints.clear();
00676             if (active_target_ == POSITION)
00677               c.orientation_constraints.clear();
00678             goal.request.goal_constraints[i] = kinematic_constraints::mergeConstraints(goal.request.goal_constraints[i], c);
00679           }
00680         }
00681       }
00682       else
00683         ROS_ERROR("Unable to construct goal representation");
00684 
00685     if (path_constraints_)
00686       goal.request.path_constraints = *path_constraints_;
00687     goal_out = goal;
00688   }
00689 
00690   void constructGoal(moveit_msgs::PickupGoal &goal_out, const std::string &object)
00691   {
00692     moveit_msgs::PickupGoal goal;
00693     goal.target_name = object;
00694     goal.group_name = opt_.group_name_;
00695     goal.end_effector = getEndEffector();
00696     goal.allowed_planning_time = planning_time_;
00697     goal.support_surface_name = support_surface_;
00698     goal.planner_id = planner_id_;
00699 
00700     if (path_constraints_)
00701       goal.path_constraints = *path_constraints_;
00702 
00703     goal_out = goal;
00704   }
00705 
00706   void constructGoal(moveit_msgs::PlaceGoal &goal_out, const std::string &object)
00707   {
00708     moveit_msgs::PlaceGoal goal;
00709     goal.attached_object_name = object;
00710     goal.group_name = opt_.group_name_;
00711     goal.allowed_planning_time = planning_time_;
00712     goal.support_surface_name = support_surface_;
00713     goal.planner_id = planner_id_;
00714 
00715     if (path_constraints_)
00716       goal.path_constraints = *path_constraints_;
00717 
00718     goal_out = goal;
00719   }
00720 
00721   void setPathConstraints(const moveit_msgs::Constraints &constraint)
00722   {
00723     path_constraints_.reset(new moveit_msgs::Constraints(constraint));
00724   }
00725 
00726   bool setPathConstraints(const std::string &constraint)
00727   {
00728     if (constraints_storage_)
00729     {
00730       moveit_warehouse::ConstraintsWithMetadata msg_m;
00731       if (constraints_storage_->getConstraints(msg_m, constraint, robot_model_->getName(), opt_.group_name_))
00732       {
00733         path_constraints_.reset(new moveit_msgs::Constraints(static_cast<moveit_msgs::Constraints>(*msg_m)));
00734     return true;
00735       }
00736       else
00737         return false;
00738     }
00739     else
00740       return false;
00741   }
00742 
00743   void clearPathConstraints()
00744   {
00745     path_constraints_.reset();
00746   }
00747 
00748   std::vector<std::string> getKnownConstraints() const
00749   {
00750     while (initializing_constraints_)
00751     {
00752       static ros::WallDuration d(0.01);
00753       d.sleep();
00754     }
00755 
00756     std::vector<std::string> c;
00757     if (constraints_storage_)
00758       constraints_storage_->getKnownConstraints(c, robot_model_->getName(), opt_.group_name_);
00759 
00760     return c;
00761   }
00762 
00763   void initializeConstraintsStorage(const std::string &host, unsigned int port)
00764   {
00765     initializing_constraints_ = true;
00766     if (constraints_init_thread_)
00767       constraints_init_thread_->join();
00768     constraints_init_thread_.reset(new boost::thread(boost::bind(&MoveGroupImpl::initializeConstraintsStorageThread, this, host, port)));
00769   }
00770 
00771   void setWorkspace(double minx, double miny, double minz, double maxx, double maxy, double maxz)
00772   {
00773     workspace_parameters_.header.frame_id = getRobotModel()->getModelFrame();
00774     workspace_parameters_.header.stamp = ros::Time::now();
00775     workspace_parameters_.min_corner.x = minx;
00776     workspace_parameters_.min_corner.y = miny;
00777     workspace_parameters_.min_corner.z = minz;
00778     workspace_parameters_.max_corner.x = maxx;
00779     workspace_parameters_.max_corner.y = maxy;
00780     workspace_parameters_.max_corner.z = maxz;
00781   }
00782 
00783 private:
00784 
00785   void initializeConstraintsStorageThread(const std::string &host, unsigned int port)
00786   {
00787     try
00788     {
00789       constraints_storage_.reset(new moveit_warehouse::ConstraintsStorage(host, port));
00790       ROS_DEBUG("Connected to constraints database");
00791     }
00792     catch(std::runtime_error &ex)
00793     {
00794       ROS_DEBUG("%s", ex.what());
00795     }
00796     initializing_constraints_ = false;
00797   }
00798 
00799   Options opt_;
00800   ros::NodeHandle node_handle_;
00801   boost::shared_ptr<tf::Transformer> tf_;
00802   robot_model::RobotModelConstPtr robot_model_;
00803   planning_scene_monitor::CurrentStateMonitorPtr current_state_monitor_;
00804   boost::scoped_ptr<actionlib::SimpleActionClient<moveit_msgs::MoveGroupAction> > move_action_client_;
00805   boost::scoped_ptr<actionlib::SimpleActionClient<moveit_msgs::PickupAction> > pick_action_client_;
00806   boost::scoped_ptr<actionlib::SimpleActionClient<moveit_msgs::PlaceAction> > place_action_client_;
00807 
00808   // general planning params
00809   robot_state::RobotStatePtr considered_start_state_;
00810   moveit_msgs::WorkspaceParameters workspace_parameters_;
00811   double planning_time_;
00812   std::string planner_id_;
00813   double goal_joint_tolerance_;
00814   double goal_position_tolerance_;
00815   double goal_orientation_tolerance_;
00816   bool can_look_;
00817   bool can_replan_;
00818   double replan_delay_;
00819 
00820   // joint state goal
00821   robot_state::RobotStatePtr joint_state_target_;
00822 
00823   // pose goal;
00824   // for each link we have a set of possible goal locations;
00825   std::map<std::string, std::vector<geometry_msgs::PoseStamped> > pose_targets_;
00826 
00827   // common properties for goals
00828   ActiveTargetType active_target_;
00829   boost::scoped_ptr<moveit_msgs::Constraints> path_constraints_;
00830   std::string end_effector_link_;
00831   std::string pose_reference_frame_;
00832   std::string support_surface_;
00833 
00834   // ROS communication
00835   ros::Publisher trajectory_event_publisher_;
00836   ros::ServiceClient execute_service_;
00837   ros::ServiceClient query_service_;
00838   ros::ServiceClient cartesian_path_service_;
00839   boost::scoped_ptr<moveit_warehouse::ConstraintsStorage> constraints_storage_;
00840   boost::scoped_ptr<boost::thread> constraints_init_thread_;
00841   bool initializing_constraints_;
00842 };
00843 
00844 MoveGroup::MoveGroup(const std::string &group_name, const boost::shared_ptr<tf::Transformer> &tf, const ros::Duration &wait_for_server)
00845 {
00846   if (!ros::ok())
00847     throw std::runtime_error("ROS does not seem to be running");
00848   impl_ = new MoveGroupImpl(Options(group_name), tf ? tf : getSharedTF(), wait_for_server);
00849 }
00850 
00851 MoveGroup::MoveGroup(const Options &opt, const boost::shared_ptr<tf::Transformer> &tf, const ros::Duration &wait_for_server)
00852 {
00853   impl_ = new MoveGroupImpl(opt, tf ? tf : getSharedTF(), wait_for_server);
00854 }
00855 
00856 MoveGroup::~MoveGroup()
00857 {
00858   delete impl_;
00859 }
00860 
00861 const std::string& MoveGroup::getName() const
00862 {
00863   return impl_->getOptions().group_name_;
00864 }
00865 
00866 bool MoveGroup::getInterfaceDescription(moveit_msgs::PlannerInterfaceDescription &desc)
00867 {
00868   return impl_->getInterfaceDescription(desc);
00869 }
00870 
00871 void MoveGroup::setPlannerId(const std::string &planner_id)
00872 {
00873   impl_->setPlannerId(planner_id);
00874 }
00875 
00876 bool MoveGroup::asyncMove()
00877 {
00878   return impl_->move(false);
00879 }
00880 
00881 bool MoveGroup::move()
00882 {
00883   return impl_->move(true);
00884 }
00885 
00886 bool MoveGroup::asyncExecute(const Plan &plan)
00887 {
00888   return impl_->execute(plan, false);
00889 }
00890 
00891 bool MoveGroup::execute(const Plan &plan)
00892 {
00893   return impl_->execute(plan, true);
00894 }
00895 
00896 bool MoveGroup::plan(Plan &plan)
00897 {
00898   return impl_->plan(plan);
00899 }
00900 
00901 bool MoveGroup::pick(const std::string &object)
00902 {
00903   return impl_->pick(object, std::vector<manipulation_msgs::Grasp>());
00904 }
00905 
00906 bool MoveGroup::pick(const std::string &object, const manipulation_msgs::Grasp &grasp)
00907 {
00908   return impl_->pick(object, std::vector<manipulation_msgs::Grasp>(1, grasp));
00909 }
00910 
00911 bool MoveGroup::pick(const std::string &object, const std::vector<manipulation_msgs::Grasp> &grasps)
00912 {
00913   return impl_->pick(object, grasps);
00914 }
00915 
00916 bool MoveGroup::place(const std::string &object)
00917 {
00918   return impl_->place(object, std::vector<manipulation_msgs::PlaceLocation>());
00919 }
00920 
00921 bool MoveGroup::place(const std::string &object, const std::vector<manipulation_msgs::PlaceLocation> &locations)
00922 {
00923   return impl_->place(object, locations);
00924 }
00925 
00926 bool MoveGroup::place(const std::string &object, const std::vector<geometry_msgs::PoseStamped> &poses)
00927 {
00928   return impl_->place(object, poses);
00929 }
00930 
00931 bool MoveGroup::place(const std::string &object, const geometry_msgs::PoseStamped &pose)
00932 {
00933   return impl_->place(object, std::vector<geometry_msgs::PoseStamped>(1, pose));
00934 }
00935 
00936 double MoveGroup::computeCartesianPath(const std::vector<geometry_msgs::Pose> &waypoints, double eef_step, double jump_threshold,
00937                        moveit_msgs::RobotTrajectory &trajectory, bool avoid_collisions)
00938 {
00939   return impl_->computeCartesianPath(waypoints, eef_step, jump_threshold, trajectory, avoid_collisions);
00940 }
00941 
00942 void MoveGroup::stop()
00943 {
00944   impl_->stop();
00945 }
00946 
00947 void MoveGroup::setStartState(const robot_state::RobotState &start_state)
00948 {
00949   impl_->setStartState(start_state);
00950 }
00951 
00952 void MoveGroup::setStartStateToCurrentState()
00953 {
00954   impl_->setStartStateToCurrentState();
00955 }
00956 
00957 void MoveGroup::setRandomTarget()
00958 {
00959   impl_->getJointStateTarget()->setToRandomValues();
00960   impl_->setTargetType(JOINT);
00961 }
00962 
00963 bool MoveGroup::setNamedTarget(const std::string &name)
00964 {
00965   std::map<std::string, std::vector<double> >::const_iterator it = remembered_joint_values_.find(name);
00966   if (it != remembered_joint_values_.end())
00967   {
00968     return setJointValueTarget(it->second);
00969   }
00970   else
00971   {
00972     if (impl_->getJointStateTarget()->setToDefaultState(name))
00973     {
00974       impl_->setTargetType(JOINT);
00975       return true;
00976     }
00977     return false;
00978   }
00979 }
00980 
00981 bool MoveGroup::setJointValueTarget(const std::vector<double> &joint_values)
00982 {
00983   impl_->setTargetType(JOINT);
00984   if (impl_->getJointStateTarget()->setVariableValues(joint_values))
00985     return impl_->getJointStateTarget()->satisfiesBounds(impl_->getGoalJointTolerance());
00986   else
00987     return false;
00988 }
00989 
00990 bool MoveGroup::setJointValueTarget(const std::map<std::string, double> &joint_values)
00991 {
00992   impl_->setTargetType(JOINT);
00993   impl_->getJointStateTarget()->setVariableValues(joint_values);
00994   return impl_->getJointStateTarget()->satisfiesBounds(impl_->getGoalJointTolerance());
00995 }
00996 
00997 bool MoveGroup::setJointValueTarget(const robot_state::RobotState &kinematic_state)
00998 {
00999   return setJointValueTarget(*kinematic_state.getJointStateGroup(getName()));
01000 }
01001 
01002 bool MoveGroup::setJointValueTarget(const robot_state::JointStateGroup &joint_state_group)
01003 {
01004   std::map<std::string, double> variable_values;
01005   joint_state_group.getVariableValues(variable_values);
01006   return setJointValueTarget(variable_values);
01007 }
01008 
01009 bool MoveGroup::setJointValueTarget(const robot_state::JointState &joint_state)
01010 {
01011   return setJointValueTarget(joint_state.getName(), joint_state.getVariableValues());
01012 }
01013 
01014 bool MoveGroup::setJointValueTarget(const std::string &joint_name, double value)
01015 {
01016   std::vector<double> values(1, value);
01017   return setJointValueTarget(joint_name, values);
01018 }
01019 
01020 bool MoveGroup::setJointValueTarget(const std::string &joint_name, const std::vector<double> &values)
01021 {
01022   impl_->setTargetType(JOINT);
01023   robot_state::JointState *joint_state = impl_->getJointStateTarget()->getJointState(joint_name);
01024   if (joint_state)
01025     if (joint_state->setVariableValues(values))
01026       return true;
01027   return false;
01028 }
01029 
01030 bool MoveGroup::setJointValueTarget(const sensor_msgs::JointState &state)
01031 {
01032   impl_->setTargetType(JOINT);
01033   impl_->getJointStateTarget()->setVariableValues(state);
01034   return impl_->getJointStateTarget()->satisfiesBounds(impl_->getGoalJointTolerance());
01035 }
01036 
01037 const robot_state::JointStateGroup& MoveGroup::getJointValueTarget() const
01038 {
01039   return *impl_->getJointStateTarget();
01040 }
01041 
01042 const std::string& MoveGroup::getEndEffectorLink() const
01043 {
01044   return impl_->getEndEffectorLink();
01045 }
01046 
01047 const std::string& MoveGroup::getEndEffector() const
01048 {
01049   return impl_->getEndEffector();
01050 }
01051 
01052 bool MoveGroup::setEndEffectorLink(const std::string &link_name)
01053 {
01054   if (impl_->getEndEffectorLink().empty() || link_name.empty())
01055     return false;
01056   impl_->setEndEffectorLink(link_name);
01057   impl_->setTargetType(POSE);
01058   return true;
01059 }
01060 
01061 bool MoveGroup::setEndEffector(const std::string &eef_name)
01062 {
01063   const robot_model::JointModelGroup *jmg = impl_->getRobotModel()->getEndEffector(eef_name);
01064   if (jmg)
01065     return setEndEffectorLink(jmg->getEndEffectorParentGroup().second);
01066   return false;
01067 }
01068 
01069 void MoveGroup::clearPoseTarget(const std::string &end_effector_link)
01070 {
01071   impl_->clearPoseTarget(end_effector_link);
01072 }
01073 
01074 void MoveGroup::clearPoseTargets()
01075 {
01076   impl_->clearPoseTargets();
01077 }
01078 
01079 bool MoveGroup::setPoseTarget(const Eigen::Affine3d &pose, const std::string &end_effector_link)
01080 {
01081   std::vector<geometry_msgs::PoseStamped> pose_msg(1);
01082   tf::poseEigenToMsg(pose, pose_msg[0].pose);
01083   pose_msg[0].header.frame_id = getPoseReferenceFrame();
01084   pose_msg[0].header.stamp = ros::Time::now();
01085   return setPoseTargets(pose_msg, end_effector_link);
01086 }
01087 
01088 bool MoveGroup::setPoseTarget(const geometry_msgs::Pose &target, const std::string &end_effector_link)
01089 {
01090   std::vector<geometry_msgs::PoseStamped> pose_msg(1);
01091   pose_msg[0].pose = target;
01092   pose_msg[0].header.frame_id = getPoseReferenceFrame();
01093   pose_msg[0].header.stamp = ros::Time::now();
01094   return setPoseTargets(pose_msg, end_effector_link);
01095 }
01096 
01097 bool MoveGroup::setPoseTarget(const geometry_msgs::PoseStamped &target, const std::string &end_effector_link)
01098 {
01099   std::vector<geometry_msgs::PoseStamped> targets(1, target);
01100   return setPoseTargets(targets, end_effector_link);
01101 }
01102 
01103 bool MoveGroup::setPoseTargets(const EigenSTL::vector_Affine3d &target, const std::string &end_effector_link)
01104 {
01105   std::vector<geometry_msgs::PoseStamped> pose_out(target.size());
01106   ros::Time tm = ros::Time::now();
01107   const std::string &frame_id = getPoseReferenceFrame();
01108   for (std::size_t i = 0 ; i < target.size() ; ++i)
01109   {
01110     tf::poseEigenToMsg(target[i], pose_out[i].pose);
01111     pose_out[i].header.stamp = tm;
01112     pose_out[i].header.frame_id = frame_id;
01113   }
01114   return setPoseTargets(pose_out, end_effector_link);
01115 }
01116 
01117 bool MoveGroup::setPoseTargets(const std::vector<geometry_msgs::Pose> &target, const std::string &end_effector_link)
01118 {
01119   std::vector<geometry_msgs::PoseStamped> target_stamped(target.size());
01120   ros::Time tm = ros::Time::now();
01121   const std::string &frame_id = getPoseReferenceFrame();
01122   for (std::size_t i = 0 ; i < target.size() ; ++i)
01123   {
01124     target_stamped[i].pose = target[i];
01125     target_stamped[i].header.stamp = tm;
01126     target_stamped[i].header.frame_id = frame_id;
01127   }
01128   return setPoseTargets(target_stamped, end_effector_link);
01129 }
01130 
01131 bool MoveGroup::setPoseTargets(const std::vector<geometry_msgs::PoseStamped> &target, const std::string &end_effector_link)
01132 {
01133   if (target.empty())
01134   {
01135     ROS_ERROR("No pose specified as goal target");
01136     return false;
01137   }
01138   else
01139   {
01140     impl_->setTargetType(POSE);
01141     return impl_->setPoseTargets(target, end_effector_link);
01142   }
01143 }
01144 
01145 const geometry_msgs::PoseStamped& MoveGroup::getPoseTarget(const std::string &end_effector_link) const
01146 {
01147   return impl_->getPoseTarget(end_effector_link);
01148 }
01149 
01150 const std::vector<geometry_msgs::PoseStamped>& MoveGroup::getPoseTargets(const std::string &end_effector_link) const
01151 {
01152   return impl_->getPoseTargets(end_effector_link);
01153 }
01154 
01155 namespace
01156 {
01157 inline void transformPose(const tf::Transformer& tf, const std::string &desired_frame, geometry_msgs::PoseStamped &target)
01158 {
01159   if (desired_frame != target.header.frame_id)
01160   {
01161     tf::Pose pose;
01162     tf::poseMsgToTF(target.pose, pose);
01163     tf::Stamped<tf::Pose> stamped_target(pose, target.header.stamp, target.header.frame_id);
01164     tf::Stamped<tf::Pose> stamped_target_out;
01165     tf.transformPose(desired_frame, stamped_target, stamped_target_out);
01166     target.header.frame_id = stamped_target_out.frame_id_;
01167     //    target.header.stamp = stamped_target_out.stamp_; // we leave the stamp to ros::Time(0) on purpose
01168     tf::poseTFToMsg(stamped_target_out, target.pose);
01169   }
01170 }
01171 }
01172 
01173 bool MoveGroup::setPositionTarget(double x, double y, double z, const std::string &end_effector_link)
01174 {
01175   geometry_msgs::PoseStamped target;
01176   if (impl_->hasPoseTarget(end_effector_link))
01177   {
01178     target = getPoseTarget(end_effector_link);
01179     transformPose(*impl_->getTF(), impl_->getPoseReferenceFrame(), target);
01180   }
01181   else
01182   {
01183     target.pose.orientation.x = 0.0;
01184     target.pose.orientation.y = 0.0;
01185     target.pose.orientation.z = 0.0;
01186     target.pose.orientation.w = 1.0;
01187     target.header.frame_id = impl_->getPoseReferenceFrame();
01188   }
01189 
01190   target.pose.position.x = x;
01191   target.pose.position.y = y;
01192   target.pose.position.z = z;
01193   bool result = setPoseTarget(target, end_effector_link);
01194   impl_->setTargetType(POSITION);
01195   return result;
01196 }
01197 
01198 bool MoveGroup::setRPYTarget(double r, double p, double y, const std::string &end_effector_link)
01199 {
01200   geometry_msgs::PoseStamped target;
01201   if (impl_->hasPoseTarget(end_effector_link))
01202   {
01203     target = getPoseTarget(end_effector_link);
01204     transformPose(*impl_->getTF(), impl_->getPoseReferenceFrame(), target);
01205   }
01206   else
01207   {
01208     target.pose.position.x = 0.0;
01209     target.pose.position.y = 0.0;
01210     target.pose.position.z = 0.0;
01211     target.header.frame_id = impl_->getPoseReferenceFrame();
01212   }
01213 
01214   tf::quaternionTFToMsg(tf::createQuaternionFromRPY(r, p, y), target.pose.orientation);
01215   bool result = setPoseTarget(target, end_effector_link);
01216   impl_->setTargetType(ORIENTATION);
01217   return result;
01218 }
01219 
01220 bool MoveGroup::setOrientationTarget(double x, double y, double z, double w, const std::string &end_effector_link)
01221 {
01222   geometry_msgs::PoseStamped target;
01223   if (impl_->hasPoseTarget(end_effector_link))
01224   {
01225     target = getPoseTarget(end_effector_link);
01226     transformPose(*impl_->getTF(), impl_->getPoseReferenceFrame(), target);
01227   }
01228   else
01229   {
01230     target.pose.position.x = 0.0;
01231     target.pose.position.y = 0.0;
01232     target.pose.position.z = 0.0;
01233     target.header.frame_id = impl_->getPoseReferenceFrame();
01234   }
01235 
01236   target.pose.orientation.x = x;
01237   target.pose.orientation.y = y;
01238   target.pose.orientation.z = z;
01239   target.pose.orientation.w = w;
01240   bool result = setPoseTarget(target, end_effector_link);
01241   impl_->setTargetType(ORIENTATION);
01242   return result;
01243 }
01244 
01245 void MoveGroup::setPoseReferenceFrame(const std::string &pose_reference_frame)
01246 {
01247   impl_->setPoseReferenceFrame(pose_reference_frame);
01248 }
01249 
01250 const std::string& MoveGroup::getPoseReferenceFrame() const
01251 {
01252   return impl_->getPoseReferenceFrame();
01253 }
01254 
01255 double MoveGroup::getGoalJointTolerance() const
01256 {
01257   return impl_->getGoalJointTolerance();
01258 }
01259 
01260 double MoveGroup::getGoalPositionTolerance() const
01261 {
01262   return impl_->getGoalPositionTolerance();
01263 }
01264 
01265 double MoveGroup::getGoalOrientationTolerance() const
01266 {
01267   return impl_->getGoalOrientationTolerance();
01268 }
01269 
01270 void MoveGroup::setGoalTolerance(double tolerance)
01271 {
01272   setGoalJointTolerance(tolerance);
01273   setGoalPositionTolerance(tolerance);
01274   setGoalOrientationTolerance(tolerance);
01275 }
01276 
01277 void MoveGroup::setGoalJointTolerance(double tolerance)
01278 {
01279   impl_->setGoalJointTolerance(tolerance);
01280 }
01281 
01282 void MoveGroup::setGoalPositionTolerance(double tolerance)
01283 {
01284   impl_->setGoalPositionTolerance(tolerance);
01285 }
01286 
01287 void MoveGroup::setGoalOrientationTolerance(double tolerance)
01288 {
01289   impl_->setGoalOrientationTolerance(tolerance);
01290 }
01291 
01292 void MoveGroup::rememberJointValues(const std::string &name)
01293 {
01294   rememberJointValues(name, getCurrentJointValues());
01295 }
01296 
01297 std::vector<double> MoveGroup::getCurrentJointValues()
01298 {
01299   robot_state::RobotStatePtr current_state;
01300   std::vector<double> values;
01301   if (impl_->getCurrentState(current_state))
01302     current_state->getJointStateGroup(getName())->getVariableValues(values);
01303   return values;
01304 }
01305 
01306 std::vector<double> MoveGroup::getRandomJointValues()
01307 {
01308   std::vector<double> backup;
01309   impl_->getJointStateTarget()->getVariableValues(backup);
01310 
01311   impl_->getJointStateTarget()->setToRandomValues();
01312   std::vector<double> r;
01313   impl_->getJointStateTarget()->getVariableValues(r);
01314 
01315   impl_->getJointStateTarget()->setVariableValues(backup);
01316   return r;
01317 }
01318 
01319 geometry_msgs::PoseStamped MoveGroup::getRandomPose(const std::string &end_effector_link)
01320 {
01321   const std::string &eef = end_effector_link.empty() ? getEndEffectorLink() : end_effector_link;
01322   Eigen::Affine3d pose;
01323   pose.setIdentity();
01324   if (eef.empty())
01325     ROS_ERROR("No end-effector specified");
01326   else
01327   {
01328     robot_state::RobotStatePtr current_state;
01329     if (impl_->getCurrentState(current_state))
01330     {
01331       current_state->getJointStateGroup(getName())->setToRandomValues();
01332       const robot_state::LinkState *ls = current_state->getLinkState(eef);
01333       if (ls)
01334         pose = ls->getGlobalLinkTransform();
01335     }
01336   }
01337   geometry_msgs::PoseStamped pose_msg;
01338   pose_msg.header.stamp = ros::Time::now();
01339   pose_msg.header.frame_id = impl_->getRobotModel()->getModelFrame();
01340   tf::poseEigenToMsg(pose, pose_msg.pose);
01341   return pose_msg;
01342 }
01343 
01344 geometry_msgs::PoseStamped MoveGroup::getCurrentPose(const std::string &end_effector_link)
01345 {
01346   const std::string &eef = end_effector_link.empty() ? getEndEffectorLink() : end_effector_link;
01347   Eigen::Affine3d pose;
01348   pose.setIdentity();
01349   if (eef.empty())
01350     ROS_ERROR("No end-effector specified");
01351   else
01352   {
01353     robot_state::RobotStatePtr current_state;
01354     if (impl_->getCurrentState(current_state))
01355     {
01356       const robot_state::LinkState *ls = current_state->getLinkState(eef);
01357       if (ls)
01358         pose = ls->getGlobalLinkTransform();
01359     }
01360   }
01361   geometry_msgs::PoseStamped pose_msg;
01362   pose_msg.header.stamp = ros::Time::now();
01363   pose_msg.header.frame_id = impl_->getRobotModel()->getModelFrame();
01364   tf::poseEigenToMsg(pose, pose_msg.pose);
01365   return pose_msg;
01366 }
01367 
01368 std::vector<double> MoveGroup::getCurrentRPY(const std::string &end_effector_link)
01369 {
01370   std::vector<double> result;
01371   const std::string &eef = end_effector_link.empty() ? getEndEffectorLink() : end_effector_link;
01372   if (eef.empty())
01373     ROS_ERROR("No end-effector specified");
01374   else
01375   {
01376     robot_state::RobotStatePtr current_state;
01377     if (impl_->getCurrentState(current_state))
01378     {
01379       const robot_state::LinkState *ls = current_state->getLinkState(eef);
01380       if (ls)
01381       {
01382     result.resize(3);
01383     tf::Matrix3x3 ptf;
01384     tf::matrixEigenToTF(ls->getGlobalLinkTransform().rotation(), ptf);
01385     tfScalar pitch, roll, yaw;
01386     ptf.getRPY(roll, pitch, yaw);
01387     result[0] = roll;
01388     result[1] = pitch;
01389     result[2] = yaw;
01390       }
01391     }
01392   }
01393   return result;
01394 }
01395 
01396 const std::vector<std::string>& MoveGroup::getJoints() const
01397 {
01398   return impl_->getJointStateTarget()->getJointModelGroup()->getJointModelNames();
01399 }
01400 
01401 unsigned int MoveGroup::getVariableCount() const
01402 {
01403   return impl_->getJointStateTarget()->getJointModelGroup()->getVariableCount();
01404 }
01405 
01406 robot_state::RobotStatePtr MoveGroup::getCurrentState()
01407 {
01408   robot_state::RobotStatePtr current_state;
01409   impl_->getCurrentState(current_state);
01410   return current_state;
01411 }
01412 
01413 void MoveGroup::rememberJointValues(const std::string &name, const std::vector<double> &values)
01414 {
01415   remembered_joint_values_[name] = values;
01416 }
01417 
01418 void MoveGroup::forgetJointValues(const std::string &name)
01419 {
01420   remembered_joint_values_.erase(name);
01421 }
01422 
01423 void MoveGroup::allowLooking(bool flag)
01424 {
01425   impl_->allowLooking(flag);
01426 }
01427 
01428 void MoveGroup::allowReplanning(bool flag)
01429 {
01430   impl_->allowReplanning(flag);
01431 }
01432 
01433 std::vector<std::string> MoveGroup::getKnownConstraints() const
01434 {
01435   return impl_->getKnownConstraints();
01436 }
01437 
01438 bool MoveGroup::setPathConstraints(const std::string &constraint)
01439 {
01440   return impl_->setPathConstraints(constraint);
01441 }
01442 
01443 void MoveGroup::setPathConstraints(const moveit_msgs::Constraints &constraint)
01444 {
01445   impl_->setPathConstraints(constraint);
01446 }
01447 
01448 void MoveGroup::clearPathConstraints()
01449 {
01450   impl_->clearPathConstraints();
01451 }
01452 
01453 void MoveGroup::setConstraintsDatabase(const std::string &host, unsigned int port)
01454 {
01455   impl_->initializeConstraintsStorage(host, port);
01456 }
01457 
01458 void MoveGroup::setWorkspace(double minx, double miny, double minz, double maxx, double maxy, double maxz)
01459 {
01460   impl_->setWorkspace(minx, miny, minz, maxx, maxy, maxz);
01461 }
01462 
01463 void MoveGroup::setPlanningTime(double seconds)
01464 {
01465   impl_->setPlanningTime(seconds);
01466 }
01467 
01468 double MoveGroup::getPlanningTime() const
01469 {
01470   return impl_->getPlanningTime();
01471 }
01472 
01473 void MoveGroup::setSupportSurfaceName(const std::string &name)
01474 {
01475   impl_->setSupportSurfaceName(name);
01476 }
01477 
01478 const std::string& MoveGroup::getPlanningFrame() const
01479 {
01480   return impl_->getRobotModel()->getModelFrame();
01481 }
01482 
01483 }
01484 }


planning_interface
Author(s): Ioan Sucan
autogenerated on Mon Oct 6 2014 02:33:28