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
00031
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
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
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
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
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
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
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