planning_scene_interface.cpp
Go to the documentation of this file.
00001 /*
00002  * planning_scene_interface.cpp
00003  *
00004  *  Created on: 26 Jul 2012
00005  *      Author: andreas
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     // init service for planning scene
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 //bool PlanningSceneInterface::setPlanningSceneDiff(const arm_navigation_msgs::PlanningScene& scene)
00050 //{
00051 //    spsdService.request.planning_scene_diff = scene;
00052 //    return sendDiff();
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     // set floating links according to robot pose... (some kind of pr2_python hack?)
00111 //    if (state.joint_state.name[0] == "floating_trans_x")
00112 //    {
00113 //        arm_navigation_msgs::RobotState& state = spsdService.request.planning_scene_diff.robot_state;
00114 //        state.joint_state.position[0] = state.multi_dof_joint_state.poses[0].position.x;
00115 //        state.joint_state.position[1] = state.multi_dof_joint_state.poses[0].position.y;
00116 //        state.joint_state.position[2] = state.multi_dof_joint_state.poses[0].position.z;
00117 //        state.joint_state.position[3] = state.multi_dof_joint_state.poses[0].orientation.x;
00118 //        state.joint_state.position[4] = state.multi_dof_joint_state.poses[0].orientation.y;
00119 //        state.joint_state.position[5] = state.multi_dof_joint_state.poses[0].orientation.z;
00120 //        state.joint_state.position[6] = state.multi_dof_joint_state.poses[0].orientation.w;
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 //    eraseObject(object->id);
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 //    eraseAttachedObject(attached->object.id);
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     // robot joints
00256     ROS_INFO("---------------------");
00257     printDiff(scene.robot_state, other.robot_state);
00258 //    // attached objects
00259 //    printDiff(scene.attached_collision_objects, other.attached_collision_objects);
00260 //    // objects
00261 //    printDiff(scene.collision_objects, other.collision_objects);
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; // rad
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             // different angle: print joint name
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; // 1mm
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     // object ordering might be different
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     // object ordering might be different
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     // attach cup_0
00390     attachObjectToGripper("cup_0", "right_arm");
00391 //    removeObject("cup_0");
00392     sendDiff();
00393     printObjects(spsdService.request.planning_scene_diff);
00394 
00395     // attach cup_0
00396 //    attachObjectToGripper("cup_0", "right_arm");
00397 //    sendDiff();
00398 //    printObjects();
00399 
00400     // detach cup_0
00401 //    detachObjectAndAdd("cup_0");
00402 //    sendDiff();
00403 //    printObjects();
00404 }
00405 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


tidyup_utils
Author(s): Andreas Hertle
autogenerated on Wed Dec 26 2012 15:27:25