precache_navigation.cpp
Go to the documentation of this file.
00001 #include <ros/ros.h>
00002 #include <tf/transform_listener.h>
00003 #include "planner_modules_pr2/module_param_cache.h"
00004 //#include "hardcoded_facts/geometryPoses.h"
00005 #include "planner_modules_pr2/navstack_module.h"
00006 #include <pluginlib/class_loader.h>
00007 #include "continual_planning_executive/stateCreator.h"
00008 #include "continual_planning_executive/goalCreator.h"
00009 #include <signal.h>
00010 
00011 static pluginlib::ClassLoader<continual_planning_executive::StateCreator>* s_StateCreatorLoader = NULL;
00012 continual_planning_executive::StateCreator* s_StateCreatorRobotLocation = NULL;
00013 continual_planning_executive::StateCreator* s_StateCreatorRobotLocationInRoom = NULL;
00014 
00015 static pluginlib::ClassLoader<continual_planning_executive::GoalCreator>* s_GoalCreatorLoader = NULL;
00016 continual_planning_executive::GoalCreator* s_GoalCreator = NULL;
00017 
00018 bool keepRunning = true;
00019 
00020 //ModuleParamCacheDouble g_PathCostCache;
00021 void signal_handler(int )
00022 {
00023     keepRunning = false;
00024 }
00025 
00026 bool loadStateCreator()
00027 {
00028     try {
00029         // create here with new as it can't go out of scope
00030         s_StateCreatorLoader
00031             = new pluginlib::ClassLoader<continual_planning_executive::StateCreator>
00032             ("continual_planning_executive", "continual_planning_executive::StateCreator");
00033     } catch(pluginlib::PluginlibException & ex) {
00034         // possible reason for failure: no known plugins
00035         ROS_ERROR("Could not instantiate class loader for continual_planning_executive::StateCreator - are there plugins registered? Error: %s", ex.what());
00036         return false;
00037     }
00038 
00039     // This should be name + params
00040     std::string state_creator_name = "tidyup_actions/state_creator_robot_pose";
00041     std::deque<std::string> state_creator_entry;
00042     state_creator_entry.push_back("robot_location");
00043     state_creator_entry.push_back("location");
00044     state_creator_entry.push_back("at-base");
00045     state_creator_entry.push_back("location");
00046 
00047     ROS_INFO("Loading state creator %s", state_creator_name.c_str());
00048     try {
00049         s_StateCreatorRobotLocation = s_StateCreatorLoader->createClassInstance(state_creator_name);
00050         s_StateCreatorRobotLocation->initialize(state_creator_entry);
00051     } catch(pluginlib::PluginlibException & ex) {
00052         ROS_ERROR("Failed to load StateCreator instance for: %s. Error: %s.",
00053                 state_creator_name.c_str(), ex.what());
00054         return false;
00055     }
00056 
00057     state_creator_name = "tidyup_actions/state_creator_robot_location_in_room";
00058     state_creator_entry.clear();
00059     state_creator_entry.push_back("robot_location");
00060     state_creator_entry.push_back("location");
00061 
00062     ROS_INFO("Loading state creator %s", state_creator_name.c_str());
00063     try {
00064         s_StateCreatorRobotLocationInRoom = s_StateCreatorLoader->createClassInstance(state_creator_name);
00065         s_StateCreatorRobotLocationInRoom->initialize(state_creator_entry);
00066     } catch(pluginlib::PluginlibException & ex) {
00067         ROS_ERROR("Failed to load StateCreator instance for: %s. Error: %s.",
00068                 state_creator_name.c_str(), ex.what());
00069         return false;
00070     }
00071 
00072     return true;
00073 }
00074 
00075 bool loadGoalCreator()
00076 {
00077     try {
00078         // create here with new as it can't go out of scope
00079         s_GoalCreatorLoader
00080             = new pluginlib::ClassLoader<continual_planning_executive::GoalCreator>
00081             ("continual_planning_executive", "continual_planning_executive::GoalCreator");
00082     } catch(pluginlib::PluginlibException & ex) {
00083         // possible reason for failure: no known plugins
00084         ROS_ERROR("Could not instantiate class loader for continual_planning_executive::GoalCreator - are there plugins registered? Error: %s", ex.what());
00085         return false;
00086     }
00087 
00088     // This should be name + params
00089     std::string goal_creator_name = "tidyup_actions/goal_creator_tidyup_objects";
00090     std::deque<std::string> goal_creator_entry;
00091 
00092     ROS_INFO("Loading goal creator %s", goal_creator_name.c_str());
00093     try {
00094         s_GoalCreator = s_GoalCreatorLoader->createClassInstance(goal_creator_name);
00095         s_GoalCreator->initialize(goal_creator_entry);
00096     } catch(pluginlib::PluginlibException & ex) {
00097         ROS_ERROR("Failed to load GoalCreator instance for: %s. Error: %s.",
00098                 goal_creator_name.c_str(), ex.what());
00099         return false;
00100     }
00101 
00102     return true;
00103 }
00104 
00105 
00106 void precacheEntry(const std::string & start, const std::string & goal, geometry_msgs::PoseStamped startPose, geometry_msgs::PoseStamped goalPose)
00107 {
00108     nav_msgs::GetPlan srv;
00109     nav_msgs::GetPlan::Request & request = srv.request;
00110     // create the path planning query for service
00111     request.start.header.frame_id = g_WorldFrame;
00112     request.goal.header.frame_id = g_WorldFrame;
00113     request.start.pose = startPose.pose;
00114     request.goal.pose = goalPose.pose;
00115     request.tolerance = g_GoalTolerance;
00116 
00117     // first lookup in the cache if we answered the query already
00118     double cost = modules::INFINITE_COST;
00119     std::string cacheKey = computePathCacheKey(start, goal, srv.request.start.pose, srv.request.goal.pose);
00120     if(g_PathCostCache.get(cacheKey, cost)) {
00121         ROS_INFO("Already got cost %.f for: %s", cost, cacheKey.c_str());
00122         return;
00123     }
00124 
00125     bool callSuccessful;
00126     cost = callPlanningService(srv, start, goal, callSuccessful);
00127     if(callSuccessful) {      // only cache real computed paths (including INFINITE_COST)
00128         //bool isRobotLocation =
00129         //    (parameterList[0].value == "robot_location" || parameterList[1].value == "robot_location");
00130         //g_PathCostCache.set(cacheKey, cost, !isRobotLocation);  // do no param cache robot_location calls
00131         ROS_INFO("Adding cache entry %s = %f", cacheKey.c_str(), cost);
00132         g_PathCostCache.set(cacheKey, cost, true);  // do param cache robot_location calls - they contain the location pose now (safe)
00133     }
00134 }
00135 
00136 bool fillPoseStamped(const std::string & name, const SymbolicState & state, geometry_msgs::PoseStamped & ps)
00137 {
00138     Predicate p;
00139     p.parameters.push_back(name);
00140     p.name = "frame-id";
00141     if(!state.hasObjectFluent(p, &ps.header.frame_id))
00142         return false;
00143     p.name = "x";
00144     if(!state.hasNumericalFluent(p, &ps.pose.position.x))
00145         return false;
00146     p.name = "y";
00147     if(!state.hasNumericalFluent(p, &ps.pose.position.y))
00148         return false;
00149     p.name = "z";
00150     if(!state.hasNumericalFluent(p, &ps.pose.position.z))
00151         return false;
00152     p.name = "qx";
00153     if(!state.hasNumericalFluent(p, &ps.pose.orientation.x))
00154         return false;
00155     p.name = "qy";
00156     if(!state.hasNumericalFluent(p, &ps.pose.orientation.y))
00157         return false;
00158     p.name = "qz";
00159     if(!state.hasNumericalFluent(p, &ps.pose.orientation.z))
00160         return false;
00161     p.name = "qw";
00162     if(!state.hasNumericalFluent(p, &ps.pose.orientation.w))
00163         return false;
00164 
00165     return true;
00166 }
00167 
00168 int main(int argc, char** argv)
00169 {
00170     ros::init(argc, argv, "precache_navigation", ros::init_options::NoSigintHandler);
00171     ros::NodeHandle nh;
00172     tf::TransformListener tfl;
00173 
00174     if(argc != 2 && argc != 4) {
00175         ROS_FATAL("Usage: %s <poses_file> [<start_location_name> <goal_location_name>]", argv[0]);
00176         return 1;
00177     }
00178     std::string startLocationName;
00179     std::string goalLocationName;
00180     if(argc == 4) {
00181         startLocationName = argv[2];
00182         goalLocationName = argv[3];
00183     }
00184 
00185     ROS_INFO("Loading poses from %s", argv[1]);
00186     //GeometryPoses posesLoader;
00187     //if(!posesLoader.load(argv[1])) {
00188     //    ROS_FATAL("Failed to load poses.");
00189     //    return 1;
00190     //}
00191     ros::NodeHandle nhPriv("~");
00192     // for the goal creator
00193     nhPriv.setParam("locations", argv[1]);
00194 
00195     if(!loadStateCreator()) {
00196         ROS_FATAL("Failed to load state creator.");
00197         return 1;
00198     }
00199     if(!loadGoalCreator()) {
00200         ROS_FATAL("Failed to load goal creator.");
00201         return 1;
00202     }
00203 
00204     // Read the params as set for tfd_modules and set them for us, as navstack_init will read those.
00205     nh.param("tfd_modules/trans_speed", g_TransSpeed, g_TransSpeed);
00206     nh.param("tfd_modules/rot_speed", g_RotSpeed, g_RotSpeed);
00207     nhPriv.setParam("trans_speed", g_TransSpeed);
00208     nhPriv.setParam("rot_speed", g_RotSpeed);
00209 
00210     int navstack_argc = 4;
00211     char** navstack_argv = new char*[navstack_argc];
00212     navstack_argv[0] = "precache_navigation";
00213     navstack_argv[1] = "/map";
00214     navstack_argv[2] = "0.05";
00215     navstack_argv[3] = "1";
00216 
00217     navstack_init(navstack_argc, navstack_argv);
00218 
00219     delete[] navstack_argv;
00220 
00221     //const std::map<std::string, geometry_msgs::PoseStamped> & poses = posesLoader.getPoses();
00222 
00223     SymbolicState currentState;
00224     SymbolicState goalState;
00225 
00226     s_GoalCreator->fillStateAndGoal(currentState, goalState);
00227 
00228     while(!s_StateCreatorRobotLocation->fillState(currentState)) {
00229         ROS_WARN("State estimation failed.");
00230         usleep(1000*1000);
00231     }
00232     while(!s_StateCreatorRobotLocationInRoom->fillState(currentState)) {
00233         ROS_WARN("State location in room estimation failed.");
00234         usleep(1000*1000);
00235     }
00236     ROS_INFO("State estimation done.");
00237 
00238     geometry_msgs::PoseStamped robotLocation;
00239     if(!fillPoseStamped("robot_location", currentState, robotLocation)) {
00240         ROS_FATAL("Could not estimate robot location");
00241         return 1;
00242     }
00243 
00244     Predicate robotLocationInRoom;
00245     robotLocationInRoom.name = "location-in-room";
00246     robotLocationInRoom.parameters.push_back("robot_location");
00247     std::string roomRobotLocation;
00248     if(!currentState.hasObjectFluent(robotLocationInRoom, &roomRobotLocation)) {
00249         ROS_ERROR("Could not determine room for robot_location");
00250     }
00251 
00252     const multimap<string, string> & typedObjects = currentState.getTypedObjects();
00253     if(startLocationName.empty() || goalLocationName.empty()) {
00254         ::signal(SIGINT, signal_handler);
00255 
00256         for(multimap<string, string>::const_iterator it1 = typedObjects.begin(); it1 != typedObjects.end(); it1++) {
00257             //printf("At1 %s %s\n", it1->first.c_str(), it1->second.c_str());
00258             if(it1->first != "manipulation_location"
00259                     && it1->first != "door_in_location"
00260                     && it1->first != "door_out_location")
00261                 continue;
00262             Predicate inRoom1;
00263             inRoom1.name = "location-in-room";
00264             inRoom1.parameters.push_back(it1->second);
00265             std::string room1;
00266             if(!currentState.hasObjectFluent(inRoom1, &room1))
00267                 continue;
00268             geometry_msgs::PoseStamped pose1;
00269             if(!fillPoseStamped(it1->second, currentState, pose1)) {
00270                 ROS_ERROR("Could not find pose for %s.", it1->second.c_str());
00271                 continue;
00272             }
00273 
00274             for(multimap<string, string>::const_iterator it2 = typedObjects.begin(); it2 != typedObjects.end(); it2++){
00275                 //printf("At2 %s %s\n", it2->first.c_str(), it2->second.c_str());
00276                 if(it2->first != "manipulation_location"
00277                         && it2->first != "door_in_location"
00278                         && it2->first != "door_out_location")
00279                     continue;
00280                 if(it1->second == it2->second)
00281                     continue;
00282 
00283                 Predicate inRoom2;
00284                 inRoom2.name = "location-in-room";
00285                 inRoom2.parameters.push_back(it2->second);
00286                 std::string room2;
00287                 if(!currentState.hasObjectFluent(inRoom2, &room2))
00288                     continue;
00289 
00290                 if(room1 != room2)
00291                     continue;
00292                 if(it2->first == "door_out_location")
00293                     continue;
00294 
00295                 geometry_msgs::PoseStamped pose2;
00296                 if(!fillPoseStamped(it2->second, currentState, pose2)) {
00297                     ROS_ERROR("Could not find pose for %s.", it2->second.c_str());
00298                     continue;
00299                 }
00300 
00301                 ROS_INFO("Precaching: %s - %s", it1->second.c_str(), it2->second.c_str());
00302                 precacheEntry(it1->second, it2->second, pose1, pose2);
00303             }
00304 
00305             // Also add paths for robot_location
00306             if(room1 != roomRobotLocation)
00307                 continue;
00308             if(it1->first == "door_out_location")
00309                 continue;
00310 
00311             ROS_INFO("Precaching: %s - %s", "robot_location", it1->second.c_str());
00312             precacheEntry("robot_location", it1->second, robotLocation, pose1);
00313 
00314             if(!keepRunning) {
00315                 ROS_WARN("Canceled precached due to SIGINT.");
00316                 break;
00317             }
00318         }
00319     } else {    // use startLocationName, goalLocationName
00320         // FIXME: don't need to handle robot_location explicitly as it's named this in the currentState.
00321         geometry_msgs::PoseStamped pose1;
00322         if(!fillPoseStamped(startLocationName, currentState, pose1)) {
00323             ROS_ERROR("Could not find pose for %s.", startLocationName.c_str());
00324             return 1;
00325         }
00326 
00327         geometry_msgs::PoseStamped pose2;
00328         if(!fillPoseStamped(goalLocationName, currentState, pose2)) {
00329             ROS_ERROR("Could not find pose for %s.", goalLocationName.c_str());
00330             return 1;
00331         }
00332 
00333         ROS_INFO("Precaching: %s - %s", startLocationName.c_str(), goalLocationName.c_str());
00334         precacheEntry(startLocationName, goalLocationName, pose1, pose2);
00335     }
00336 
00337     /*
00338     // location pairs
00339     for(std::map<std::string, geometry_msgs::PoseStamped>::const_iterator it1 = poses.begin(); it1 != poses.end(); it1++) {
00340         for(std::map<std::string, geometry_msgs::PoseStamped>::const_iterator it2 = poses.begin(); it2 != poses.end(); it2++) {
00341             if(it1->first == it2->first)
00342                 continue;
00343             ROS_INFO("Precaching: %s - %s", it1->first.c_str(), it2->first.c_str());
00344             precacheEntry(it1->first, it2->first, it1->second, it2->second);
00345         }
00346     }
00347 
00348     // current location - location
00349     for(std::map<std::string, geometry_msgs::PoseStamped>::const_iterator it1 = poses.begin(); it1 != poses.end(); it1++) {
00350         ROS_INFO("Precaching: %s - %s", it1->first.c_str(), "robot_location");
00351         precacheEntry(it1->first, "robot_location", it1->second, robotLocation);
00352         ROS_INFO("Precaching: %s - %s", "robot_location", it1->first.c_str());
00353         precacheEntry("robot_location", it1->first, robotLocation, it1->second);
00354     }
00355     */
00356     // door needs to be open in planning scene
00357 
00358     ROS_INFO("Precaching done.\n\n\n");
00359 
00360     return 0;
00361 }
 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