Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "tidyup_utils/planning_scene_interface.h"
00009 #include "tidyup_utils/transformer.h"
00010
00011 PlanningSceneInterface* PlanningSceneInterface::singleton_instance = NULL;
00012
00013 PlanningSceneInterface* PlanningSceneInterface::instance()
00014 {
00015 if (singleton_instance == NULL)
00016 {
00017 singleton_instance = new PlanningSceneInterface();
00018 }
00019 return singleton_instance;
00020 }
00021
00022 PlanningSceneInterface::PlanningSceneInterface() : logName("[psi]")
00023 {
00024
00025 std::string service_name = "/environment_server/set_planning_scene_diff";
00026 while (!ros::service::waitForService(service_name, ros::Duration(3.0)))
00027 {
00028 ROS_ERROR_NAMED(logName, "Service %s not available - waiting.", service_name.c_str());
00029 }
00030 setPlanningSceneService = ros::service::createClient<arm_navigation_msgs::SetPlanningSceneDiff>(service_name, true);
00031 if (!setPlanningSceneService)
00032 {
00033 ROS_FATAL_NAMED(logName, "Could not initialize get plan service from %s (client name: %s)", service_name.c_str(), setPlanningSceneService.getService().c_str());
00034 return;
00035 }
00036 if (setPlanningSceneService.call(spsdService))
00037 {
00038 spsdService.request.planning_scene_diff = spsdService.response.planning_scene;
00039 }
00040 else
00041 {
00042 ROS_ERROR_NAMED(logName, "%s Could not initialize planning scene.", __PRETTY_FUNCTION__);
00043 return;
00044 }
00045 globalFrame = getRobotState_().multi_dof_joint_state.frame_ids[0];
00046 ROS_INFO_NAMED(logName, "planning scene interface initialized.");
00047 }
00048
00049
00050
00051
00052
00053
00054 bool PlanningSceneInterface::sendDiff()
00055 {
00056 if (setPlanningSceneService.call(spsdService))
00057 {
00058 ROS_INFO_NAMED(logName, "sending planning scene diff.");
00059 spsdService.request.planning_scene_diff = spsdService.response.planning_scene;
00060 return true;
00061 }
00062 else
00063 {
00064 ROS_ERROR_NAMED(logName, "send planning scene diff FAILED.");
00065 return false;
00066 }
00067 }
00068
00069 bool PlanningSceneInterface::resetPlanningScene()
00070 {
00071 spsdService.request.planning_scene_diff = arm_navigation_msgs::PlanningScene();
00072 return sendDiff();
00073 }
00074
00075 const arm_navigation_msgs::CollisionObject* PlanningSceneInterface::getCollisionObject(const std::string& id)
00076 {
00077 return getCollisionObject_(id);
00078 }
00079
00080 const arm_navigation_msgs::AttachedCollisionObject* PlanningSceneInterface::getAttachedCollisionObject(const std::string& id)
00081 {
00082 return getAttachedCollisionObject_(id);
00083 }
00084
00085 arm_navigation_msgs::CollisionObject* PlanningSceneInterface::getCollisionObject_(const std::string& id)
00086 {
00087 std::vector<arm_navigation_msgs::CollisionObject>& objects = getCollisionObjects_();
00088 for(std::vector<arm_navigation_msgs::CollisionObject>::iterator it = objects.begin(); it != objects.end(); it++)
00089 {
00090 if (it->id == id && it->operation.operation != it->operation.REMOVE)
00091 return &*it;
00092 }
00093 return NULL;
00094 }
00095
00096 arm_navigation_msgs::AttachedCollisionObject* PlanningSceneInterface::getAttachedCollisionObject_(const std::string& id)
00097 {
00098 std::vector<arm_navigation_msgs::AttachedCollisionObject>& objects = getAttachedCollisionObjects_();
00099 for(std::vector<arm_navigation_msgs::AttachedCollisionObject>::iterator it = objects.begin(); it != objects.end(); it++)
00100 {
00101 if (it->object.id == id && it->object.operation.operation != it->object.operation.REMOVE)
00102 return &*it;
00103 }
00104 return NULL;
00105 }
00106
00107 void PlanningSceneInterface::setRobotState(const arm_navigation_msgs::RobotState& state)
00108 {
00109 spsdService.request.planning_scene_diff.robot_state = state;
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 }
00123
00124 void PlanningSceneInterface::addObject(const arm_navigation_msgs::CollisionObject& object)
00125 {
00126 std::vector<arm_navigation_msgs::CollisionObject>& objects = getCollisionObjects_();
00127 for(std::vector<arm_navigation_msgs::CollisionObject>::iterator it = objects.begin(); it != objects.end(); it++)
00128 {
00129 if (it->id == object.id)
00130 {
00131 objects.erase(it);
00132 break;
00133 }
00134 }
00135 std::vector<arm_navigation_msgs::AttachedCollisionObject>& attachedObjects = getAttachedCollisionObjects_();
00136 for(std::vector<arm_navigation_msgs::AttachedCollisionObject>::iterator it = attachedObjects.begin(); it != attachedObjects.end(); it++)
00137 {
00138 if (it->object.id == object.id)
00139 {
00140 attachedObjects.erase(it);
00141 break;
00142 }
00143 }
00144 getCollisionObjects_().push_back(object);
00145 getCollisionObjects_().back().operation.operation = object.operation.ADD;
00146 }
00147
00148 void PlanningSceneInterface::removeObject(const std::string& id)
00149 {
00150 std::vector<arm_navigation_msgs::CollisionObject>& objects = getCollisionObjects_();
00151 for(std::vector<arm_navigation_msgs::CollisionObject>::iterator it = objects.begin(); it != objects.end(); it++)
00152 {
00153 if (it->id == id)
00154 {
00155 it->operation.operation = it->operation.REMOVE;
00156 it->header.stamp = ros::Time::now();
00157 return;
00158 }
00159 }
00160 std::vector<arm_navigation_msgs::AttachedCollisionObject>& attachedObjects = getAttachedCollisionObjects_();
00161 for(std::vector<arm_navigation_msgs::AttachedCollisionObject>::iterator it = attachedObjects.begin(); it != attachedObjects.end(); it++)
00162 {
00163 if (it->object.id == id)
00164 {
00165 it->object.operation.operation = it->object.operation.REMOVE;
00166 it->object.header.stamp = ros::Time::now();
00167 return;
00168 }
00169 }
00170 }
00171
00172 void PlanningSceneInterface::updateObject(const std::string& id, const geometry_msgs::Pose& pose)
00173 {
00174 arm_navigation_msgs::CollisionObject* object = getCollisionObject_(id);
00175 if (object == NULL)
00176 {
00177 arm_navigation_msgs::AttachedCollisionObject* attached = getAttachedCollisionObject_(id);
00178 if (attached == NULL)
00179 {
00180 ROS_ERROR_NAMED(logName, "no object %s exists in planning scene.", id.c_str());
00181 return;
00182 }
00183 object = &attached->object;
00184 }
00185 object->poses[0] = pose;
00186 object->operation.operation = object->operation.ADD;
00187 object->header.stamp = ros::Time::now();
00188 }
00189
00190 void PlanningSceneInterface::attachObjectToGripper(const std::string& id, const std::string& arm)
00191 {
00192 arm_navigation_msgs::CollisionObject* object = getCollisionObject_(id);
00193 const HandDescription& hand = HandDescription::get(arm);
00194 if (object == NULL)
00195 {
00196 arm_navigation_msgs::AttachedCollisionObject* attached = getAttachedCollisionObject_(id);
00197 if (attached == NULL)
00198 {
00199 ROS_ERROR("%s no object %s exists in planning scene.", logName.c_str(), id.c_str());
00200 return;
00201 }
00202 if (attached->link_name == hand.getAttachLink())
00203 {
00204 ROS_INFO("%s object %s already attached at the correct arm.", logName.c_str(), id.c_str());
00205 return;
00206 }
00207 ROS_INFO("%s object %s attached at wrong arm. detaching.", logName.c_str(), id.c_str());
00208 detachObjectAndAdd(id);
00209 object = getCollisionObject_(id);
00210 }
00211 getAttachedCollisionObjects_().push_back(arm_navigation_msgs::AttachedCollisionObject());
00212 arm_navigation_msgs::AttachedCollisionObject& attached = getAttachedCollisionObjects_().back();
00213 attached.object = *object;
00214 attached.link_name = hand.getAttachLink();
00215 attached.touch_links = hand.getTouchLinks();
00216 attached.object.operation.operation = attached.object.operation.ADD;
00217 attached.object.header.stamp = ros::Time::now();
00218 Transformer::transform(hand.getAttachLink(), object->header.frame_id, getRobotState(), attached.object.poses[0]);
00219 attached.object.header.frame_id = hand.getAttachLink();
00220 object->operation.operation = object->operation.REMOVE;
00221
00222 }
00223
00224 void PlanningSceneInterface::detachObjectAndAdd(const std::string& id)
00225 {
00226 arm_navigation_msgs::AttachedCollisionObject* attached = getAttachedCollisionObject_(id);
00227 if (attached == NULL)
00228 {
00229 arm_navigation_msgs::CollisionObject* object = getCollisionObject_(id);
00230 if (object == NULL)
00231 {
00232 ROS_ERROR_NAMED(logName, "no object %s exists in planning scene.", id.c_str());
00233 return;
00234 }
00235 ROS_INFO_NAMED(logName, "object %s is not attached in planning scene.", id.c_str());
00236 return;
00237 }
00238 getCollisionObjects_().push_back(attached->object);
00239 arm_navigation_msgs::CollisionObject& object = getCollisionObjects_().back();
00240 Transformer::transform(globalFrame, object.header.frame_id, getRobotState_(), object.poses[0]);
00241 object.operation.operation = object.operation.ADD;
00242 object.header.frame_id = globalFrame;
00243 object.header.stamp = ros::Time::now();
00244 attached->object.operation.operation = attached->object.operation.REMOVE;
00245
00246 }
00247
00248 void PlanningSceneInterface::printDiffToCurrent(const arm_navigation_msgs::PlanningScene& other) const
00249 {
00250 printDiff(spsdService.request.planning_scene_diff, other);
00251 }
00252
00253 void PlanningSceneInterface::printDiff(const arm_navigation_msgs::PlanningScene& scene, const arm_navigation_msgs::PlanningScene& other)
00254 {
00255
00256 ROS_INFO("---------------------");
00257 printDiff(scene.robot_state, other.robot_state);
00258
00259
00260
00261
00262 ROS_INFO("--------------------- objects");
00263 printObjects(scene);
00264 ROS_INFO("--------------------- other objects");
00265 printObjects(other);
00266 ROS_INFO("---------------------");
00267 }
00268
00269 void PlanningSceneInterface::printDiff(const arm_navigation_msgs::RobotState& state, const arm_navigation_msgs::RobotState& other)
00270 {
00271 ROS_INFO("RobotState diff:");
00272 if (isDifferent(state.multi_dof_joint_state.poses[0], other.multi_dof_joint_state.poses[0]))
00273 {
00274 ROS_INFO_STREAM("robot pose: " << state.multi_dof_joint_state.poses[0] << " vs " << other.multi_dof_joint_state.poses[0]);
00275 }
00276 double epsilon = 0.01;
00277 for (size_t i = 0; i < state.joint_state.position.size(); i++)
00278 {
00279 if (fabs(state.joint_state.position[i] - other.joint_state.position[i]) > epsilon)
00280 {
00281
00282 ROS_INFO_STREAM("joint " << state.joint_state.name[i] << " " << state.joint_state.position[i] << " vs " << other.joint_state.position[i]);
00283 }
00284 }
00285 }
00286
00287 bool PlanningSceneInterface::isDifferent(const geometry_msgs::Pose& pose, const geometry_msgs::Pose& other)
00288 {
00289 double epsilon = 0.001;
00290 bool different = false;
00291 if (fabs(pose.position.x - other.position.x) > epsilon)
00292 different = true;
00293 if (fabs(pose.position.y - other.position.y) > epsilon)
00294 different = true;
00295 if (fabs(pose.position.z - other.position.z) > epsilon)
00296 different = true;
00297 if (fabs(pose.orientation.x - other.orientation.x) > epsilon)
00298 different = true;
00299 if (fabs(pose.orientation.y - other.orientation.y) > epsilon)
00300 different = true;
00301 if (fabs(pose.orientation.z - other.orientation.z) > epsilon)
00302 different = true;
00303 if (fabs(pose.orientation.w - other.orientation.w) > epsilon)
00304 different = true;
00305 return different;
00306 }
00307
00308 void PlanningSceneInterface::printDiff(
00309 const std::vector<arm_navigation_msgs::CollisionObject>& objectList,
00310 const std::vector<arm_navigation_msgs::CollisionObject>& other)
00311 {
00312
00313 for (std::vector<arm_navigation_msgs::CollisionObject>::const_iterator objectIt = objectList.begin();
00314 objectIt != objectList.end(); objectIt++)
00315 {
00316 for (std::vector<arm_navigation_msgs::CollisionObject>::const_iterator otherIt = other.begin();
00317 otherIt != other.end(); otherIt++)
00318 {
00319 if (objectIt->id == otherIt->id)
00320 {
00321 if (objectIt->operation.operation != otherIt->operation.operation)
00322 {
00323 ROS_INFO_STREAM("object: " << objectIt->id << " op: " << objectIt->operation.operation << " vs " << otherIt->operation.operation);
00324 continue;
00325 }
00326 if (isDifferent(objectIt->poses[0], otherIt->poses[0]))
00327 {
00328 ROS_INFO_STREAM("object: " << objectIt->id << " pose: " << objectIt->poses[0] << " vs " << otherIt->poses[0]);
00329 continue;
00330 }
00331 }
00332 }
00333 ROS_INFO_STREAM("object: " << objectIt->id << " removed in other");
00334 }
00335 }
00336
00337 void PlanningSceneInterface::printDiff(const std::vector<arm_navigation_msgs::AttachedCollisionObject>& objectList,
00338 const std::vector<arm_navigation_msgs::AttachedCollisionObject>& other)
00339 {
00340
00341 for (std::vector<arm_navigation_msgs::AttachedCollisionObject>::const_iterator objectIt = objectList.begin();
00342 objectIt != objectList.end(); objectIt++)
00343 {
00344 for (std::vector<arm_navigation_msgs::AttachedCollisionObject>::const_iterator otherIt = other.begin();
00345 otherIt != other.end(); otherIt++)
00346 {
00347 if (objectIt->object.id == otherIt->object.id)
00348 {
00349 if (objectIt->object.operation.operation != otherIt->object.operation.operation)
00350 {
00351 ROS_INFO_STREAM("object: " << objectIt->object.id << " op: " << objectIt->object.operation << " vs " << otherIt->object.operation);
00352 continue;
00353 }
00354 if (objectIt->link_name == otherIt->link_name)
00355 {
00356 ROS_INFO_STREAM("object: " << objectIt->object.id << " link_name: " << objectIt->link_name << " vs " << otherIt->link_name);
00357 continue;
00358 }
00359 }
00360 }
00361 ROS_INFO_STREAM("object: " << objectIt->object.id << " removed in other");
00362 }
00363 }
00364
00365 void PlanningSceneInterface::printAttachedObject(const arm_navigation_msgs::AttachedCollisionObject& object)
00366 {
00367 ROS_INFO_STREAM("attached: " << object.object.id << " at " << object.link_name);
00368 }
00369
00370 void PlanningSceneInterface::printObjects(const arm_navigation_msgs::PlanningScene& scene)
00371 {
00372 const std::vector <arm_navigation_msgs::AttachedCollisionObject>& attachedObjects = scene.attached_collision_objects;
00373 for (std::vector <arm_navigation_msgs::AttachedCollisionObject>::const_iterator attachedIt = attachedObjects.begin(); attachedIt != attachedObjects.end(); attachedIt++)
00374 {
00375 ROS_INFO_STREAM("attached: " << attachedIt->object.id << " op: " << attachedIt->object.operation << " at " << attachedIt->link_name);
00376 }
00377 const std::vector <arm_navigation_msgs::CollisionObject>& objects = scene.collision_objects;
00378 for (std::vector <arm_navigation_msgs::CollisionObject>::const_iterator objectIt = objects.begin(); objectIt != objects.end(); objectIt++)
00379 {
00380 ROS_INFO_STREAM("object: " << objectIt->id << " op: " << objectIt->operation);
00381 }
00382 }
00383
00384 void PlanningSceneInterface::test()
00385 {
00386 resetPlanningScene();
00387 printObjects(spsdService.request.planning_scene_diff);
00388
00389
00390 attachObjectToGripper("cup_0", "right_arm");
00391
00392 sendDiff();
00393 printObjects(spsdService.request.planning_scene_diff);
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 }
00405