action.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2016 SoftBank Robotics Europe
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015 */
00016 
00017 #include <moveit_msgs/PickupGoal.h>
00018 #include <moveit_msgs/RobotTrajectory.h>
00019 #include <moveit_msgs/GetPositionFK.h>
00020 #include <moveit_msgs/GetPlanningScene.h>
00021 #include <moveit_msgs/PlanningScene.h>
00022 #include <moveit/planning_scene_monitor/planning_scene_monitor.h>
00023 
00024 #include "romeo_moveit_actions/action.hpp"
00025 
00026 namespace moveit_simple_actions
00027 {
00028 
00029 Action::Action(ros::NodeHandle *nh,
00030                const std::string &arm,
00031                const std::string &robot_name,
00032                const std::string &base_frame):
00033   verbose_(false),
00034   attempts_max_(3),
00035   planning_time_(20.0), //=5 in GUI
00036   planner_id_("RRTConnectkConfigDefault"), //RRTConnect
00037   tolerance_min_(0.03), //tested on Pepper, works from 0.03
00038   tolerance_step_(0.02),
00039   max_velocity_scaling_factor_(1.0), //=1.0 in GUI
00040   dist_th_(0.08f),
00041   flag_(FLAG_MOVE),
00042   end_eff_(arm+"_hand"),
00043   plan_group_(arm+"_arm"),
00044   posture_(robot_name, end_eff_, plan_group_),
00045   base_frame_(base_frame)
00046 {
00047   /* ROS_INFO_STREAM(<< "Planning group: " << plan_group_
00048   ROS_INFO_STREAM("End Effector: " << end_eff_);
00049   ROS_INFO_STREAM("Planning Group: " << plan_group_);*/
00050 
00051   nh->getParam("tolerance_min", tolerance_min_);
00052 
00053   if (robot_name == "nao")
00054     planning_time_ = 30.0;
00055 
00056   // Create MoveGroup for the planning group
00057   move_group_.reset(new move_group_interface::MoveGroup(plan_group_));
00058   move_group_->setGoalTolerance(tolerance_min_);
00059   move_group_->setPlanningTime(planning_time_);
00060   move_group_->setPlannerId(planner_id_);
00061   move_group_->setNumPlanningAttempts(4);
00062   /*move_group_->setGoalPositionTolerance(0.1); //0.0001
00063   move_group_->setGoalOrientationTolerance(0.1); //0.001*/
00064 
00065   // Load grasp generator
00066   if (!grasp_data_.loadRobotGraspData(*nh, end_eff_))
00067   {
00068     ROS_ERROR("The grasp data cannot be loaded");
00069     ros::shutdown();
00070   }
00071 
00072   //generate grasps at PI/angle_resolution increments
00073   grasp_data_.angle_resolution_ = 30;
00074   /* grasp depth, when <= 0 the grasps is from other side
00075    * of the object or from bottom */
00076   grasp_data_.grasp_depth_ = 0.01;
00077   /*grasp_data_.approach_retreat_desired_dist_ = 0.3; //0.2 //as bigger better grasp
00078   grasp_data_.approach_retreat_min_dist_ = 0.05; //0.06*/
00079   /*std::cout << "grasp_data.approach_retreat_desired_dist_=" << grasp_data_.approach_retreat_desired_dist_ << std::endl
00080                << " grasp_data.approach_retreat_min_dist_=" << grasp_data_.approach_retreat_min_dist_ << std::endl
00081                << " grasp_data_.grasp_depth_= " << grasp_data_.grasp_depth_ << std::endl;*/
00082 
00083   if (grasp_data_.pre_grasp_posture_.points.size() > 0)
00084     for (int i=0; i<grasp_data_.pre_grasp_posture_.joint_names.size(); ++i)
00085     {
00086       if (grasp_data_.pre_grasp_posture_.joint_names[i].find("Hand") != std::string::npos)
00087       {
00088         if (grasp_data_.pre_grasp_posture_.points.size() > 0)
00089           posture_.initHandPose(grasp_data_.pre_grasp_posture_.points.at(0).positions[i], 0);
00090       }
00091       if (grasp_data_.grasp_posture_.joint_names[i].find("Hand") != std::string::npos)
00092       {
00093         if (grasp_data_.grasp_posture_.points.size() > 0)
00094           posture_.initHandPose(grasp_data_.grasp_posture_.points.at(0).positions[i], 1);
00095       }
00096     }
00097 
00098   // Load Grasp generator
00099   simple_grasps_.reset(new moveit_simple_grasps::SimpleGrasps(moveit_visual_tools::MoveItVisualToolsPtr()));
00100 
00101   pub_obj_pose_ = nh->advertise<geometry_msgs::PoseStamped>("/pose_target", 10);
00102 
00103   pub_plan_pose_ = nh->advertise<geometry_msgs::PoseStamped>("/pose_plan", 10);
00104   pub_plan_traj_ = nh->advertise<moveit_msgs::RobotTrajectory>("/trajectory", 10);
00105   client_fk_ = nh->serviceClient<moveit_msgs::GetPositionFK>("/compute_fk");
00106 
00107   planning_scene_publisher_ = nh->advertise<moveit_msgs::PlanningScene>("/planning_scene", 1);
00108 
00109   planning_scene_client_ = nh->serviceClient<moveit_msgs::GetPlanningScene>("/get_planning_scene");
00110 
00111   allowedCollisionLinks_ = move_group_->getRobotModel()->getJointModelGroup(grasp_data_.ee_group_)->getLinkModelNames();
00112   allowedCollisionLinks_.push_back(grasp_data_.ee_parent_link_);
00113   allowedCollisionLinks_.push_back("l_wrist");
00114   allowedCollisionLinks_.push_back("r_wrist");
00115   for(int i=0; i<allowedCollisionLinks_.size(); ++i)
00116     ROS_INFO_STREAM(allowedCollisionLinks_[i]);
00117 }
00118 
00119 void Action::initVisualTools(moveit_visual_tools::MoveItVisualToolsPtr &visual_tools)
00120 {
00121   visual_tools_ = visual_tools;
00122 
00123   // Load Grasp generator
00124   simple_grasps_.reset(new moveit_simple_grasps::SimpleGrasps(visual_tools_));
00125 }
00126 
00127 bool Action::pickDefault(MetaBlock *block,
00128                          const std::string surface_name)
00129 {
00130   bool done = false;
00131 
00132   std::vector<moveit_msgs::Grasp> grasps(1);
00133 
00134   moveit_msgs::Grasp g;
00135   g.grasp_pose.header.frame_id = block->name_;
00136   g.grasp_pose.pose = block->pose_;
00137   g.grasp_pose.pose = grasp_data_.grasp_pose_to_eef_pose_;
00138 
00139   g.pre_grasp_approach.direction.header.frame_id = grasp_data_.ee_parent_link_;
00140   g.pre_grasp_approach.direction.vector.x = 0;
00141   g.pre_grasp_approach.direction.vector.y = 0;
00142   g.pre_grasp_approach.direction.vector.z = -1;
00143   g.pre_grasp_approach.min_distance = 0.06; //0.01;
00144   g.pre_grasp_approach.desired_distance = 0.2;
00145 
00146   g.post_grasp_retreat.direction.header.frame_id = grasp_data_.ee_parent_link_;
00147   g.post_grasp_retreat.direction.vector.x = 0;
00148   g.post_grasp_retreat.direction.vector.y = 0;
00149   g.post_grasp_retreat.direction.vector.z = 1; // Retreat direction (pos z axis)
00150   g.post_grasp_retreat.min_distance = 0.06;
00151   g.post_grasp_retreat.desired_distance = 0.2;
00152 
00153   g.pre_grasp_posture.header.frame_id = grasp_data_.ee_parent_link_;
00154   g.grasp_posture.header.frame_id = grasp_data_.ee_parent_link_;
00155   if (grasp_data_.grasp_posture_.joint_names.size() > 0)
00156   {
00157     g.pre_grasp_posture.joint_names.resize(1);
00158     g.pre_grasp_posture.joint_names[0] = grasp_data_.grasp_posture_.joint_names[0];
00159     g.pre_grasp_posture.points.resize(1);
00160     g.pre_grasp_posture.points[0].positions.resize(1);
00161     g.pre_grasp_posture.points[0].positions[0] = 0.0;
00162 
00163     g.grasp_posture.joint_names.resize(1);
00164     g.grasp_posture.joint_names[0] = g.pre_grasp_posture.joint_names[0];
00165     g.grasp_posture.points.resize(1);
00166     g.grasp_posture.points[0].positions.resize(1);
00167     g.grasp_posture.points[0].positions[0] = 1.0;
00168   }
00169   std::cout << "-- pickDefault g " << g << std::endl;
00170 
00171     grasps[0] = g;
00172 
00173     // Prevent collision with table
00174     move_group_->setSupportSurfaceName(surface_name);
00175 
00176     /* an optional list of obstacles that
00177      * can be touched/pushed/moved in the course of grasping */
00178     std::vector<std::string> allowed_touch_objects;
00179     allowed_touch_objects.push_back(block->name_);
00180 
00181     // Add this list to all grasps
00182     for (std::size_t i = 0; i < grasps.size(); ++i)
00183       grasps[i].allowed_touch_objects = allowed_touch_objects;
00184 
00185     if (move_group_->pick(block->name_, grasps)){
00186       done = true;
00187 
00188       return true;
00189     }
00190     sleep(0.7);
00191   //}
00192 }
00193 
00194 bool Action::executeAction()
00195 {
00196   bool success(false);
00197 
00198   if (verbose_)
00199     ROS_INFO_STREAM("Execution of the planned action");
00200 
00201   if (!move_group_)
00202     return false;
00203 
00204   if (current_plan_ && flag_ == FLAG_MOVE)
00205     success = move_group_->execute(*current_plan_);
00206 
00207   if (verbose_ && success)
00208       ROS_INFO_STREAM("Execute success! \n\n");
00209 
00210   // If the function is called and FLAG_NO_MOVE return true
00211   // because only call executeAction if plan is success
00212   return success || flag_ == FLAG_NO_MOVE;
00213 }
00214 
00215 bool Action::graspPlan(MetaBlock *block, const std::string surface_name)
00216 {
00217   bool success(false);
00218 
00219   if (verbose_)
00220     ROS_INFO_STREAM("Planning " << block->name_
00221                     << " at pose " << block->pose_);
00222 
00223   double tolerance_cur =  move_group_->getGoalPositionTolerance();
00224   move_group_->setGoalTolerance(0.1);//0.05
00225 
00226   // Prevent collision with table
00227   if (!surface_name.empty())
00228     move_group_->setSupportSurfaceName(surface_name);
00229 
00230   if (!move_group_)
00231     return false;
00232 
00233   //move_group_->setApproximateJointValueTargets(target, move_group_->getEndEffectorLink().c_str());
00234   move_group_->setPoseTargets(configureForPlanning(generateGrasps(block)),
00235                               move_group_->getEndEffectorLink().c_str());
00236 
00237   current_plan_.reset(new moveit::planning_interface::MoveGroup::Plan());
00238   success = move_group_->plan(*current_plan_);
00239   if (!success)
00240     current_plan_.reset();
00241   else
00242     publishPlanInfo(*current_plan_, block->pose_);
00243 
00244   if (verbose_ && success)
00245       ROS_INFO_STREAM("Grasp planning success! \n\n");
00246 
00247   move_group_->setGoalTolerance(tolerance_cur);
00248 
00249   return success;
00250 }
00251 
00252 geometry_msgs::PoseStamped Action::getGraspPose(MetaBlock *block)
00253 {
00254   geometry_msgs::PoseStamped goal;
00255   goal.header.stamp = ros::Time::now();
00256 
00257   if (block->base_frame_ == base_frame_)
00258   {
00259     goal.header.frame_id = block->base_frame_;
00260     goal.pose = block->pose_;
00261     goal.pose.position.x += grasp_data_.grasp_pose_to_eef_pose_.position.x;
00262     goal.pose.position.y += grasp_data_.grasp_pose_to_eef_pose_.position.y;
00263     goal.pose.position.z -= grasp_data_.grasp_pose_to_eef_pose_.position.z;
00264 
00265     goal.pose.orientation = grasp_data_.grasp_pose_to_eef_pose_.orientation;
00266   }
00267   else
00268   {
00269     geometry_msgs::PoseStamped pose_transform = block->getTransformed(&listener_, base_frame_);
00270     goal.header.frame_id = base_frame_;
00271 
00272     goal.pose = pose_transform.pose;
00273     goal.pose.position.x += grasp_data_.grasp_pose_to_eef_pose_.position.x;
00274     goal.pose.position.y += grasp_data_.grasp_pose_to_eef_pose_.position.y;
00275     goal.pose.position.z += grasp_data_.grasp_pose_to_eef_pose_.position.z;
00276   }
00277   return goal;
00278 }
00279 
00280 float Action::computeDistance(MetaBlock *block)
00281 {
00282   geometry_msgs::PoseStamped goal = getGraspPose(block);
00283 
00284   float dist = computeDistance(goal.pose);
00285 
00286   return dist;
00287 }
00288 
00289 float Action::computeDistance(geometry_msgs::Pose goal)
00290 {
00291   geometry_msgs::Pose current(move_group_->getCurrentPose().pose);
00292   float dist = sqrt((goal.position.x - current.position.x)
00293                     * (goal.position.x - current.position.x)
00294                     + (goal.position.y - current.position.y)
00295                     * (goal.position.y - current.position.y)
00296                     + (goal.position.z - current.position.z)
00297                     * (goal.position.z - current.position.z));
00298   return dist;
00299 }
00300 
00301 bool Action::poseHeadZero()
00302 {
00303   return posture_.poseHeadZero();
00304 }
00305 
00306 bool Action::poseHeadDown()
00307 {
00308   return posture_.poseHeadDown();
00309 }
00310 
00311 bool Action::poseHand(const int pose_id)
00312 {
00313   double tolerance_cur = move_group_->getGoalPositionTolerance();
00314   move_group_->setGoalTolerance(0.05);
00315   bool res = posture_.poseHand(end_eff_, plan_group_, pose_id);
00316   move_group_->setGoalTolerance(tolerance_cur);
00317   return res;
00318 }
00319 
00320 void Action::poseHandOpen()
00321 {
00322   posture_.poseHandOpen(end_eff_);
00323 }
00324 
00325 void Action::poseHandClose()
00326 {
00327   posture_.poseHandClose(end_eff_);
00328 }
00329 
00330 geometry_msgs::Pose Action::getPose()
00331 {
00332   geometry_msgs::PoseStamped pose_now;
00333   pose_now.header.stamp = ros::Time::now();
00334   pose_now.header.frame_id = grasp_data_.base_link_;
00335 
00336   pose_now.pose = move_group_->getCurrentPose().pose;
00337 
00338   pose_now.pose.position.x -= grasp_data_.grasp_pose_to_eef_pose_.position.x;
00339   pose_now.pose.position.y -= grasp_data_.grasp_pose_to_eef_pose_.position.y;
00340   pose_now.pose.position.z -= grasp_data_.grasp_pose_to_eef_pose_.position.z;
00341   pose_now.pose.orientation = grasp_data_.grasp_pose_to_eef_pose_.orientation;
00342   //ROS_INFO_STREAM("current pose is " << pose_now);
00343 
00344   pub_obj_pose_.publish(pose_now);
00345 
00346   return pose_now.pose;
00347 }
00348 
00349 void Action::setTolerance(const double value)
00350 {
00351   move_group_->setGoalTolerance(value);
00352   if (verbose_)
00353     ROS_INFO_STREAM("The Goal Position Tolerance = "
00354                     << move_group_->getGoalPositionTolerance());
00355 }
00356 
00357 void Action::releaseObject(MetaBlock *block)
00358 {
00359   move_group_->detachObject(block->name_);
00360 
00361   //remove the collision temporally
00362   std::vector<std::string> objects;
00363   objects.push_back(block->name_);
00364   current_scene_.removeCollisionObjects(objects);
00365 
00366   //go to the required pose
00367   poseHand(2);
00368   ros::Duration(1.0).sleep();
00369   poseHandOpen();
00370 
00371   //add the collision object back
00372   std::vector<moveit_msgs::CollisionObject> coll_objects;
00373   coll_objects.push_back(block->collObj_);
00374   current_scene_.addCollisionObjects(coll_objects);
00375 }
00376 
00377 bool Action::setAllowedMoveItCollisionMatrix(moveit_msgs::AllowedCollisionMatrix& m)
00378 {
00379     moveit_msgs::PlanningScene planning_scene;
00380 
00381     if (planning_scene_publisher_.getNumSubscribers() < 1)
00382     {
00383         ROS_ERROR("Setting collision matrix won't have any effect!");
00384         return false;
00385     }
00386     planning_scene.is_diff = true;
00387     planning_scene.allowed_collision_matrix = m;
00388     planning_scene_publisher_.publish(planning_scene);
00389     return true;
00390 }
00391 
00392 bool Action::getCurrentMoveItAllowedCollisionMatrix(moveit_msgs::AllowedCollisionMatrix& matrix)
00393 {
00394     moveit_msgs::GetPlanningScene srv;
00395 
00396     srv.request.components.components = moveit_msgs::PlanningSceneComponents::ALLOWED_COLLISION_MATRIX;
00397 
00398     if (!planning_scene_client_.call(srv))
00399     {
00400         ROS_ERROR("Can't obtain planning scene");
00401         return false;
00402     }
00403 
00404     matrix = srv.response.scene.allowed_collision_matrix;
00405     if (matrix.entry_names.empty())
00406     {
00407         ROS_ERROR("Collision matrix should not be empty");
00408         return false;
00409     }
00410 
00411     //ROS_INFO_STREAM("Matrix: "<<matrix);
00412     return true;
00413 }
00414 
00415 std::vector<std::string>::iterator Action::ensureExistsInACM(const std::string& name,
00416                                                              moveit_msgs::AllowedCollisionMatrix& m,
00417                                                              bool initFlag)
00418 {
00419     std::vector<std::string>::iterator name_entry = std::find(m.entry_names.begin(), m.entry_names.end(), name);
00420     if (name_entry == m.entry_names.end())
00421     {
00422         ROS_DEBUG_STREAM("Could not find object " << name
00423                          << " in collision matrix. Inserting.");
00424         expandMoveItCollisionMatrix(name, m, initFlag);
00425         // re-assign the 'name_entry' iterator to the new entry_names place
00426         name_entry = std::find(m.entry_names.begin(), m.entry_names.end(), name);
00427         if (name_entry == m.entry_names.end())
00428         {
00429             ROS_ERROR("consistency, name should now be in map");
00430         }
00431     }
00432     return name_entry;
00433 }
00434 
00435 void Action::expandMoveItCollisionMatrix(const std::string& name,
00436                                          moveit_msgs::AllowedCollisionMatrix& m,
00437                                          bool default_val)
00438 {
00439 
00440     for (int i = 0; i < m.entry_names.size(); ++i)
00441     {
00442         m.entry_values[i].enabled.push_back(default_val);
00443     }
00444 
00445     m.entry_names.push_back(name);
00446 
00447     moveit_msgs::AllowedCollisionEntry e;
00448     e.enabled.assign(m.entry_names.size(), default_val);
00449     m.entry_values.push_back(e);
00450 }
00451 
00452 void Action::updateCollisionMatrix(const std::string& name)
00453 {
00454   moveit_msgs::AllowedCollisionMatrix m;
00455   if (!getCurrentMoveItAllowedCollisionMatrix(m))
00456     return;
00457 
00458   //ROS_INFO_STREAM("Allowed collisoin: " << block->name_);
00459   std::vector<std::string>::iterator objEntry = ensureExistsInACM(name, m, false);
00460   int obj_idx = objEntry - m.entry_names.begin();
00461 
00462   std::vector<std::string>::const_iterator it;
00463   for (it = allowedCollisionLinks_.begin(); it != allowedCollisionLinks_.end(); ++it)
00464   {
00465       std::vector<std::string>::iterator linkEntry = ensureExistsInACM(*it, m, false);
00466       int link_idx = linkEntry - m.entry_names.begin();
00467       m.entry_values[link_idx].enabled[obj_idx] = true;
00468       m.entry_values[obj_idx].enabled[link_idx] = true;
00469   }
00470   setAllowedMoveItCollisionMatrix(m);
00471 }
00472 
00473 bool Action::reachGrasp(MetaBlock *block,
00474                         const std::string surface_name,
00475                         int attempts_nbr,
00476                         float tolerance_min,
00477                         double planning_time)
00478 {
00479   bool success(false);
00480 
00481   //if (verbose_)
00482     ROS_INFO_STREAM("Reaching at position = "
00483                     << block->pose_.position.x << " "
00484                     << block->pose_.position.y << " "
00485                     << block->pose_.position.z);
00486 
00487   if (attempts_nbr == 0)
00488     attempts_nbr = attempts_max_;
00489 
00490   if (planning_time == 0.0)
00491     planning_time = planning_time_;
00492 
00493   if (tolerance_min == 0.0)
00494     tolerance_min = tolerance_min_;
00495 
00496   move_group_->setGoalTolerance(tolerance_min);
00497   move_group_->setPlanningTime(planning_time);
00498 
00499   updateCollisionMatrix(block->name_);
00500 
00501   geometry_msgs::PoseStamped pose = getGraspPose(block);
00502   ros::Duration(1.0).sleep();
00503 
00504   //reach the object
00505   if (!reachAction(pose, surface_name, attempts_nbr))
00506     return false;
00507 
00508   sleep(8.0);
00509 
00510   //compute the distance to the object
00511   float dist = computeDistance(pose.pose);
00512   if (verbose_)
00513     ROS_INFO_STREAM("Reached at distance = " << dist);
00514 
00515   //close the hand, if the object is close enough
00516   if (dist < dist_th_)
00517   {
00518     poseHandClose();
00519     success = true;
00520   }
00521 
00522   //attach the object
00523   if (success)
00524   {
00525     move_group_->attachObject(block->name_, grasp_data_.ee_parent_link_);
00526     object_attached_ = block->name_;
00527   }
00528 
00529   //if (verbose_)
00530     ROS_INFO_STREAM("Distance to the object= " << dist
00531                     << "; is grasped=" << success);
00532 
00533   return success;
00534 }
00535 
00536 bool Action::reachAction(geometry_msgs::PoseStamped pose_target,
00537                          const std::string surface_name,
00538                          const int attempts_nbr)
00539 {
00540   bool success(false);
00541 
00542   if (verbose_)
00543     ROS_INFO_STREAM("Planning to the pose " << pose_target);
00544 
00545   if (!move_group_)
00546     return false;
00547 
00548   current_plan_.reset(new moveit::planning_interface::MoveGroup::Plan());
00549 
00550   // Prevent collision with table
00551   if (!surface_name.empty())
00552     move_group_->setSupportSurfaceName(surface_name);
00553 
00554   move_group_->setPoseTarget(pose_target,
00555                              move_group_->getEndEffectorLink().c_str());
00556 
00557   //publish the target pose
00558   pub_obj_pose_.publish(pose_target);
00559 
00560   move_group_->setMaxVelocityScalingFactor(max_velocity_scaling_factor_); //TODO back
00561   move_group_->setNumPlanningAttempts(10); //Seems to not improve the results
00562   double tolerance = tolerance_min_;
00563   int attempts = 0;
00564 
00565   //find a planning solution while increasing tolerance
00566   while (!success && (attempts < attempts_nbr))
00567   {
00568     move_group_->setGoalTolerance(tolerance);
00569     success = move_group_->plan(*current_plan_);
00570 
00571     if (verbose_ && success)
00572       ROS_INFO_STREAM("Reaching success with tolerance " << tolerance << "\n\n");
00573 
00574     if (!success)
00575     {
00576       tolerance += tolerance_step_;
00577 
00578       if (verbose_)
00579         ROS_INFO_STREAM("Planning retry with the tolerance " << tolerance);
00580     }
00581     ++attempts;
00582   }
00583 
00584   //find an approximate solution
00585   if (!success)
00586   {
00587     move_group_->setApproximateJointValueTarget(pose_target,
00588                                                 move_group_->getEndEffectorLink().c_str());
00589     success = move_group_->plan(*current_plan_);
00590     if (verbose_ && success)
00591       ROS_INFO_STREAM("Reaching success with approximate joint value");
00592   }
00593 
00594   if (success)
00595   {
00596     //publishPlanInfo(*current_plan_, pose_target.pose);
00597     success = executeAction();
00598   }
00599   else
00600     current_plan_.reset();
00601 
00602   return success;
00603 }
00604 
00605 bool Action::graspPlanAllPossible(MetaBlock *block,
00606                                   const std::string surface_name)
00607 {
00608   bool success(false);
00609 
00610   if (verbose_)
00611     ROS_INFO_STREAM("Planning all possible grasps to " << block->pose_);
00612 
00613   // Prevent collision with table
00614   if (!surface_name.empty())
00615     move_group_->setSupportSurfaceName(surface_name);
00616 
00617   std::vector<geometry_msgs::Pose> targets =
00618       configureForPlanning(generateGrasps(block));
00619 
00620   moveit::planning_interface::MoveGroup::Plan plan;
00621 
00622   if (targets.size() == 0)
00623     return false;
00624 
00625   double tolerance_cur =  move_group_->getGoalPositionTolerance();
00626   move_group_->setGoalTolerance(0.1);
00627 
00628   int counts = 0;
00629   std::vector<geometry_msgs::Pose>::iterator it=targets.begin();
00630   for (; it!=targets.end();++it)
00631   {
00632     //move_group_->setPoseTarget(*it, move_group_->getEndEffectorLink().c_str());
00633     //move_group_->setPositionTarget(it->position.x, it->position.y, it->position.z, move_group_->getEndEffectorLink().c_str());
00634     success = move_group_->setApproximateJointValueTarget(*it, move_group_->getEndEffectorLink().c_str());
00635     success = move_group_->plan(plan);
00636     if (success)
00637       ++counts;
00638   }
00639   if (verbose_)
00640     ROS_INFO_STREAM( "Planning success for "
00641                      << counts << " generated poses! \n\n");
00642 
00643   move_group_->setGoalTolerance(tolerance_cur);
00644 
00645   return success;
00646 }
00647 
00648 std::vector<moveit_msgs::Grasp> Action::generateGrasps(MetaBlock *block)
00649 {
00650   std::vector<moveit_msgs::Grasp> grasps;
00651   if (block->name_.empty())
00652   {
00653     ROS_INFO_STREAM("No object choosen to grasp");
00654     return grasps;
00655   }
00656 
00657   if (verbose_)
00658     visual_tools_->deleteAllMarkers();
00659 
00660   geometry_msgs::Pose pose = block->pose_;
00661   pose.position.z += block->size_y_/2.0;
00662   simple_grasps_->generateBlockGrasps(pose, grasp_data_, grasps );
00663 
00664   /*if (verbose_)
00665   {
00666     double speed = 0.01;
00667     visual_tools_->publishGrasps(grasps, grasp_data_.ee_parent_link_, speed);
00668     visual_tools_->deleteAllMarkers();
00669     sleep(0.5);
00670   }*/
00671 
00672   if (grasps.size() > 0)
00673   {
00674     /* an optional list of obstacles that we have semantic information about
00675      * and that can be touched/pushed/moved in the course of grasping */
00676     std::vector<std::string> allowed_touch_objects(1);
00677     allowed_touch_objects[0] = block->name_;
00678     for (std::size_t i = 0; i < grasps.size(); ++i)
00679       grasps[i].allowed_touch_objects = allowed_touch_objects;
00680   }
00681 
00682   return grasps;
00683 }
00684 
00685 std::vector<geometry_msgs::Pose> Action::configureForPlanning(
00686     const std::vector<moveit_msgs::Grasp> &grasps)
00687 {
00688   std::vector<geometry_msgs::Pose> targets(grasps.size());
00689 
00690   if (grasps.size() > 0)
00691   {
00692     std::vector<moveit_msgs::Grasp>::const_iterator it_grasp = grasps.begin();
00693     std::vector<geometry_msgs::Pose>::iterator it_pose = targets.begin();
00694     for (; it_grasp!=grasps.end(); ++it_grasp, ++it_pose)
00695     {
00696       *it_pose = it_grasp->grasp_pose.pose;
00697     }
00698   }
00699 
00700   return targets;
00701 }
00702 
00703 bool Action::pickAction(MetaBlock *block, 
00704                         const std::string surface_name,
00705                         int attempts_nbr,
00706                         double planning_time)
00707 {
00708   bool success(false);
00709 
00710   //if (verbose_)
00711     ROS_INFO_STREAM("Pick at pose "
00712                     << block->pose_.position.x << " "
00713                     << block->pose_.position.y << " "
00714                     << block->pose_.position.z);
00715 
00716   if (attempts_nbr == 0)
00717     attempts_nbr = attempts_max_;
00718 
00719   if (planning_time == 0.0)
00720     planning_time = planning_time_;
00721 
00722   std::vector<moveit_msgs::Grasp> grasps = generateGrasps(block);
00723 
00724   if (grasps.size() == 0)
00725     return false;
00726 
00727   // Prevent collision with table
00728   if (!surface_name.empty())
00729     move_group_->setSupportSurfaceName(surface_name);
00730 
00731   move_group_->setPlanningTime(planning_time);
00732 
00733   double tolerance = tolerance_min_;
00734   int attempts = 0;
00735 
00736   //find a planning solution while increasing tolerance
00737   while (!success && (attempts < attempts_nbr))
00738   {
00739     move_group_->setGoalTolerance(tolerance);
00740     success = move_group_->pick(block->name_, grasps);
00741 
00742     if (!success)
00743     {
00744       tolerance += tolerance_step_;
00745 
00746       if (verbose_)
00747         ROS_INFO_STREAM("Try planning with the tolerance " << tolerance);
00748     }
00749     ++attempts;
00750   }
00751 
00752   move_group_->setGoalTolerance(tolerance_min_);
00753 
00754   if (verbose_ & success)
00755     ROS_INFO_STREAM("Pick success with tolerance " << tolerance << "\n\n");
00756 
00757   return success;
00758 }
00759 
00760 bool Action::placeAction(MetaBlock *block,
00761                          const std::string surface_name)
00762 {
00763   if (verbose_)
00764     ROS_INFO_STREAM("Placing " << block->name_
00765                     << " at pose " << block->goal_pose_);
00766 
00767   // Prevent collision with table
00768   if (!surface_name.empty())
00769     move_group_->setSupportSurfaceName(surface_name);
00770 
00771   std::vector<moveit_msgs::PlaceLocation> place_locations;
00772 
00773   // Re-usable datastruct
00774   geometry_msgs::PoseStamped pose_stamped;
00775   pose_stamped.header.frame_id = grasp_data_.base_link_;
00776   pose_stamped.header.stamp = ros::Time::now();
00777 
00778   // Create 360 degrees of place location rotated around a center
00779   //for (double angle = 0; angle < 2*M_PI; angle += M_PI/2)
00780   //{
00781     pose_stamped.pose = block->goal_pose_;
00782 
00783     // Create new place location
00784     moveit_msgs::PlaceLocation place_loc;
00785     place_loc.place_pose = pose_stamped;
00786 
00787     // Approach
00788     moveit_msgs::GripperTranslation pre_place_approach;
00789     pre_place_approach.direction.header.stamp = ros::Time::now();
00790     // The distance the origin of a robot link needs to travel
00791     pre_place_approach.desired_distance = grasp_data_.approach_retreat_desired_dist_;
00792     // half of the desired? Untested.
00793     pre_place_approach.min_distance = grasp_data_.approach_retreat_min_dist_;
00794     pre_place_approach.direction.header.frame_id = grasp_data_.base_link_;
00795     pre_place_approach.direction.vector.x = 0;
00796     pre_place_approach.direction.vector.y = 0;
00797     //Approach direction (negative z axis)
00798     pre_place_approach.direction.vector.z = 0.1; //-1
00799     place_loc.pre_place_approach = pre_place_approach;
00800 
00801     // Retreat
00802     /*moveit_msgs::GripperTranslation post_place_retreat(pre_place_approach);
00803     post_place_retreat.direction.vector.x = 0;
00804     post_place_retreat.direction.vector.y = 0;
00805     post_place_retreat.direction.vector.z = -1; //1 // Retreat direction (pos z axis)
00806     place_loc.post_place_retreat = post_place_retreat;*/
00807     // Post place posture - use same as pre-grasp posture (the OPEN command)
00808     place_loc.post_place_posture = grasp_data_.pre_grasp_posture_;
00809 
00810     place_locations.push_back(place_loc);
00811   //}
00812 
00813   //to test
00814   move_group_->setStartState(*move_group_->getCurrentState());
00815 
00816   bool success = move_group_->place(block->name_, place_locations);
00817   if (verbose_)
00818   {
00819     if (success)
00820       ROS_INFO_STREAM("Place success! \n\n");
00821     else
00822       ROS_ERROR_STREAM_NAMED("simple_actions:","Place failed.");
00823   }
00824 
00825   return success;
00826 }
00827 
00828 void Action::publishPlanInfo(moveit::planning_interface::MoveGroup::Plan plan,
00829                              geometry_msgs::Pose pose_target)
00830 {
00831   // Get the last position of the trajectory plan and transform that joints values
00832   // into pose of end effector in /base_link frame
00833   // Then that is published to /pose_plan and the trajectory to /trajectory topics
00834   //TODO: Check if using directly robotStatePtr changes the real robot
00835   int num_points = plan.trajectory_.joint_trajectory.points.size();
00836   moveit::core::RobotStatePtr robotStatePtr = move_group_->getCurrentState();
00837   robotStatePtr->setJointGroupPositions(plan_group_, plan.trajectory_.joint_trajectory.points[num_points-1].positions);
00838   moveit_msgs::RobotState robotStateMsg;
00839   moveit::core::robotStateToRobotStateMsg(*robotStatePtr, robotStateMsg);
00840 
00841   std::vector<std::string> links_vect;
00842   links_vect.push_back(move_group_->getEndEffectorLink());
00843 
00844   moveit_msgs::GetPositionFK srv;
00845   srv.request.header.frame_id = "/base_link"; //grasp_data_.ee_parent_link_; //TODO: To check
00846   srv.request.fk_link_names = links_vect;
00847   srv.request.robot_state = robotStateMsg;
00848 
00849   if (client_fk_.call(srv))
00850   {
00851     if(srv.response.pose_stamped.size() > 0)
00852     {
00853       int eef_index = srv.response.fk_link_names.size() - 1;
00854 
00855       pub_plan_pose_.publish(srv.response.pose_stamped[eef_index]);
00856 
00857       if(verbose_)
00858       {
00859         // Compute the distance between the last pose of the trajectory plan
00860         // and the target pose
00861         double x_target = pose_target.position.x;
00862         double y_target = pose_target.position.y;
00863         double z_target = pose_target.position.z;
00864 
00865         double x_pose = srv.response.pose_stamped[eef_index].pose.position.x;
00866         double y_pose = srv.response.pose_stamped[eef_index].pose.position.y;
00867         double z_pose = srv.response.pose_stamped[eef_index].pose.position.z;
00868 
00869         double error = sqrt(pow(x_target-x_pose,2)
00870                             + pow(y_target-y_pose,2)
00871                             + pow(z_target-z_pose,2));
00872 
00873         ROS_INFO_STREAM("Distance of last trajectory pose from target pose: "
00874                         << error << " meters");
00875       }
00876     }
00877     else
00878     {
00879       ROS_WARN_STREAM("No result of service /compute_fk \nMoveitCodeError: "
00880                       << srv.response.error_code);
00881     }
00882   }
00883   else
00884   {
00885     ROS_WARN("Failed to call service /compute_fk");
00886   }
00887   pub_plan_traj_.publish(plan.trajectory_);
00888 }
00889 
00890 void Action::setPlanningTime(const double value)
00891 {
00892   planning_time_ = value;
00893   move_group_->setPlanningTime(value);
00894   if(verbose_)
00895     ROS_INFO_STREAM("Planning time set to " << value);
00896 }
00897 
00898 void Action::setToleranceStep(const double value)
00899 {
00900   tolerance_step_ = value;
00901   if(verbose_)
00902     ROS_INFO_STREAM("Tolerance step set to " << value);
00903 }
00904 
00905 void Action::setToleranceMin(const double value)
00906 {
00907   tolerance_min_ = value;
00908   if(verbose_)
00909     ROS_INFO_STREAM("Tolerance min set to " << value);
00910 }
00911 
00912 void Action::setMaxVelocityScalingFactor(const double value)
00913 {
00914   max_velocity_scaling_factor_ = value;
00915   move_group_->setMaxVelocityScalingFactor(max_velocity_scaling_factor_);
00916   if(verbose_)
00917     ROS_INFO_STREAM("Max velocity scaling factor set to " << value);
00918 }
00919 
00920 void Action::setVerbose(bool verbose)
00921 {
00922   verbose_ = verbose;
00923   if(verbose_)
00924     ROS_INFO_STREAM("Verbose set to " << verbose);
00925 }
00926 
00927 void Action::setAttemptsMax(int value)
00928 {
00929   attempts_max_ = value;
00930   if(verbose_)
00931     ROS_INFO_STREAM("Attempts max set to " << value);
00932 }
00933 
00934 void Action::setFlag(int flag)
00935 {
00936   if(flag == FLAG_MOVE || flag == FLAG_NO_MOVE)
00937   {
00938     flag_ = flag;
00939     if(verbose_)
00940       ROS_INFO_STREAM("Flag set to " << flag);
00941   }
00942   else
00943     ROS_WARN_STREAM("No value: " << flag
00944                     << " for flag, will remain as: " << flag_);
00945 }
00946 
00947 void Action::detachObject(const std::string &block_name)
00948 {
00949   move_group_->detachObject(block_name);
00950 }
00951 
00952 void Action::attachObject(const std::string &block_name)
00953 {
00954   move_group_->attachObject(block_name, grasp_data_.ee_group_);
00955 }
00956 
00957 std::string Action::getBaseLink()
00958 {
00959   return grasp_data_.base_link_;
00960 }
00961 }


romeo_moveit_actions
Author(s):
autogenerated on Thu Jun 6 2019 21:57:24