00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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";
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;
00109 goal_orientation_tolerance_ = 1e-3;
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
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
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
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
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
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
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 ¤t_state)
00350 {
00351 if (!current_state_monitor_)
00352 {
00353 ROS_ERROR("Unable to get current robot state");
00354 return false;
00355 }
00356
00357
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
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
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
00663
00664
00665
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
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
00821 robot_state::RobotStatePtr joint_state_target_;
00822
00823
00824
00825 std::map<std::string, std::vector<geometry_msgs::PoseStamped> > pose_targets_;
00826
00827
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
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
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 }