simplepickplace.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 //publish messages with objects poses
00018 #include <geometry_msgs/Pose.h>
00019 #include <geometry_msgs/PoseStamped.h>
00020 #include <moveit_msgs/GetPlanningScene.h>
00021 #include <moveit_msgs/DisplayTrajectory.h>
00022 #include <moveit/move_group_interface/move_group.h>
00023 
00024 #include "romeo_moveit_actions/simplepickplace.hpp"
00025 #include "romeo_moveit_actions/tools.hpp"
00026 #include "romeo_moveit_actions/toolsForObject.hpp"
00027 
00028 namespace moveit_simple_actions
00029 {
00030   MetaBlock SimplePickPlace::createTable()
00031   {
00032     //create a table
00033     double height = -floor_to_base_height_ + (pose_default_.position.z-block_size_y_/2.0);
00034     double width = std::fabs(pose_default_r_.position.y*2.0) + block_size_x_/2.0;
00035     double depth = 0.35;
00036     geometry_msgs::Pose pose;
00037     setPose(&pose,
00038             pose_default_.position.x - block_size_x_/2.0 + depth/2.0,
00039             0.0,
00040             floor_to_base_height_ + height/2.0);
00041 
00042     MetaBlock table("table",
00043                     pose,
00044                     shape_msgs::SolidPrimitive::BOX,
00045                     depth,
00046                     width,
00047                     height);
00048     return table;
00049   }
00050 
00051   SimplePickPlace::SimplePickPlace(const std::string robot_name,
00052                                    double test_step,
00053                                    const double x_min,
00054                                    const double x_max,
00055                                    const double y_min,
00056                                    const double y_max,
00057                                    const double z_min,
00058                                    const double z_max,
00059                                    const std::string left_arm_name,
00060                                    const std::string right_arm_name,
00061                                    const bool verbose):
00062       nh_("~"),
00063       nh_priv_(""),
00064       robot_name_(robot_name),
00065       verbose_(verbose),
00066       base_frame_("base_link"),
00067       block_size_x_(0.03),
00068       block_size_y_(0.13),
00069       floor_to_base_height_(-1.0),
00070       env_shown_(false),
00071       evaluation_(verbose_, base_frame_),
00072       obj_proc_(&nh_priv_, &evaluation_),
00073       rate_(12.0)
00074   {
00075     setPose(&pose_zero_, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0);
00076     pose_default_ = pose_zero_;
00077     pose_default_r_ = pose_default_;
00078     if (robot_name_ == "nao")
00079     {
00080       block_size_x_ = 0.01;
00081       setPose(&pose_default_, 0.2, 0.1, 0.0);
00082       setPose(&pose_default_r_, 0.2, -0.1, 0.0);
00083       test_step = (test_step==0.0)?0.03:test_step;
00084       x_min_ = (x_min==0.0)?0.1:x_min;
00085       x_max_ = (x_max==0.0)?0.21:x_max;
00086       y_min_ = (y_min==0.0)?0.12:y_min;
00087       y_max_ = (y_max==0.0)?0.24:y_max;
00088       z_min_ = (z_min==0.0)?-0.07:z_min;
00089       z_max_ = (z_max==0.0)?0.05:z_max;
00090     }
00091     else if (robot_name == "pepper")
00092     {
00093       block_size_x_ = 0.02;
00094       setPose(&pose_default_, 0.25, 0.2, -0.1);
00095       setPose(&pose_default_r_, 0.25, -0.2, -0.1);
00096       test_step = (test_step==0.0)?0.04:test_step;
00097       x_min_ = (x_min==0.0)?0.2:x_min;
00098       x_max_ = (x_max==0.0)?0.4:x_max;
00099       y_min_ = (y_min==0.0)?0.12:y_min;
00100       y_max_ = (y_max==0.0)?0.24:y_max;
00101       z_min_ = (z_min==0.0)?-0.13:z_min;
00102       z_max_ = (z_max==0.0)?0.0:z_max;
00103     }
00104     else if (robot_name_ == "romeo")
00105     {
00106       setPose(&pose_default_, 0.44, 0.15, -0.1);
00107       setPose(&pose_default_r_, 0.49, -0.25, -0.1);
00108       test_step = (test_step==0.0)?0.02:test_step;
00109       x_min_ = (x_min==0.0)?0.38:x_min;
00110       x_max_ = (x_max==0.0)?0.5:x_max;
00111       y_min_ = (y_min==0.0)?0.12:y_min;
00112       y_max_ = (y_max==0.0)?0.24:y_max;
00113       z_min_ = (z_min==0.0)?-0.17:z_min;
00114       z_max_ = (z_max==0.0)?-0.08:z_max;
00115     }
00116 
00117     // objects related initialization
00118     /*sub_obj_coll_ = nh_.subscribe<moveit_msgs::CollisionObject>(
00119           "/collision_object", 100, &SimplePickPlace::getCollisionObjects, this);*/
00120 
00121     pub_obj_pose_ = nh_.advertise<geometry_msgs::PoseStamped>("/pose_current", 1);
00122 
00123     pub_obj_moveit_ = nh_.advertise<moveit_msgs::CollisionObject>("/collision_object", 10);
00124 
00125     // Load the Robot Viz Tools for publishing to rviz
00126     visual_tools_.reset(new moveit_visual_tools::MoveItVisualTools("odom"));
00127     visual_tools_->setManualSceneUpdating(false);
00128     visual_tools_->setFloorToBaseHeight(floor_to_base_height_);
00129     visual_tools_->deleteAllMarkers();
00130     visual_tools_->removeAllCollisionObjects();
00131     ros::Duration(1.0).sleep();
00132 
00133     action_left_ = new Action(&nh_, left_arm_name, robot_name_, base_frame_);
00134     action_right_ = new Action(&nh_, right_arm_name, robot_name_, base_frame_);
00135     action_left_->initVisualTools(visual_tools_);
00136     action_right_->initVisualTools(visual_tools_);
00137 
00138     msg_obj_pose_.header.frame_id = action_left_->getBaseLink();
00139 
00140     //move the robots parts to init positions
00141     //if (promptUserQuestion("Should I move the head to look down?"))
00142       //action_left_->poseHeadDown();
00143 
00144     //move arms to the initial position
00145     //if (promptUserQuestion(("Should I move the "+action_left_->end_eff+" to the initial pose?").c_str()))
00146     action_left_->poseHand(1);
00147 
00148     //if (promptUserQuestion(("Should I move the "+action_right_->plan_group+" to the initial pose?").c_str()))
00149     action_right_->poseHand(1);
00150 
00151     ros::Duration(1.0).sleep();
00152 
00153     //create a possible table
00154     blocks_surfaces_.push_back(createTable());
00155     support_surface_ = blocks_surfaces_.back().name_;
00156     //remove surfaces and publish again
00157     if (robot_name_ == "romeo")
00158     {
00159       std::vector<std::string> objects = getObjectsOldList(&blocks_surfaces_);
00160       current_scene_.removeCollisionObjects(objects);
00161       sleep(1.0);
00162       //add a collision block
00163       if (blocks_surfaces_.size() > 0)
00164       {
00165         blocks_surfaces_.back().publishBlock(&current_scene_);
00166         env_shown_ = true;
00167       }
00168     }
00169 
00170     evaluation_.init(test_step,
00171                      block_size_x_,
00172                      block_size_y_,
00173                      floor_to_base_height_,
00174                      x_min_,
00175                      x_max_,
00176                      y_min_,
00177                      y_max_,
00178                      z_min_,
00179                      z_max_);
00180 
00181     printTutorial(robot_name);
00182   }
00183 
00184 
00185   void SimplePickPlace::switchArm(Action *action)
00186   {
00187     if (action->plan_group_.find("left") != std::string::npos)
00188       action = action_right_;
00189     else
00190       action = action_left_;
00191 
00192     ROS_INFO_STREAM("Switching the active arm to " << action->plan_group_);
00193     sleep(2.0);
00194   }
00195 
00196   void SimplePickPlace::createObj(const MetaBlock &block)
00197   {
00198     obj_proc_.addBlock(block);
00199     msg_obj_pose_.header.frame_id = block.base_frame_;
00200     msg_obj_pose_.pose = block.pose_;
00201     pub_obj_pose_.publish(msg_obj_pose_);
00202 
00203     //publish the collision object
00204     //obj_proc_.blocks_->back().publishBlock(&current_scene_);
00205   }
00206 
00207   bool SimplePickPlace::checkObj(int &block_id)
00208   {
00209     if ((block_id >= 0) && (block_id < obj_proc_.getAmountOfBlocks()))
00210       return true;
00211     else
00212       false;
00213   }
00214 
00215   void SimplePickPlace::run()
00216   {
00217     int block_id = -1;
00218     int hand_id = 0; //0: any, 1: left, 2:right
00219     Action *action = action_left_;
00220 
00221     //create a virtual object
00222     MetaBlock block_l("Virtual1",
00223                       pose_default_,
00224                       shape_msgs::SolidPrimitive::CYLINDER,
00225                       block_size_x_,
00226                       block_size_y_,
00227                       0.0);
00228 
00229     createObj(block_l);
00230     block_id = 0;
00231 
00232     std::string actionName = "";
00233     MetaBlock *block;
00234 
00235     // Release the object if any
00236     if (checkObj(block_id))
00237     {
00238       block = obj_proc_.getBlock(block_id);
00239       action->releaseObject(block);
00240     }
00241 
00242     //the main loop
00243     while(ros::ok())
00244     {
00245       //if there are some objects, take the first
00246       if ((block_id == -1) && (obj_proc_.getAmountOfBlocks() > 0))
00247         block_id = 0;
00248       //if the object does not exist
00249       else if (block_id >= obj_proc_.getAmountOfBlocks())
00250       {
00251         ROS_WARN_STREAM("The object " << block_id << " does not exist");
00252         block_id = -1;
00253         obj_proc_.cleanObjects(true);
00254       }
00255 
00256       if (block_id >= 0)
00257       {
00258         block = obj_proc_.getBlock(block_id);
00259         if (block == NULL)
00260         {
00261           ROS_INFO_STREAM("the object " << block_id << " does not exist");
00262           block_id = -1;
00263           continue;
00264         }
00265 
00266         //update the object's pose
00267         msg_obj_pose_.header.frame_id = block->base_frame_;
00268         msg_obj_pose_.pose = block->pose_;
00269         pub_obj_pose_.publish(msg_obj_pose_);
00270         ROS_INFO_STREAM("The current active object is "
00271                         << block->name_
00272                         << " out of " << obj_proc_.getAmountOfBlocks());
00273         //obj_proc_.publishAllCollObj(&blocks_);
00274       }
00275 
00276       //ROS_INFO_STREAM("What do you want me to do ?");
00277       actionName = promptUserQuestionString();
00278       ROS_INFO_STREAM("Action chosen '" << actionName
00279                       << "' object_id=" << block_id
00280                       << " the arm active=" << action->plan_group_);
00281       // Pick the object with a grasp generator
00282       if ((checkObj(block_id)) && (actionName == "g"))
00283       {
00284         bool success = action->pickAction(block, support_surface_);
00285         //if not succeded then try with another arm
00286         if(!success)
00287         {
00288           switchArm(action);
00289           success = action->pickAction(block, support_surface_);
00290         }
00291 
00292         if(success)
00293           stat_poses_success_.push_back(block->pose_);
00294       }
00295       // Place the object with a default function
00296       else if ((checkObj(block_id)) && (actionName == "p"))
00297       {
00298         if(action->placeAction(block, support_surface_))
00299         {
00300           /* swap this block's start and the end pose
00301            * so that we can then move them back to position */
00302           swapPoses(&block->pose_, &block->goal_pose_);
00303           resetBlock(block);
00304         }
00305       }
00306       //return the hand to the initial pose and relese the object
00307       else if (actionName == "i")
00308       {
00309         // Remove the attached object and the collision object
00310         if (checkObj(block_id))
00311           action->releaseObject(block);
00312         else
00313           action->poseHand(2);
00314       }
00315       //return the hand to the initial pose
00316       else if ((actionName.length() == 3) || (actionName.compare(0,1,"i") == 0))
00317       {
00318         //remove the attached object and the collision object
00319         if (checkObj(block_id))
00320           resetBlock(block);
00321         //go to the required pose
00322         action->poseHand(actionName.at(1));
00323       }
00324       //exit the application
00325       else if (actionName == "q")
00326         break;
00327       //clean a virtual box on the left arm side
00328       else if (actionName == "lb")
00329       {
00330         obj_proc_.cleanObjects();
00331         createObj(MetaBlock("Virtual1", pose_default_, shape_msgs::SolidPrimitive::BOX, block_size_x_, block_size_y_, 0.0));
00332       }
00333       //create a virtual cylinder on the left hand side
00334       else if (actionName == "lc")
00335       {
00336         obj_proc_.cleanObjects();
00337         createObj(MetaBlock("Virtual1", pose_default_, shape_msgs::SolidPrimitive::CYLINDER, block_size_x_, block_size_y_, 0.0));
00338       }
00339       //create a virtual box on the right hand side
00340       else if (actionName == "rb")
00341       {
00342         obj_proc_.cleanObjects();
00343         createObj(MetaBlock("Virtual1", pose_default_r_, shape_msgs::SolidPrimitive::BOX, block_size_x_, block_size_y_, 0.0));
00344       }
00345       //create a virtual cylinder on the right hand side
00346       else if (actionName == "rc")
00347       {
00348         obj_proc_.cleanObjects();
00349         createObj(MetaBlock("Virtual1", pose_default_r_, shape_msgs::SolidPrimitive::CYLINDER, block_size_x_, block_size_y_, 0.0));
00350       }
00351       //detect objects
00352       else if (actionName == "d")
00353       {
00354         obj_proc_.cleanObjects();
00355 
00356         obj_proc_.triggerObjectDetection();
00357       }
00358       //continuous object detection
00359       else if (actionName == "dd")
00360       {
00361         obj_proc_.cleanObjects(true);
00362 
00363         ROS_INFO_STREAM("Object detection is running...");
00364         ros::Time start_time = ros::Time::now();
00365         while ((obj_proc_.getAmountOfBlocks() <= 0)
00366                && (ros::Time::now()-start_time < ros::Duration(10.0)))
00367         {
00368           obj_proc_.triggerObjectDetection();
00369           rate_.sleep();
00370         }
00371         if (verbose_)
00372           ROS_INFO_STREAM(obj_proc_.getAmountOfBlocks() << " objects detected");
00373       }
00374       //plan possible movement
00375       else if ((checkObj(block_id)) && (actionName == "plan"))
00376       {
00377         //TODO: do not remove an object but allow a collision to it
00378         visual_tools_->cleanupCO(block->name_);
00379         action->graspPlan(block, support_surface_);
00380         resetBlock(block);
00381       }
00382       //plan all possible movements
00383       else if ((checkObj(block_id)) && (actionName == "a"))
00384       {
00385         //TODO: do not remove an object but allow a collision to it
00386         visual_tools_->cleanupCO(block->name_);
00387         action->graspPlanAllPossible(block, support_surface_);
00388         resetBlock(block);
00389       }
00390       //reaching based on default pose and grasp
00391       else if ((checkObj(block_id)) && (actionName == "u"))
00392       {
00393         action->reachGrasp(block, support_surface_, 1, 0.015, 50.0);
00394       }
00395       //reach from top
00396       else if ((checkObj(block_id)) && (actionName == "reachtop"))
00397       {
00398         //TODO: do not remove an object but allow a collision to it
00399         visual_tools_->cleanupCO(block->name_);
00400         geometry_msgs::PoseStamped pose;
00401         pose.header.frame_id = block->base_frame_;
00402         pose.header.stamp = ros::Time::now();
00403         pose.pose = block->pose_;
00404         pose.pose.orientation.x = 0;
00405         pose.pose.position.z += block->size_x_*1.5;
00406         action->reachAction(pose, support_surface_);
00407         resetBlock(block);
00408       }
00409       //pick an object without a grasp generator
00410       else if ((checkObj(block_id)) && (actionName == "b"))
00411       {
00412         action->pickDefault(block, support_surface_);
00413       }
00414       //execute the planned movement
00415       else if ((checkObj(block_id)) && (actionName == "execute"))
00416       {
00417         action->executeAction();
00418       }
00419       //print the current pose
00420       else if (actionName == "get_pose")
00421       {
00422         action->getPose();
00423       }
00424       //open hand
00425       else if (actionName == "hand_open")
00426       {
00427         action->poseHandOpen();
00428       }
00429       //close hand
00430       else if (actionName == "hand_close")
00431       {
00432         action->poseHandClose();
00433       }
00434       //process the next object
00435       else if (actionName == "next_obj")
00436         ++block_id;
00437       //test the goal space for picking
00438       else if (actionName == "test_pick")
00439       {
00440         cleanObjects(&blocks_surfaces_, false);
00441         obj_proc_.cleanObjects();
00442         evaluation_.testReach(nh_,
00443                               &pub_obj_pose_,
00444                               &obj_proc_.pub_obj_poses_,
00445                               &pub_obj_moveit_,
00446                               visual_tools_,
00447                               action_left_,
00448                               action_right_,
00449                               &blocks_surfaces_,
00450                               true);
00451       }
00452       //test the goal space for reaching
00453       else if (actionName == "test_reach")
00454       {
00455         obj_proc_.cleanObjects();
00456         evaluation_.testReach(nh_,
00457                               &pub_obj_pose_,
00458                               &obj_proc_.pub_obj_poses_,
00459                               &pub_obj_moveit_,
00460                               visual_tools_,
00461                               action_left_,
00462                               action_right_,
00463                               &blocks_surfaces_,
00464                               false);
00465       }
00466       //set the table height
00467       else if (actionName == "set_table_height")
00468       {
00469         //TODO make a function
00470         if (blocks_surfaces_.size() > 0)
00471         {
00472           blocks_surfaces_.back().size_z_ = promptUserValue("Set the table height to");
00473           blocks_surfaces_.back().pose_.position.z =
00474               floor_to_base_height_ + blocks_surfaces_.back().size_z_/2.0;
00475           blocks_surfaces_.back().publishBlock(&current_scene_);
00476         }
00477       }
00478       //clean the scene
00479       else if (actionName == "table")
00480       {
00481         if (env_shown_)
00482         {
00483           //cleanObjects(&blocks_surfaces_, false);
00484           //cleanObjects(&blocks_);
00485           //env_shown_ = false;
00486           std::vector<std::string> objects = getObjectsList(blocks_surfaces_);
00487           current_scene_.removeCollisionObjects(objects);
00488           env_shown_ = false;
00489         }
00490         else
00491         {
00492           //pub_obj_moveit_.publish(blocks_surfaces_.front().collObj_);
00493           //env_shown_ = true;
00494           if (blocks_surfaces_.size() > 0)
00495           {
00496             blocks_surfaces_.back().publishBlock(&current_scene_);
00497             env_shown_ = true;
00498           }
00499         }
00500       }
00501       //moving the virtual object down
00502       else if (checkObj(block_id) && ((actionName == "x") || (actionName == "down")))
00503       {
00504         geometry_msgs::Pose pose(block->pose_);
00505         pose.position.z -= 0.05;
00506         block->updatePose(&current_scene_, pose);
00507       }
00508       //move the virtual object left
00509       else if (checkObj(block_id) && ((actionName == "s") || (actionName == "left")))
00510       {
00511         geometry_msgs::Pose pose(block->pose_);
00512         pose.position.y -= 0.05;
00513         block->updatePose(&current_scene_, pose);
00514       }
00515       //move the virtual object up
00516       else if (checkObj(block_id) && ((actionName == "e") || (actionName == "up")))
00517       {
00518         geometry_msgs::Pose pose(block->pose_);
00519         pose.position.z += 0.05;
00520         block->updatePose(&current_scene_, pose);
00521       }
00522       //move the virtual object right
00523       else if (checkObj(block_id) && ((actionName == "f") || (actionName == "right")))
00524       {
00525         geometry_msgs::Pose pose(block->pose_);
00526         pose.position.y += 0.05;
00527         block->updatePose(&current_scene_, pose);
00528       }
00529       //move the virtual object farther
00530       else if (checkObj(block_id) && ((actionName == "c") || (actionName == "farther")))
00531       {
00532         geometry_msgs::Pose pose(block->pose_);
00533         pose.position.x += 0.05;
00534         block->updatePose(&current_scene_, pose);
00535       }
00536       //move the virtual object closer
00537       else if (checkObj(block_id) && ((actionName == "r") || (actionName == "closer")))
00538       {
00539         geometry_msgs::Pose pose(block->pose_);
00540         pose.position.x -= 0.05;
00541         block->updatePose(&current_scene_, pose);
00542       }
00543       //set the tolerance
00544       else if (actionName == "j")
00545         action->setTolerance(promptUserValue("Set the value: "));
00546       //switch the active arm
00547       else if (actionName == "switcharm")
00548         switchArm(action);
00549       //move the head down
00550       else if (actionName == "look_down")
00551         action->poseHeadDown();
00552       //move the head to zero
00553       else if (actionName == "look_zero")
00554         action->poseHeadZero();
00555       //print the statistics on grasps
00556       else if (actionName == "stat")
00557       {
00558         ROS_INFO_STREAM("Successfully grasped objects at the locations: ");
00559         std::vector <geometry_msgs::Pose>::iterator it = stat_poses_success_.begin();
00560         for (; it != stat_poses_success_.end(); ++it)
00561         {
00562           ROS_INFO_STREAM(" [" << it->position.x << " "
00563                           << it->position.y << " "
00564                           << it->position.z << "] ["
00565                           << it->orientation.x << " "
00566                           << it->orientation.y << " "
00567                           << it->orientation.z << " "
00568                           << it->orientation.w << "]");
00569         }
00570       }
00571       //print the statistics on grasps
00572       else if (actionName == "stat_evaluation")
00573       {
00574         evaluation_.printStat();
00575       }
00576 
00577       if (actionName == "q")
00578         break;
00579     }
00580   }
00581 
00582   //clean the object list based on the timestamp
00583   void SimplePickPlace::cleanObjects(std::vector<MetaBlock> *objects,
00584                                      const bool list_erase)
00585   {
00586     std::vector<std::string> objects_list = getObjectsOldList(objects);
00587     current_scene_.removeCollisionObjects(objects_list);
00588 
00589     //remove from the memory
00590     if (list_erase)
00591       objects->clear();
00592   }
00593 
00594   void SimplePickPlace::resetBlock(MetaBlock *block)
00595   {
00596     // Remove attached object
00597     if(block->name_ != support_surface_)
00598     {
00599       action_left_->detachObject(block->name_);
00600       action_right_->detachObject(block->name_);
00601     }
00602     sleep(0.2);
00603 
00604     // Remove/Add collision object
00605     //visual_tools_->cleanupCO(block->name_);
00606     //visual_tools_->processCollisionObjectMsg(block->wrapToCollisionObject);
00607 
00608     block->publishBlock(&current_scene_);
00609   }
00610 
00611 } //namespace


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