tidyup_planning_scene_updater.cpp
Go to the documentation of this file.
00001 /*
00002  * tidyup_planning_scene_updater.cpp
00003  *
00004  *  Created on: 10 Aug 2012
00005  *      Author: andreas
00006  */
00007 
00008 #include "planner_modules_pr2/tidyup_planning_scene_updater.h"
00009 #include <tidyup_utils/planning_scene_interface.h>
00010 #include <tidyup_utils/arm_state.h>
00011 #include <tidyup_utils/stringutil.h>
00012 #include <hardcoded_facts/geometryPoses.h>
00013 #include <ros/ros.h>
00014 
00015 using std::vector;
00016 using std::map;
00017 using std::set;
00018 using std::string;
00019 
00020 TidyupPlanningSceneUpdater* TidyupPlanningSceneUpdater::instance = NULL;
00021 
00022 TidyupPlanningSceneUpdater::TidyupPlanningSceneUpdater() : logName("[psu]")
00023 {
00024     string doorLocationFileName;
00025     ros::param::get("/continual_planning_executive/door_location_file", doorLocationFileName);
00026     loadDoorPoses(doorLocationFileName);
00027 
00028     defaultAttachPose.position.x = 0.032;
00029     defaultAttachPose.position.y = 0.015;
00030     defaultAttachPose.position.z = 0.0;
00031     defaultAttachPose.orientation.x = 0.707;
00032     defaultAttachPose.orientation.y = -0.106;
00033     defaultAttachPose.orientation.z = -0.690;
00034     defaultAttachPose.orientation.w = 0.105;
00035 
00036     ROS_INFO("%s initialized.\n", logName.c_str());
00037 }
00038 
00039 TidyupPlanningSceneUpdater::~TidyupPlanningSceneUpdater()
00040 {
00041 }
00042 
00043 bool TidyupPlanningSceneUpdater::readState(
00044         const string& robotLocation,
00045         predicateCallbackType predicateCallback,
00046         numericalFluentCallbackType numericalFluentCallback,
00047         geometry_msgs::Pose& robotPose,
00048         map<string, geometry_msgs::Pose>& movableObjects,
00049         map<string, string>& graspedObjects,
00050         map<string, string>& objectsOnStatic,
00051         set<string>& openDoors)
00052 {
00053     if (instance == NULL) instance = new TidyupPlanningSceneUpdater();
00054     return instance->readState_(robotLocation, predicateCallback, numericalFluentCallback, robotPose, movableObjects, graspedObjects, objectsOnStatic, openDoors);
00055 }
00056 
00057 bool TidyupPlanningSceneUpdater::readState_(
00058         const string& robotLocation,
00059         predicateCallbackType predicateCallback,
00060         numericalFluentCallbackType numericalFluentCallback,
00061         geometry_msgs::Pose& robotPose,
00062         map<string, geometry_msgs::Pose>& movableObjects,
00063         map<string, string>& graspedObjects,
00064         map<string, string>& objectsOnStatic,
00065         set<string>& openDoors)
00066 {
00067     // get poses of all movable objects
00068     PlanningSceneInterface* psi = PlanningSceneInterface::instance();
00069 //    psi->resetPlanningScene();
00070     geometry_msgs::Pose pose;
00071     const vector <arm_navigation_msgs::CollisionObject>& collisionObjects = psi->getCollisionObjects();
00072     for (vector <arm_navigation_msgs::CollisionObject>::const_iterator it = collisionObjects.begin();
00073             it != collisionObjects.end(); it++)
00074     {
00075         const string& objectName = it->id;
00076         if (StringUtil::startsWith(objectName, "table"))
00077             continue;
00078         if (StringUtil::startsWith(objectName, "door"))
00079             continue;
00080         if (StringUtil::startsWith(objectName, "sponge"))
00081             continue;
00082         if (! fillPoseFromState(pose, objectName, numericalFluentCallback))
00083         {
00084             psi->removeObject(objectName);
00085         }
00086         else
00087         {
00088             movableObjects.insert(make_pair(objectName, pose));
00089         }
00090     }
00091     const vector <arm_navigation_msgs::AttachedCollisionObject>& attachedObjects = psi->getAttachedCollisionObjects();
00092     for (vector <arm_navigation_msgs::AttachedCollisionObject>::const_iterator it = attachedObjects.begin(); it != attachedObjects.end(); it++)
00093     {
00094         const string& objectName = it->object.id;
00095         if (! fillPoseFromState(pose, objectName, numericalFluentCallback))
00096         {
00097             psi->removeObject(objectName);
00098         }
00099         else
00100         {
00101             movableObjects.insert(make_pair(objectName, pose));
00102         }
00103     }
00104 
00105     // find grasped objects and objects on tables
00106     PredicateList* predicates = NULL;
00107     if (!predicateCallback(predicates))
00108     {
00109         ROS_ERROR("%s predicateCallback failed.", logName.c_str());
00110         return false;
00111     }
00112     ROS_ASSERT(predicates != NULL);
00113     for (PredicateList::iterator it = predicates->begin(); it != predicates->end(); it++)
00114     {
00115         Predicate p = *it;
00116         if (!p.value)
00117             continue;
00118         if (p.name == "on")
00119         {
00120             ROS_ASSERT(p.parameters.size() == 2);
00121             // (on movable static)
00122             objectsOnStatic.insert(make_pair(p.parameters.front().value, p.parameters.back().value));
00123         }
00124         else if (p.name == "grasped")
00125         {
00126             ROS_ASSERT(p.parameters.size() == 2);
00127             // (grasped object arm)
00128             graspedObjects.insert(make_pair(p.parameters.front().value, p.parameters.back().value));
00129         }
00130         else if (p.name == "door-open")
00131         {
00132             ROS_ASSERT(p.parameters.size() == 1);
00133             // (door-open door)
00134             openDoors.insert(p.parameters.front().value);
00135         }
00136     }
00137 
00138     // Robot pose
00139     if (! fillPoseFromState(robotPose, robotLocation, numericalFluentCallback))
00140     {
00141         ROS_ERROR("%s get robot location failed.", logName.c_str());
00142     }
00143     return true;
00144 }
00145 
00146 bool TidyupPlanningSceneUpdater::update(const geometry_msgs::Pose& robotPose,
00147         const map<string, geometry_msgs::Pose>& movableObjects,
00148         const map<string, string>& graspedObjects,
00149         const set<string>& openDoors)
00150 {
00151     if (instance == NULL) instance = new TidyupPlanningSceneUpdater();
00152     return instance->update_(robotPose, movableObjects, graspedObjects, openDoors);
00153 }
00154 
00155 bool TidyupPlanningSceneUpdater::update_(const geometry_msgs::Pose& robotPose,
00156         const map<string, geometry_msgs::Pose>& movableObjects,
00157         const map<string, string>& graspedObjects,
00158         const set<string>& openDoors)
00159 {
00160     PlanningSceneInterface* psi = PlanningSceneInterface::instance();
00161 //    psi->resetPlanningScene();
00162 
00163     // set robot state in planning scene
00164     ROS_INFO("%s update robot state in planning scene", logName.c_str());
00165     arm_navigation_msgs::RobotState state = psi->getRobotState();
00166     state.multi_dof_joint_state.poses[0] = robotPose;
00167     ArmState::get("/arm_configurations/side_tuck/position/", "right_arm").replaceJointPositions(state.joint_state);
00168     ArmState::get("/arm_configurations/side_tuck/position/", "left_arm").replaceJointPositions(state.joint_state);
00169 
00170     // update pose of graspable object in the planning scene
00171     for(map<string, geometry_msgs::Pose>::const_iterator movabelObjectIt = movableObjects.begin(); movabelObjectIt != movableObjects.end(); movabelObjectIt++)
00172     {
00173         string object_name = movabelObjectIt->first;
00174         ROS_INFO("%s updating object %s", logName.c_str(), object_name.c_str());
00175         // if this object is attached somewhere we need to detach it
00176         if (psi->getAttachedCollisionObject(object_name) != NULL)
00177         {
00178             psi->detachObjectAndAdd(object_name);
00179         }
00180         // object is not attached, update pose
00181         if (psi->getCollisionObject(object_name) != NULL)
00182         {
00183             psi->updateObject(object_name, movabelObjectIt->second);
00184         }
00185         else
00186         {
00187             ROS_ERROR("%s object %s does not exist in planning scene.", logName.c_str(), object_name.c_str());
00188             return false;
00189         }
00190     }
00191 
00192     // attach putdown object to the correct arm
00193 //    const arm_navigation_msgs::CollisionObject* object = psi->getCollisionObject(request.putdown_object);
00194     for (map<string, string>::const_iterator graspedIt = graspedObjects.begin(); graspedIt != graspedObjects.end(); graspedIt++)
00195     {
00196         const string& objectName = graspedIt->first;
00197         const string& arm = graspedIt->second;
00198         ROS_INFO("%s attaching object %s to arm %s", logName.c_str(), objectName.c_str(), arm.c_str());
00199         ArmState::get("/arm_configurations/side_carry/position/", arm).replaceJointPositions(state.joint_state);
00200         psi->attachObjectToGripper(objectName, arm);
00201         psi->updateObject(objectName, defaultAttachPose);
00202     }
00203     psi->setRobotState(state);
00204 
00205     // update doors
00206     for (map<string, Door>::const_iterator doorIt = doors.begin(); doorIt != doors.end(); doorIt++)
00207     {
00208         if (openDoors.find(doorIt->first) != openDoors.end())
00209         {
00210             // door is open
00211             psi->updateObject(doorIt->first, doorIt->second.openPose);
00212         }
00213         else
00214         {
00215             // door is closed
00216             psi->updateObject(doorIt->first, doorIt->second.closedPose);
00217         }
00218     }
00219 
00220     // send changes
00221     return psi->sendDiff();
00222 }
00223 
00224 bool TidyupPlanningSceneUpdater::fillPoseFromState(geometry_msgs::Pose& pose,
00225         const string& poseName,
00226         numericalFluentCallbackType numericalFluentCallback)
00227 {
00228     // create the numerical fluent request
00229     ParameterList startParams;
00230     startParams.push_back(Parameter("", "", poseName));
00231     NumericalFluentList nfRequest;
00232     nfRequest.reserve(7);
00233     nfRequest.push_back(NumericalFluent("x", startParams));
00234     nfRequest.push_back(NumericalFluent("y", startParams));
00235     nfRequest.push_back(NumericalFluent("z", startParams));
00236     nfRequest.push_back(NumericalFluent("qx", startParams));
00237     nfRequest.push_back(NumericalFluent("qy", startParams));
00238     nfRequest.push_back(NumericalFluent("qz", startParams));
00239     nfRequest.push_back(NumericalFluent("qw", startParams));
00240 
00241     // get the fluents
00242     NumericalFluentList* nfRequestP = &nfRequest;
00243     if (!numericalFluentCallback(nfRequestP))
00244     {
00245         ROS_ERROR("fillPoseFromState failed for object: %s", poseName.c_str());
00246         return false;
00247     }
00248 
00249     // fill pose stamped
00250     pose.position.x = nfRequest[0].value;
00251     pose.position.y = nfRequest[1].value;
00252     pose.position.z = nfRequest[2].value;
00253     pose.orientation.x = nfRequest[3].value;
00254     pose.orientation.y = nfRequest[4].value;
00255     pose.orientation.z = nfRequest[5].value;
00256     pose.orientation.w = nfRequest[6].value;
00257     return true;
00258 }
00259 
00260 void TidyupPlanningSceneUpdater::loadDoorPoses(const string& doorLocationFileName)
00261 {
00262     GeometryPoses locations = GeometryPoses();
00263     ROS_ASSERT_MSG(locations.load(doorLocationFileName), "Could not load locations from \"%s\".", doorLocationFileName.c_str());
00264     const std::map<std::string, geometry_msgs::PoseStamped>& poses = locations.getPoses();
00265     for(std::map<std::string, geometry_msgs::PoseStamped>::const_iterator posesIterator = poses.begin(); posesIterator != poses.end(); posesIterator++)
00266     {
00267         string name = posesIterator->first;
00268         if (StringUtil::startsWith(name, "door"))
00269         {
00270             string doorName;
00271             bool open = false;
00272             if(StringUtil::endsWith(name, "_closed"))
00273             {
00274                 doorName = name.substr(0, name.length()-7);
00275             }
00276             else if(StringUtil::endsWith(name, "_open"))
00277             {
00278                 doorName = name.substr(0, name.length()-5);
00279                 open = true;
00280             }
00281             else
00282             {
00283                 ROS_ERROR("navstack planning scene: misformated door location entry %s in file %s", name.c_str(), doorLocationFileName.c_str());
00284                 continue;
00285             }
00286             map<string, Door>::iterator doorIterator = doors.find(doorName);
00287             if (doorIterator == doors.end())
00288             {
00289                 doors.insert(make_pair(doorName, Door(doorName)));
00290                 doorIterator = doors.find(doorName);
00291             }
00292             Door& door = doorIterator->second;
00293             if (open)
00294             {
00295                 door.openPose = posesIterator->second.pose;
00296             }
00297             else
00298             {
00299                 door.closedPose = posesIterator->second.pose;
00300             }
00301         }
00302     }
00303 }
00304 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends Defines


planner_modules_pr2
Author(s): Christian Dornhege, Andreas Hertle
autogenerated on Wed Dec 26 2012 15:49:38