00001 #include "planner_modules_pr2/navstack_planning_scene_module.h" 00002 #include "planner_modules_pr2/navstack_module.h" 00003 #include "planner_modules_pr2/tidyup_planning_scene_updater.h" 00004 #include <ros/ros.h> 00005 #include <geometry_msgs/Pose.h> 00006 #include <utility> 00007 using std::map; using std::pair; using std::make_pair; using std::set; 00008 00009 VERIFY_CONDITIONCHECKER_DEF(planning_scene_pathCost); 00010 00011 string logName = "[psNavModule]"; 00012 00013 //PlanningSceneNavigationModule* PlanningSceneNavigationModule::singleton_instance = NULL; 00014 // 00015 //PlanningSceneNavigationModule* PlanningSceneNavigationModule::instance() 00016 //{ 00017 // if (singleton_instance == NULL) singleton_instance = new PlanningSceneNavigationModule(); 00018 // return singleton_instance; 00019 //} 00020 // 00021 //void PlanningSceneNavigationModule::loadDoorPoses(const string& doorLocationFileName) 00022 //{ 00023 // GeometryPoses locations = GeometryPoses(); 00024 // ROS_ASSERT_MSG(locations.load(doorLocationFileName), "Could not load locations from \"%s\".", doorLocationFileName.c_str()); 00025 // const std::map<std::string, geometry_msgs::PoseStamped>& poses = locations.getPoses(); 00026 // for(std::map<std::string, geometry_msgs::PoseStamped>::const_iterator posesIterator = poses.begin(); posesIterator != poses.end(); posesIterator++) 00027 // { 00028 // string name = posesIterator->first; 00029 // if (StringUtil::startsWith(name, "door")) 00030 // { 00031 // string doorName; 00032 // bool open = false; 00033 // if(StringUtil::endsWith(name, "_closed")) 00034 // { 00035 // doorName = name.substr(0, name.length()-7); 00036 // } 00037 // else if(StringUtil::endsWith(name, "_open")) 00038 // { 00039 // doorName = name.substr(0, name.length()-5); 00040 // open = true; 00041 // } 00042 // else 00043 // { 00044 // ROS_ERROR("navstack planning scene: misformated door location entry %s in file %s", name.c_str(), doorLocationFileName.c_str()); 00045 // continue; 00046 // } 00047 // map<string, Door>::iterator doorIterator = doors.find(doorName); 00048 // if (doorIterator == doors.end()) 00049 // { 00050 // doors.insert(make_pair(doorName, Door(doorName))); 00051 // doorIterator = doors.find(doorName); 00052 // } 00053 // Door& door = doorIterator->second; 00054 // if (open) 00055 // { 00056 // door.openPose = posesIterator->second; 00057 // } 00058 // else 00059 // { 00060 // door.closedPose = posesIterator->second; 00061 // } 00062 // } 00063 // } 00064 //} 00065 // 00066 //void PlanningSceneNavigationModule::fillPoseFromState(geometry_msgs::Pose& pose, const string& poseName, numericalFluentCallbackType numericalFluentCallback) 00067 //{ 00068 // // create the numerical fluent request 00069 // ParameterList startParams; 00070 // startParams.push_back(Parameter("", "", poseName)); 00071 // NumericalFluentList nfRequest; 00072 // nfRequest.reserve(7); 00073 // nfRequest.push_back(NumericalFluent("x", startParams)); 00074 // nfRequest.push_back(NumericalFluent("y", startParams)); 00075 // nfRequest.push_back(NumericalFluent("z", startParams)); 00076 // nfRequest.push_back(NumericalFluent("qx", startParams)); 00077 // nfRequest.push_back(NumericalFluent("qy", startParams)); 00078 // nfRequest.push_back(NumericalFluent("qz", startParams)); 00079 // nfRequest.push_back(NumericalFluent("qw", startParams)); 00080 // 00081 // // get the fluents 00082 // NumericalFluentList* nfRequestP = &nfRequest; 00083 // if (!numericalFluentCallback(nfRequestP)) 00084 // { 00085 // ROS_INFO("fillPoseFromState failed for object: %s", poseName.c_str()); 00086 // return; 00087 // } 00088 // 00089 // // fill pose stamped 00090 // pose.position.x = nfRequest[0].value; 00091 // pose.position.y = nfRequest[1].value; 00092 // pose.position.z = nfRequest[2].value; 00093 // pose.orientation.x = nfRequest[3].value; 00094 // pose.orientation.y = nfRequest[4].value; 00095 // pose.orientation.z = nfRequest[5].value; 00096 // pose.orientation.w = nfRequest[6].value; 00097 //} 00098 // 00099 //bool PlanningSceneNavigationModule::setPlanningSceneDiffFromState(const ParameterList & parameterList, 00100 // predicateCallbackType predicateCallback, 00101 // numericalFluentCallbackType numericalFluentCallback) 00102 //{ 00103 // 00104 // // update objects in planning scene 00105 // PlanningSceneInterface* psi = PlanningSceneInterface::instance(); 00106 // psi->resetPlanningScene(); 00107 // for (map<string, Door>::const_iterator doorIterator = doors.begin(); doorIterator != doors.end(); doorIterator++) 00108 // { 00109 // string doorName = doorIterator->first; 00110 // if (psi->getCollisionObject(doorName) != NULL) 00111 // { 00112 // // update door pose 00113 // PredicateList predicates; 00114 // ParameterList pl; 00115 // pl.push_back(Parameter("", "", doorName)); 00116 // predicates.push_back(Predicate("door-open", pl)); 00117 // PredicateList* predicateRequest = &predicates; 00118 // if ( ! predicateCallback(predicateRequest)) 00119 // { 00120 // ROS_ERROR("predicateCallback failed for door: %s", doorName.c_str()); 00121 // return false; 00122 // } 00123 // geometry_msgs::Pose pose; 00124 // if (predicates[0].value) 00125 // { 00126 // // door is open 00127 // psi->updateObject(doorName, doorIterator->second.openPose.pose); 00128 // } 00129 // else 00130 // { 00131 // // door is closed 00132 // psi->updateObject(doorName, doorIterator->second.closedPose.pose); 00133 // } 00134 // } 00135 // } 00136 // // set robot state 00137 // ROS_ASSERT(parameterList.size() > 1); 00138 // const string& robotStartPose = parameterList[0].value; 00139 // arm_navigation_msgs::RobotState state = psi->getRobotState(); 00140 // ArmState::get("/arm_configurations/side_tuck/position/", "right_arm").replaceJointPositions(state.joint_state); 00141 // ArmState::get("/arm_configurations/side_tuck/position/", "left_arm").replaceJointPositions(state.joint_state); 00142 // fillPoseFromState(state.multi_dof_joint_state.poses[0], robotStartPose, numericalFluentCallback); 00143 // psi->setRobotState(state); 00144 // return psi->sendDiff(); 00145 //} 00146 00147 void planning_scene_navstack_init(int argc, char** argv) 00148 { 00149 navstack_init(argc, argv); 00150 ROS_INFO("%s initialized.", logName.c_str()); 00151 } 00152 00153 double planning_scene_pathCost(const ParameterList & parameterList, 00154 predicateCallbackType predicateCallback, numericalFluentCallbackType numericalFluentCallback, int relaxed) 00155 { 00156 // need this for computing cache key 00157 nav_msgs::GetPlan srv; 00158 if (!fillPathRequest(parameterList, numericalFluentCallback, srv.request)) 00159 { 00160 return INFINITE_COST; 00161 } 00162 00163 // first lookup in the cache if we answered the query already 00164 double cost = 0; 00165 if (g_PathCostCache.get(computePathCacheKey(parameterList[0].value, parameterList[1].value, srv.request.start.pose, srv.request.goal.pose), cost)) 00166 { 00167 return cost; 00168 } 00169 00170 if(relaxed || true) { 00171 std::vector<geometry_msgs::PoseStamped> directPath; 00172 directPath.push_back(srv.request.start); 00173 directPath.push_back(srv.request.goal); 00174 return getPlanCost(directPath); 00175 } 00176 00177 // read state 00178 string robotLocation = parameterList[0].value; 00179 geometry_msgs::Pose robotPose; 00180 map<string, geometry_msgs::Pose> movableObjects; 00181 map<string, string> graspedObjects; 00182 map<string, string> objectsOnStatic; 00183 set<string> openDoors; 00184 // arm_navigation_msgs::PlanningScene world = PlanningSceneInterface::instance()->getCurrentScene(); 00185 if (! TidyupPlanningSceneUpdater::readState(robotLocation, predicateCallback, numericalFluentCallback, robotPose, movableObjects, graspedObjects, objectsOnStatic, openDoors)) 00186 { 00187 ROS_ERROR("%s read state failed.", logName.c_str()); 00188 return INFINITE_COST; 00189 } 00190 // set planning scene 00191 if (! TidyupPlanningSceneUpdater::update(robotPose, movableObjects, graspedObjects, openDoors)) 00192 { 00193 ROS_ERROR("%s update planning scene failed.", logName.c_str()); 00194 return INFINITE_COST; 00195 } 00196 // PlanningSceneInterface::instance()->printDiffToCurrent(world); 00197 return pathCost(parameterList, predicateCallback, numericalFluentCallback, relaxed); 00198 } 00199