MoveItCollisionMatrixManipulator.cpp
Go to the documentation of this file.
00001 #include <moveit_object_handling/MoveItCollisionMatrixManipulator.h>
00002 #include <moveit_object_handling/MoveItHelpers.h>
00003 
00004 #include <moveit_msgs/AllowedCollisionEntry.h>
00005 #include <moveit_msgs/GetCartesianPath.h>
00006 
00007 #include <Eigen/Core>
00008 
00009 #define DEFAULT_SET_PLANNING_SCENE_TOPIC "/planning_scene"
00010 #define DEFAULT_GET_PLANNING_SCENE_TOPIC "/get_planning_scene"
00011 
00012 using moveit_object_handling::MoveItCollisionMatrixManipulator;
00013 
00014 MoveItCollisionMatrixManipulator::MoveItCollisionMatrixManipulator(ros::NodeHandle& nh)
00015 {
00016     ros::NodeHandle _node("/moveit_object_handling");
00017 
00018     GET_PLANNING_SCENE_TOPIC = DEFAULT_GET_PLANNING_SCENE_TOPIC;
00019     _node.param<std::string>("moveit_get_planning_scene_topic", GET_PLANNING_SCENE_TOPIC, GET_PLANNING_SCENE_TOPIC);
00020     ROS_INFO("Got moveit_get_planning_scene_topic: <%s>", GET_PLANNING_SCENE_TOPIC.c_str());
00021 
00022 
00023     SET_PLANNING_SCENE_TOPIC = DEFAULT_SET_PLANNING_SCENE_TOPIC;
00024     _node.param<std::string>("moveit_set_planning_scene_topic", SET_PLANNING_SCENE_TOPIC, SET_PLANNING_SCENE_TOPIC);
00025     ROS_INFO("Got moveit_set_planning_scene_topic: <%s>", SET_PLANNING_SCENE_TOPIC.c_str());
00026 
00027     planning_scene_publisher = nh.advertise<moveit_msgs::PlanningScene>(SET_PLANNING_SCENE_TOPIC, 1);
00028     planning_scene_client = nh.serviceClient<moveit_msgs::GetPlanningScene>(GET_PLANNING_SCENE_TOPIC);
00029 
00030     // only done to ensure connections are made with the planning scene
00031     // topic/service, this works better together with MoveIt! launch files
00032     ros::Duration(0.2).sleep();
00033 }
00034 
00035 MoveItCollisionMatrixManipulator::~MoveItCollisionMatrixManipulator()
00036 {}
00037 
00038 
00039 void MoveItCollisionMatrixManipulator::expandMoveItCollisionMatrix(const std::string& name,
00040         moveit_msgs::AllowedCollisionMatrix& m, bool default_val)
00041 {
00042 
00043     for (int i = 0; i < m.entry_names.size(); ++i)
00044     {
00045         m.entry_values[i].enabled.push_back(default_val);
00046     }
00047 
00048     m.entry_names.push_back(name);
00049 
00050     moveit_msgs::AllowedCollisionEntry e;
00051     e.enabled.assign(m.entry_names.size(), default_val);
00052     m.entry_values.push_back(e);
00053 }
00054 
00055 bool MoveItCollisionMatrixManipulator::getCurrentMoveItAllowedCollisionMatrix(
00056     moveit_msgs::AllowedCollisionMatrix& matrix)
00057 {
00058 
00059     moveit_msgs::GetPlanningScene srv;
00060 
00061     srv.request.components.components = moveit_msgs::PlanningSceneComponents::ALLOWED_COLLISION_MATRIX;
00062 
00063     if (!planning_scene_client.call(srv))
00064     {
00065         ROS_ERROR("Can't obtain planning scene");
00066         return false;
00067     }
00068 
00069     matrix = srv.response.scene.allowed_collision_matrix;
00070     if (matrix.entry_names.empty())
00071     {
00072         ROS_ERROR("Collision matrix should not be empty");
00073         return false;
00074     }
00075 
00076     //ROS_INFO_STREAM("Matrix: "<<matrix);
00077     return true;
00078 }
00079 
00080 bool MoveItCollisionMatrixManipulator::setAllowedMoveItCollisionMatrix(moveit_msgs::AllowedCollisionMatrix& m)
00081 {
00082     moveit_msgs::PlanningScene planning_scene;
00083 
00084     if (planning_scene_publisher.getNumSubscribers() < 1)
00085     {
00086         ROS_ERROR("Setting collision matrix won't have any effect!");
00087         return false;
00088     }
00089     planning_scene.is_diff = true;
00090     planning_scene.allowed_collision_matrix = m;
00091     planning_scene_publisher.publish(planning_scene);
00092     return true;
00093 }
00094 
00095 
00096 bool MoveItCollisionMatrixManipulator::addAllowedMoveItCollision(const std::string& name,
00097         const std::vector<std::string>& linkNames)
00098 {
00099     moveit_msgs::AllowedCollisionMatrix m;
00100     if (!getCurrentMoveItAllowedCollisionMatrix(m))
00101     {
00102         return false;
00103     }
00104 
00105     //ROS_INFO_STREAM("Allowed collisoin: "<<m);
00106 
00107     std::vector<std::string>::iterator objEntry = ensureExistsInACM(name, m, false);
00108     int obj_idx = objEntry - m.entry_names.begin();
00109 
00110     std::vector<std::string>::const_iterator it;
00111     for (it = linkNames.begin(); it != linkNames.end(); ++it)
00112     {
00113         std::vector<std::string>::iterator linkEntry = ensureExistsInACM(*it, m, false);
00114         int link_idx = linkEntry - m.entry_names.begin();
00115         m.entry_values[link_idx].enabled[obj_idx] = true;
00116         m.entry_values[obj_idx].enabled[link_idx] = true;
00117     }
00118 
00119     setAllowedMoveItCollisionMatrix(m);
00120     return true;
00121 }
00122 
00123 
00124 
00125 std::vector<std::string>::iterator MoveItCollisionMatrixManipulator::ensureExistsInACM(
00126     const std::string& name, moveit_msgs::AllowedCollisionMatrix& m, bool initFlag)
00127 {
00128     std::vector<std::string>::iterator name_entry = std::find(m.entry_names.begin(), m.entry_names.end(), name);
00129     if (name_entry == m.entry_names.end())
00130     {
00131         ROS_DEBUG_STREAM("Could not find object " << name
00132                          << " in collision matrix. Inserting.");
00133         expandMoveItCollisionMatrix(name, m, initFlag);
00134         // re-assign the 'name_entry' iterator to the new entry_names place
00135         name_entry = std::find(m.entry_names.begin(), m.entry_names.end(), name);
00136         if (name_entry == m.entry_names.end())
00137         {
00138             ROS_ERROR("consistency, name should now be in map");
00139         }
00140     }
00141     return name_entry;
00142 }
00143 
00144 
00145 bool MoveItCollisionMatrixManipulator::setAllowedMoveItCollision(const std::string& name1, const std::string& name2, const bool flag)
00146 {
00147 
00148     moveit_msgs::AllowedCollisionMatrix m;
00149     if (!getCurrentMoveItAllowedCollisionMatrix(m))
00150     {
00151         return false;
00152     }
00153 
00154     //ROS_INFO_STREAM("Allowed collisoin: "<<m);
00155 
00156     std::vector<std::string>::iterator name1_entry = ensureExistsInACM(name1, m, false);
00157     std::vector<std::string>::iterator name2_entry = ensureExistsInACM(name2, m, false);
00158 
00159     int name1_entry_idx = name1_entry - m.entry_names.begin();
00160     int name2_entry_idx = name2_entry - m.entry_names.begin();
00161 
00162     m.entry_values[name2_entry_idx].enabled[name1_entry_idx] = flag;
00163     m.entry_values[name1_entry_idx].enabled[name2_entry_idx] = flag;
00164 
00165     setAllowedMoveItCollisionMatrix(m);
00166     return true;
00167 }
00168 
00169 
00170 
00171 
00172 
00173 bool MoveItCollisionMatrixManipulator::attachMoveItObjectToRobot(const std::string& name,
00174         const std::string& link_name, const std::vector<std::string>& allowedTouchLinks)
00175 {
00176 
00177     if (planning_scene_publisher.getNumSubscribers() < 1)
00178     {
00179         ROS_ERROR("attachObjectToRobot: No node subscribed to planning scene publisher, can't refresh octomap. %s",
00180                   SET_PLANNING_SCENE_TOPIC.c_str());
00181         return false;
00182     }
00183 
00184     moveit_msgs::GetPlanningScene srv;
00185     srv.request.components.components = moveit_msgs::PlanningSceneComponents::WORLD_OBJECT_NAMES |
00186                                         moveit_msgs::PlanningSceneComponents::WORLD_OBJECT_GEOMETRY;
00187 
00188     ROS_INFO("Requesting scene to modify object attachment..");
00189 
00190     if (!planning_scene_client.call(srv))
00191     {
00192         ROS_ERROR("Can't obtain planning scene");
00193         return false;
00194     }
00195 
00196     moveit_msgs::PlanningScene planning_scene;
00197     planning_scene.is_diff = true;
00198 
00199     ROS_INFO("Now attaching object to robot");
00200 
00201     moveit_msgs::CollisionObject collObj;
00202     if (!hasObject(name, srv.response.scene.world.collision_objects, collObj))
00203     {
00204         ROS_ERROR("Object %s was not in the scene", name.c_str());
00205         return false;
00206     }
00207     else
00208     {
00209         //remove object from planning scene
00210         collObj.operation = collObj.REMOVE;
00211         planning_scene.world.collision_objects.push_back(collObj);
00212     }
00213 
00214     moveit_msgs::AttachedCollisionObject attached_object;
00215     attached_object.link_name = link_name;
00216     attached_object.object.header.frame_id = link_name;
00217     attached_object.object = collObj;
00218     attached_object.touch_links = allowedTouchLinks;
00219     geometry_msgs::Pose pose;
00220     pose.orientation.w = 1.0;
00221 
00222     attached_object.object.operation = attached_object.object.ADD;
00223     planning_scene.robot_state.attached_collision_objects.push_back(attached_object);
00224 
00225 
00226     planning_scene_publisher.publish(planning_scene);
00227 
00228     ROS_INFO("Have attached object. %s", __FILE__);
00229 
00230     while (true)
00231     {
00232         srv.request.components.components = moveit_msgs::PlanningSceneComponents::ROBOT_STATE_ATTACHED_OBJECTS;
00233 
00234         ROS_INFO("Requesting scene to see if object is attached..");
00235 
00236         if (!planning_scene_client.call(srv))
00237         {
00238             ROS_ERROR("Can't obtain planning scene");
00239             return false;
00240         }
00241 
00242         ROS_INFO("Scene obtained");
00243         moveit_msgs::AttachedCollisionObject o;
00244         if (hasObject(name, srv.response.scene.robot_state.attached_collision_objects, o))
00245         {
00246             ROS_INFO("Scene is updated with attached object.");
00247             break;
00248         }
00249         ROS_INFO("Waiting for scene update to attach object...");
00250         ros::Duration(0.5).sleep();
00251     }
00252 
00253     ROS_INFO("Successfully attached object.");
00254 
00255     return true;
00256 }
00257 
00258 
00259 bool MoveItCollisionMatrixManipulator::detachMoveItObjectFromRobot(const std::string& name)
00260 {
00261 
00262     if (planning_scene_publisher.getNumSubscribers() < 1)
00263     {
00264         ROS_ERROR("attachObjectToRobot: No node subscribed to planning scene publisher, can't refresh octomap. %s",
00265                   SET_PLANNING_SCENE_TOPIC.c_str());
00266         return false;
00267     }
00268 
00269     moveit_msgs::GetPlanningScene srv;
00270     srv.request.components.components = moveit_msgs::PlanningSceneComponents::ROBOT_STATE_ATTACHED_OBJECTS;
00271 
00272     ROS_INFO("Requesting scene to modify object attachment..");
00273 
00274     if (!planning_scene_client.call(srv))
00275     {
00276         ROS_ERROR("Can't obtain planning scene");
00277         return false;
00278     }
00279 
00280     moveit_msgs::PlanningScene planning_scene;
00281     planning_scene.is_diff = true;
00282 
00283     ROS_INFO("Now detaching object from robot");
00284 
00285     moveit_msgs::AttachedCollisionObject attObj;
00286     if (!hasObject(name, srv.response.scene.robot_state.attached_collision_objects, attObj))
00287     {
00288         ROS_ERROR("Object %s was not attached to robot", name.c_str());
00289         return false;
00290     }
00291     else
00292     {
00293         //remove object from planning scene
00294         attObj.object.operation = attObj.object.REMOVE;
00295         planning_scene.robot_state.attached_collision_objects.push_back(attObj);
00296     }
00297 
00298     moveit_msgs::CollisionObject collision_object = attObj.object;
00299     collision_object.operation = collision_object.ADD;
00300     planning_scene.world.collision_objects.push_back(collision_object);
00301 
00302     planning_scene_publisher.publish(planning_scene);
00303 
00304     ROS_INFO("Have deattached object. %s", __FILE__);
00305 
00306     while (true)
00307     {
00308         srv.request.components.components = moveit_msgs::PlanningSceneComponents::WORLD_OBJECT_NAMES;
00309 
00310         ROS_INFO("Requesting scene to see if object is detached..");
00311 
00312         if (!planning_scene_client.call(srv))
00313         {
00314             ROS_ERROR("Can't obtain planning scene");
00315             return false;
00316         }
00317 
00318         ROS_INFO("Scene obtained");
00319         moveit_msgs::CollisionObject o;
00320         if (hasObject(name, srv.response.scene.world.collision_objects, o))
00321         {
00322             ROS_INFO("Scene is updated with detached object.");
00323             break;
00324         }
00325         ROS_INFO("Waiting for scene update to detach object...");
00326         ros::Duration(0.5).sleep();
00327     }
00328 
00329     ROS_INFO("Successfully detached object.");
00330 
00331     return true;
00332 }
00333 
00334 
00335 bool MoveItCollisionMatrixManipulator::getMoveItScene(octomap_msgs::OctomapWithPose & octomap,
00336         std::vector<moveit_msgs::CollisionObject>& collision_objects)
00337 {
00338 
00339     moveit_msgs::GetPlanningScene srv;
00340 
00341     srv.request.components.components = moveit_msgs::PlanningSceneComponents::OCTOMAP |
00342                                         moveit_msgs::PlanningSceneComponents::WORLD_OBJECT_NAMES |
00343                                         moveit_msgs::PlanningSceneComponents::WORLD_OBJECT_GEOMETRY;
00344 
00345     if (!planning_scene_client.call(srv))
00346     {
00347         ROS_ERROR("Can't obtain planning scene");
00348         return false;
00349     }
00350 
00351     moveit_msgs::PlanningScene& planning_scene = srv.response.scene;
00352 
00353     octomap = planning_scene.world.octomap;
00354     collision_objects = planning_scene.world.collision_objects;
00355     return true;
00356 }
00357 
00358 bool MoveItCollisionMatrixManipulator::hasObject(const std::string& name,
00359         const std::vector<moveit_msgs::AttachedCollisionObject>& objs, moveit_msgs::AttachedCollisionObject& o)
00360 {
00361     for (int i = 0; i < objs.size(); ++i)
00362     {
00363         if (objs[i].object.id == name)
00364         {
00365             o = objs[i];
00366             return true;
00367         }
00368     }
00369     return false;
00370 }
00371 
00372 
00373 bool MoveItCollisionMatrixManipulator::hasObject(const std::string& name,
00374         const std::vector<moveit_msgs::CollisionObject>& objs, moveit_msgs::CollisionObject& o)
00375 {
00376     for (int i = 0; i < objs.size(); ++i)
00377     {
00378         if (objs[i].id == name)
00379         {
00380             o = objs[i];
00381             return true;
00382         }
00383     }
00384     return false;
00385 }
00386 
00387 
00388 bool MoveItCollisionMatrixManipulator::removeObject(const std::string& name,
00389         std::vector<moveit_msgs::CollisionObject>& objs)
00390 {
00391     for (int i = 0; i < objs.size(); ++i)
00392     {
00393         if (objs[i].id == name)
00394         {
00395             objs.erase(objs.begin() + i);
00396             return true;
00397         }
00398     }
00399     return false;
00400 }
00401 
00402 
00403 bool MoveItCollisionMatrixManipulator::removeObject(const std::string& name,
00404         std::vector<moveit_msgs::AttachedCollisionObject>& objs)
00405 {
00406     for (int i = 0; i < objs.size(); ++i)
00407     {
00408         if (objs[i].object.id == name)
00409         {
00410             objs.erase(objs.begin() + i);
00411             return true;
00412         }
00413     }
00414     return false;
00415 }
00416 
00417 


moveit_object_handling
Author(s): Jennifer Buehler
autogenerated on Sat Mar 2 2019 03:50:51