segbot_logical_navigator.cpp
Go to the documentation of this file.
00001 
00038 #include <actionlib/client/simple_action_client.h>
00039 #include <actionlib/client/terminal_state.h>
00040 #include <actionlib/server/simple_action_server.h>
00041 #include <boost/date_time/posix_time/posix_time.hpp>
00042 #include <boost/filesystem.hpp>
00043 #include <boost/foreach.hpp>
00044 #include <boost/thread/thread.hpp>
00045 #include <bwi_tools/resource_resolver.h>
00046 #include <message_filters/subscriber.h>
00047 #include <move_base_msgs/MoveBaseAction.h>
00048 #include <multi_level_map_msgs/ChangeCurrentLevel.h>
00049 #include <multi_level_map_msgs/LevelMetaData.h>
00050 #include <multi_level_map_msgs/MultiLevelMapData.h>
00051 #include <multi_level_map_utils/utils.h>
00052 #include <map_msgs/OccupancyGridUpdate.h>
00053 #include <nav_msgs/Odometry.h>
00054 #include <ros/ros.h>
00055 #include <tf/message_filter.h>
00056 #include <tf/transform_datatypes.h>
00057 #include <tf/transform_listener.h>
00058 
00059 #include <bwi_msgs/LogicalNavigationAction.h>
00060 #include <segbot_logical_translator/segbot_logical_translator.h>
00061 
00062 using bwi_planning_common::PlannerAtom;
00063 using bwi_planning_common::NO_DOOR_IDX;
00064 
00065 class SegbotLogicalNavigator : public segbot_logical_translator::SegbotLogicalTranslator {
00066 
00067   public:
00068 
00069     typedef actionlib::SimpleActionServer<bwi_msgs::LogicalNavigationAction> LogicalNavActionServer;
00070 
00071     SegbotLogicalNavigator();
00072     void execute(const bwi_msgs::LogicalNavigationGoalConstPtr &goal);
00073 
00074   protected:
00075 
00076     void senseState(std::vector<PlannerAtom>& observations,
00077         size_t door_idx = NO_DOOR_IDX);
00078     bool approachDoor(const std::string& door_name,
00079         std::vector<PlannerAtom>& observations,
00080         std::string& error_message, bool gothrough = false);
00081     bool senseDoor(const std::string& door_name,
00082         std::vector<PlannerAtom>& observations,
00083         std::string& error_message);
00084 
00085     bool approachObject(const std::string& object_name,
00086         std::vector<PlannerAtom>& observations,
00087         std::string& error_message);
00088 
00089     bool changeFloor(const std::string& new_room,
00090                      const std::string& facing_door,
00091                      std::vector<PlannerAtom>& observations,
00092                      std::string& error_message);
00093 
00094     bool executeNavigationGoal(const geometry_msgs::PoseStamped& pose);
00095     void odometryHandler(const nav_msgs::Odometry::ConstPtr& odom);
00096 
00097     void currentLevelHandler(const multi_level_map_msgs::LevelMetaData::ConstPtr& current_level);
00098     void multimapHandler(const multi_level_map_msgs::MultiLevelMapData::ConstPtr& multimap);
00099 
00100     void publishNavigationMap(bool publish_map_with_doors = false,
00101                               bool wait_for_costmap_change = false);
00102 
00103     float robot_x_;
00104     float robot_y_;
00105     float robot_yaw_;
00106     std::string current_level_id_;
00107 
00108     double door_proximity_distance_;
00109 
00110     boost::shared_ptr<LogicalNavActionServer> execute_action_server_;
00111     bool execute_action_server_started_;
00112 
00113     boost::shared_ptr<actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> > robot_controller_;
00114 
00115     boost::shared_ptr<tf::TransformListener> tf_;
00116     boost::shared_ptr<tf::MessageFilter<nav_msgs::Odometry> > tf_filter_;
00117     boost::shared_ptr<message_filters::Subscriber<nav_msgs::Odometry> > odom_subscriber_;
00118 
00119     ros::Subscriber current_level_subscriber_;
00120     ros::Subscriber multimap_subscriber_;
00121     ros::ServiceClient change_level_client_;
00122     bool change_level_client_available_;
00123     std::vector<multi_level_map_msgs::LevelMetaData> all_levels_;
00124     std::map<std::string, std::vector<bwi_planning_common::Door> > level_to_doors_map_;
00125     std::map<std::string, std::vector<std::string> > level_to_loc_names_map_;
00126     std::map<std::string, std::vector<int32_t> > level_to_loc_map_;
00127 
00128     ros::Publisher navigation_map_publisher_;
00129     bool last_map_published_with_doors_;
00130 
00131     // Subscribe to costmap and costmap updates message to ensure that a published navigation map has been accepted.
00132     void costmapSubscriber(const nav_msgs::OccupancyGrid::ConstPtr& costmap);
00133     void costmapUpdatesSubscriber(const map_msgs::OccupancyGridUpdate::ConstPtr& costmap_updates);
00134     ros::Subscriber costmap_subscriber_;
00135     ros::Subscriber costmap_updates_subscriber_;
00136     bool full_global_costmap_update_;
00137     int global_costmap_width_;
00138 
00139     bool robot_controller_available_;
00140 
00141 };
00142 
00143 SegbotLogicalNavigator::SegbotLogicalNavigator() :
00144     robot_x_(0), robot_y_(0), robot_yaw_(0), current_level_id_(""), execute_action_server_started_(false),
00145     change_level_client_available_(false), robot_controller_available_(false) {
00146 
00147   ROS_INFO("SegbotLogicalNavigator: Advertising services!");
00148 
00149   ros::param::param("~door_proximity_distance", door_proximity_distance_, 2.0);
00150 
00151   // Make sure you publish the default map at least once so that navigation can start up! Ensure this pub is latched.
00152   ros::NodeHandle private_nh("~");
00153   navigation_map_publisher_ = private_nh.advertise<nav_msgs::OccupancyGrid>("map", 1, true);
00154 
00155   robot_controller_.reset(
00156       new actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction>(
00157         "move_base", true));
00158 
00159   tf_.reset(new tf::TransformListener);
00160   odom_subscriber_.reset(new message_filters::Subscriber<nav_msgs::Odometry>);
00161   odom_subscriber_->subscribe(*nh_, "odom", 5);
00162   tf_filter_.reset(new tf::MessageFilter<nav_msgs::Odometry>(
00163         *odom_subscriber_, *tf_, global_frame_id_, 5));
00164   tf_filter_->registerCallback(
00165       boost::bind(&SegbotLogicalNavigator::odometryHandler, this, _1));
00166 
00167   execute_action_server_.reset(new LogicalNavActionServer(*nh_,
00168                                                           "execute_logical_goal",
00169                                                           boost::bind(&SegbotLogicalNavigator::execute, this, _1),
00170                                                           false));
00171 
00172   current_level_subscriber_ = nh_->subscribe("level_mux/current_level",
00173                                              1,
00174                                              &SegbotLogicalNavigator::currentLevelHandler,
00175                                              this);
00176 
00177   multimap_subscriber_ = nh_->subscribe("map_metadata",
00178                                         1,
00179                                         &SegbotLogicalNavigator::multimapHandler,
00180                                         this);
00181 
00182   // Subscribe to the global costmap and Use the local costmap width as a substitute for max raytrace range.
00183   costmap_subscriber_ = nh_->subscribe("move_base/global_costmap/costmap",
00184                                        1,
00185                                        &SegbotLogicalNavigator::costmapSubscriber,
00186                                        this);
00187   costmap_updates_subscriber_ = nh_->subscribe("move_base/global_costmap/costmap_updates",
00188                                                1,
00189                                                &SegbotLogicalNavigator::costmapUpdatesSubscriber,
00190                                                this);
00191   global_costmap_width_ = -1;
00192   full_global_costmap_update_ = false;
00193 }
00194 
00195 void SegbotLogicalNavigator::currentLevelHandler(const multi_level_map_msgs::LevelMetaData::ConstPtr& current_level) {
00196   if (current_level_id_ != current_level->level_id) {
00197     std::string resolved_map_file = bwi_tools::resolveRosResource(current_level->map_file);
00198     ros::param::set("~map_file", resolved_map_file);
00199     std::string resolved_data_directory = bwi_tools::resolveRosResource(current_level->data_directory);
00200     ros::param::set("~data_directory", resolved_data_directory);
00201     if (SegbotLogicalTranslator::initialize()) {
00202       publishNavigationMap();
00203       // Once the translator is initialized, update the current level id.
00204       current_level_id_ = current_level->level_id;
00205     }
00206   }
00207 }
00208 
00209 void SegbotLogicalNavigator::costmapSubscriber(const nav_msgs::OccupancyGrid::ConstPtr& costmap) {
00210   global_costmap_width_ = costmap->info.width;
00211 }
00212 
00213 void SegbotLogicalNavigator::costmapUpdatesSubscriber(const map_msgs::OccupancyGridUpdate::ConstPtr& costmap_updates) {
00214   if (global_costmap_width_ != -1 && costmap_updates->width == global_costmap_width_) {
00215     full_global_costmap_update_ = true;
00216   }
00217 }
00218 
00219 void SegbotLogicalNavigator::multimapHandler(const multi_level_map_msgs::MultiLevelMapData::ConstPtr& multimap) {
00220 
00221   // Read in the objects for each level.
00222   BOOST_FOREACH(const multi_level_map_msgs::LevelMetaData &level, multimap->levels) {
00223     std::string resolved_data_directory = bwi_tools::resolveRosResource(level.data_directory);
00224     std::string doors_file = resolved_data_directory + "/doors.yaml";
00225     std::string locations_file = resolved_data_directory + "/locations.yaml";
00226     bwi_planning_common::readDoorFile(doors_file, level_to_doors_map_[level.level_id]);
00227     bwi_planning_common::readLocationFile(locations_file,
00228                                           level_to_loc_names_map_[level.level_id],
00229                                           level_to_loc_map_[level.level_id]);
00230   }
00231 
00232   // Start the change level service client.
00233   if (!change_level_client_available_) {
00234     change_level_client_available_ = ros::service::waitForService("level_mux/change_current_level", ros::Duration(5.0));
00235     if (change_level_client_available_) {
00236       change_level_client_ = nh_->serviceClient<multi_level_map_msgs::ChangeCurrentLevel>("level_mux/change_current_level");
00237     }
00238   }
00239 
00240 }
00241 
00242 void SegbotLogicalNavigator::publishNavigationMap(bool publish_map_with_doors, bool wait_for_costmap_change) {
00243   if (wait_for_costmap_change) {
00244     full_global_costmap_update_ = false;
00245   }
00246   if (publish_map_with_doors) {
00247     navigation_map_publisher_.publish(map_with_doors_);
00248     last_map_published_with_doors_ = true;
00249   } else {
00250     navigation_map_publisher_.publish(map_);
00251     last_map_published_with_doors_ = false;
00252   }
00253   if (wait_for_costmap_change) {
00254     int counter = 0;
00255     while (!full_global_costmap_update_ && counter < 100) {
00256       boost::this_thread::sleep(boost::posix_time::milliseconds(20));
00257       counter++;
00258     }
00259     if (counter == 100) {
00260       ROS_WARN_STREAM("segbot_logical_navigator: Waited 2 seconds for move_base global costmap to change, but it did not. I'll move forward with the assumption that the map changed and I missed the notification.");
00261     }
00262   }
00263 }
00264 
00265 void SegbotLogicalNavigator::senseState(std::vector<PlannerAtom>& observations, size_t door_idx) {
00266 
00267   PlannerAtom at;
00268   at.name = "at";
00269   size_t location_idx = getLocationIdx(bwi::Point2f(robot_x_, robot_y_));
00270   at.value.push_back(getLocationString(location_idx));
00271   observations.push_back(at);
00272 
00273   size_t num_doors = getNumDoors();
00274   bwi::Point2f robot_loc(robot_x_, robot_y_);
00275   bool beside_found = false;
00276   size_t beside_idx = NO_DOOR_IDX;
00277   size_t facing_idx = NO_DOOR_IDX;
00278 
00279   for (size_t door = 0; door < num_doors; ++door) {
00280 
00281     if (door_idx != NO_DOOR_IDX && door != door_idx) {
00282       // We've only requested information about a specific door (door_idx)
00283       continue;
00284     }
00285 
00286     if ((doors_[door].approach_names[0] != getLocationString(location_idx)) &&
00287         (doors_[door].approach_names[1] != getLocationString(location_idx))) {
00288       // We can't sense the current door since we're not in a location that this door connects.
00289       continue;
00290     }
00291 
00292     bool facing_door =
00293       isRobotFacingDoor(robot_loc, robot_yaw_, door_proximity_distance_, door);
00294     bool beside_door = !beside_found &&
00295       isRobotBesideDoor(robot_loc, robot_yaw_, door_proximity_distance_, door);
00296 
00297     if (facing_door) {
00298       facing_idx = door;
00299       beside_idx = door;
00300       break;
00301     }
00302 
00303     if (beside_door) {
00304       beside_idx = door;
00305       beside_found = true;
00306     }
00307   }
00308 
00309   for (size_t door = 0; door < num_doors; ++door) {
00310 
00311     if ((doors_[door].approach_names[0] != getLocationString(location_idx)) &&
00312         (doors_[door].approach_names[1] != getLocationString(location_idx))) {
00313       // We can't sense the current door since we're not in a location that this door connects.
00314       continue;
00315     }
00316 
00317     PlannerAtom beside_door;
00318     beside_door.value.push_back(getDoorString(door));
00319     beside_door.name = "beside";
00320     if (beside_idx != door) {
00321       beside_door.name = "-" + beside_door.name;
00322     }
00323     observations.push_back(beside_door);
00324 
00325     PlannerAtom facing_door;
00326     facing_door.value.push_back(getDoorString(door));
00327     facing_door.name = "facing";
00328     if (facing_idx != door) {
00329       facing_door.name = "-" + facing_door.name;
00330     }
00331     observations.push_back(facing_door);
00332   }
00333 
00334   // If we are facing a door, also sense whether it is open
00335   if (facing_idx != NO_DOOR_IDX) {
00336     PlannerAtom door_open;
00337     door_open.value.push_back(getDoorString(facing_idx));
00338     if (isDoorOpen(facing_idx)) {
00339       door_open.name = "open";
00340       observations.push_back(door_open);
00341     } else {
00342       door_open.name = "-open";
00343       observations.push_back(door_open);
00344     }
00345   }
00346 }
00347 
00348 bool SegbotLogicalNavigator::executeNavigationGoal(
00349     const geometry_msgs::PoseStamped& pose) {
00350 
00351   if (!robot_controller_available_) {
00352     ROS_INFO("SegbotLogicalNavigator: Need to send command to robot. Waiting for move_base server...");
00353     robot_controller_->waitForServer();
00354     ROS_INFO("SegbotLogicalNavigator:   move_base server found!");
00355   }
00356 
00357   move_base_msgs::MoveBaseGoal goal;
00358   goal.target_pose = pose;
00359   robot_controller_->sendGoal(goal);
00360   bool navigation_request_complete = false;
00361   while (!navigation_request_complete) {
00362     if (execute_action_server_->isPreemptRequested() || !ros::ok()) {
00363       ROS_INFO("SegbotLogicalNavigator: Got pre-empted. Cancelling low level navigation task...");
00364       robot_controller_->cancelGoal();
00365       break;
00366     }
00367     navigation_request_complete = robot_controller_->waitForResult(ros::Duration(0.5));
00368   }
00369 
00370   if (navigation_request_complete) {
00371     actionlib::SimpleClientGoalState state = robot_controller_->getState();
00372     return state == actionlib::SimpleClientGoalState::SUCCEEDED;
00373   }
00374 
00375   // If we're here, then we preempted the request ourselves. Let's mark our current request as not successful.
00376   return false;
00377 }
00378 
00379 void SegbotLogicalNavigator::odometryHandler(
00380     const nav_msgs::Odometry::ConstPtr& odom) {
00381   geometry_msgs::PoseStamped pose_in, pose_out;
00382   pose_in.header = odom->header;
00383   pose_in.pose = odom->pose.pose;
00384   tf_->transformPose(global_frame_id_, pose_in, pose_out);
00385   robot_x_ = pose_out.pose.position.x;
00386   robot_y_ = pose_out.pose.position.y;
00387   //ROS_INFO("OdometryHandler X:%f Y:%f" , robot_x_, robot_y_);
00388 
00389   robot_yaw_ = tf::getYaw(pose_out.pose.orientation);
00390 
00391   if(!execute_action_server_started_) {
00392     execute_action_server_->start();
00393     execute_action_server_started_ = true;
00394   }
00395 }
00396 
00397 bool SegbotLogicalNavigator::approachDoor(const std::string& door_name,
00398     std::vector<PlannerAtom>& observations,
00399     std::string& error_message, bool gothrough) {
00400   error_message = "";
00401 
00402   size_t door_idx = getDoorIdx(door_name);
00403   if (door_idx == NO_DOOR_IDX) {
00404     // Interface failure
00405     error_message = "Could not resolve argument: " + door_name;
00406     return false;
00407   } else {
00408 
00409 
00410     bwi::Point2f approach_pt;
00411     float approach_yaw = 0;
00412     bool door_approachable = false;
00413 
00414     if (!gothrough) {
00415       publishNavigationMap(true, true);
00416       door_approachable = getApproachPoint(door_idx, bwi::Point2f(robot_x_, robot_y_), approach_pt, approach_yaw);
00417     } else {
00418       publishNavigationMap(false, true);
00419       door_approachable = getThroughDoorPoint(door_idx, bwi::Point2f(robot_x_, robot_y_), approach_pt, approach_yaw);
00420     }
00421 
00422     if (door_approachable) {
00423       geometry_msgs::PoseStamped pose;
00424       pose.header.stamp = ros::Time::now();
00425       pose.header.frame_id = global_frame_id_;
00426       pose.pose.position.x = approach_pt.x;
00427       pose.pose.position.y = approach_pt.y;
00428       // std::cout << "approaching " << approach_pt.x << "," << approach_pt.y << std::endl;
00429       tf::quaternionTFToMsg(
00430           tf::createQuaternionFromYaw(approach_yaw), pose.pose.orientation);
00431       bool success = executeNavigationGoal(pose);
00432 
00433       // Publish the observable fluents. Since we're likely going to sense the door, make sure the no-doors map was
00434       // published.
00435       publishNavigationMap(false, true);
00436       senseState(observations, door_idx);
00437 
00438       return success;
00439     } else {
00440       // Planning failure
00441       error_message = "Cannot interact with " + door_name + " from here.";
00442       return false;
00443     }
00444   }
00445 }
00446 
00447 bool SegbotLogicalNavigator::approachObject(const std::string& object_name,
00448     std::vector<PlannerAtom>& observations,
00449     std::string& error_message) {
00450 
00451   error_message = "";
00452   observations.clear();
00453 
00454   if (object_approach_map_.find(object_name) != object_approach_map_.end()) {
00455 
00456     if (!isObjectApproachable(object_name, bwi::Point2f(robot_x_, robot_y_))) {
00457       error_message = "Cannot interact with " + object_name + " from the robot's current location.";
00458       return false;
00459     }
00460 
00461     publishNavigationMap(true);
00462 
00463     geometry_msgs::PoseStamped pose;
00464     pose.header.stamp = ros::Time::now();
00465     pose.header.frame_id = global_frame_id_;
00466     pose.pose = object_approach_map_[object_name];
00467     bool success = executeNavigationGoal(pose);
00468 
00469     // Publish the observable fluents
00470     senseState(observations, NO_DOOR_IDX);
00471     PlannerAtom closeto;
00472     closeto.name = "closeto";
00473     closeto.value.push_back(object_name);
00474     if (!success) {
00475       closeto.name = "-closeto";
00476     }
00477     observations.push_back(closeto);
00478     return success;
00479   }
00480 
00481   error_message = object_name + " does not exist.";
00482   return false;
00483 }
00484 
00485 bool SegbotLogicalNavigator::changeFloor(const std::string& new_room,
00486                                          const std::string& facing_door,
00487                                          std::vector<PlannerAtom>& observations,
00488                                          std::string& error_message) {
00489 
00490   error_message = "";
00491   observations.clear();
00492 
00493   // Make sure we can change floors and all arguments are correct.
00494   std::string floor_name;
00495   if (!change_level_client_available_) {
00496     error_message = "SegbotLogicalNavigator has not received the multimap. Cannot change floors!";
00497     return false;
00498   } else {
00499     bool new_room_found = false;
00500     typedef std::pair<std::string, std::vector<std::string> > Level2LocNamesPair;
00501     BOOST_FOREACH(const Level2LocNamesPair& level_to_loc, level_to_loc_names_map_) {
00502       if (std::find(level_to_loc.second.begin(), level_to_loc.second.end(), new_room) != level_to_loc.second.end()) {
00503         new_room_found = true;
00504         floor_name = level_to_loc.first;
00505         break;
00506       }
00507     }
00508 
00509     if (!new_room_found) {
00510       error_message = "Location " + new_room + " has not been defined on any floor!";
00511       return false;
00512     }
00513   }
00514 
00515   if (current_level_id_ == floor_name) {
00516     error_message = "The robot is already on " + floor_name + " (in which " + new_room + " exists)!";
00517     return false;
00518   }
00519 
00520   // Now find the door on this floor that corresponds to facing_door
00521   bool door_found;
00522   bwi_planning_common::Door door;
00523   BOOST_FOREACH(const bwi_planning_common::Door& floor_door, level_to_doors_map_[floor_name]) {
00524     if (floor_door.name == facing_door) {
00525       door_found = true;
00526       door = floor_door;
00527       break;
00528     }
00529   }
00530 
00531   if (!door_found) {
00532     error_message = "Door " + facing_door + " has not been defined on floor " + floor_name + "!";
00533     return false;
00534   }
00535 
00536   bwi::Point2f approach_pt;
00537   float approach_yaw = 0;
00538   if (door.approach_names[0] == new_room) {
00539     approach_pt = door.approach_points[0];
00540     approach_yaw = door.approach_yaw[0];
00541   } else if (door.approach_names[1] == new_room) {
00542     approach_pt = door.approach_points[1];
00543     approach_yaw = door.approach_yaw[1];
00544   } else {
00545     error_message = "Door " + facing_door + " does not connect location " + new_room + "!";
00546     return false;
00547   }
00548 
00549   multi_level_map_msgs::ChangeCurrentLevel srv;
00550   srv.request.new_level_id = floor_name;
00551   srv.request.publish_initial_pose = true;
00552 
00553   geometry_msgs::PoseWithCovarianceStamped &pose = srv.request.initial_pose;
00554   pose.header.stamp = ros::Time::now();
00555   pose.header.frame_id = global_frame_id_;
00556   pose.pose.pose.position.x = approach_pt.x;
00557   pose.pose.pose.position.y = approach_pt.y;
00558   tf::quaternionTFToMsg( tf::createQuaternionFromYaw(approach_yaw), pose.pose.pose.orientation);
00559   pose.pose.covariance[0] = 0.1;
00560   pose.pose.covariance[7] = 0.1f;
00561   pose.pose.covariance[35] = 0.25f;
00562 
00563   if (change_level_client_.call(srv)) {
00564     if (!srv.response.success) {
00565       error_message = srv.response.error_message;
00566       return false;
00567     }
00568 
00569     // Yea! the call succeeded! Wait for current_level_id_ to be changed once everything gets updated.
00570     ros::Rate r(1);
00571     while (current_level_id_ != floor_name) r.sleep();
00572 
00573     // Publish the observable fluents
00574     senseState(observations);
00575     return true;
00576   } else {
00577     error_message = "ChangeCurrentLevel service call failed for unknown reason.";
00578     return false;
00579   }
00580 }
00581 
00582 bool SegbotLogicalNavigator::senseDoor(const std::string& door_name,
00583     std::vector<PlannerAtom>& observations,
00584     std::string& error_message) {
00585   error_message = "";
00586   size_t door_idx =
00587     bwi_planning_common::resolveDoor(door_name, doors_);
00588   if (door_idx == bwi_planning_common::NO_DOOR_IDX) {
00589     error_message = "Door " + door_name + " does not exist!";
00590     return false;
00591   }
00592   bool door_open = isDoorOpen(door_idx);
00593   PlannerAtom open;
00594   open.name = "open";
00595   if (!door_open) {
00596     open.name = "-" + open.name;
00597   }
00598   open.value.push_back(door_name);
00599   observations.push_back(open);
00600   return true;
00601 }
00602 
00603 void SegbotLogicalNavigator::execute(const bwi_msgs::LogicalNavigationGoalConstPtr& goal) {
00604 
00605   bwi_msgs::LogicalNavigationResult res;
00606   res.observations.clear();
00607 
00608   if (goal->command.name == "approach") {
00609     res.success = approachDoor(goal->command.value[0], res.observations, res.status, false);
00610   } else if (goal->command.name == "gothrough") {
00611     res.success = approachDoor(goal->command.value[0], res.observations,
00612         res.status, true);
00613   } else if (goal->command.name == "sensedoor") {
00614     res.success = senseDoor(goal->command.value[0], res.observations,
00615         res.status);
00616   } else if (goal->command.name == "goto") {
00617     res.success = approachObject(goal->command.value[0], res.observations,
00618         res.status);
00619   } else if (goal->command.name == "changefloor") {
00620     res.success = changeFloor(goal->command.value[0], goal->command.value[1], res.observations, res.status);
00621   } else {
00622     res.success = true;
00623     res.status = "";
00624     senseState(res.observations);
00625   }
00626 
00627   if (res.success) {
00628     execute_action_server_->setSucceeded(res);
00629   } else if (execute_action_server_->isPreemptRequested()) {
00630     execute_action_server_->setPreempted(res);
00631   } else {
00632     execute_action_server_->setAborted(res);
00633   }
00634 
00635 }
00636 
00637 int main(int argc, char *argv[]) {
00638 
00639   ros::init(argc, argv, "segbot_logical_translator");
00640   ros::NodeHandle nh;
00641 
00642   ROS_INFO("SegbotLogicalNavigator: Starting up node...");
00643   SegbotLogicalNavigator handler;
00644   ros::MultiThreadedSpinner spinner(2);
00645   spinner.spin();
00646   ROS_INFO("SegbotLogicalNavigator: Stopping node.");
00647 
00648   return 0;
00649 }


segbot_logical_translator
Author(s): Piyush Khandelwal
autogenerated on Thu Aug 27 2015 15:11:22