00001 #include <ros/ros.h>
00002 #include <tf/transform_listener.h>
00003 #include "planner_modules_pr2/module_param_cache.h"
00004
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
00021 void signal_handler(int )
00022 {
00023 keepRunning = false;
00024 }
00025
00026 bool loadStateCreator()
00027 {
00028 try {
00029
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
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
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
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
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
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
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
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) {
00128
00129
00130
00131 ROS_INFO("Adding cache entry %s = %f", cacheKey.c_str(), cost);
00132 g_PathCostCache.set(cacheKey, cost, true);
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
00187
00188
00189
00190
00191 ros::NodeHandle nhPriv("~");
00192
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
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
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
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
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
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 {
00320
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
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 ROS_INFO("Precaching done.\n\n\n");
00359
00360 return 0;
00361 }