SimulatedChangeFloor.cpp
Go to the documentation of this file.
00001 #include "SimulatedChangeFloor.h"
00002 
00003 #include <boost/foreach.hpp>
00004 
00005 #include "ActionFactory.h"
00006 #include "../StaticFacts.h"
00007 
00008 #include "bwi_kr_execution/UpdateFluents.h"
00009 #include "ros/console.h"
00010 #include "ros/ros.h"
00011 
00012 #include <actionlib/client/simple_action_client.h>
00013 #include <bwi_msgs/DoorHandlerInterface.h>
00014 #include <bwi_msgs/LogicalNavigationAction.h>
00015 #include <bwi_msgs/ResolveChangeFloor.h>
00016 #include <bwi_msgs/RobotTeleporterInterface.h>
00017 
00018 namespace bwi_krexec {
00019 
00020 SimulatedChangeFloor::SimulatedChangeFloor() :
00021              robot_teleported(false),
00022              done(false),
00023              failed(false) {}
00024 
00025 void SimulatedChangeFloor::run() {
00026 
00027   if (!done) {
00028   
00029     // Get the doors for this elevator.
00030     std::string facing_door;
00031     std::list<actasp::AspAtom> static_facts = StaticFacts::staticFacts(); 
00032     BOOST_FOREACH(const actasp::AspAtom fact, static_facts) {
00033       if (fact.getName() == "hasdoor") {
00034         std::vector<std::string> params = fact.getParameters();
00035         if (params[0] == dest_room) {
00036           // NOTE: This makes the assumption that an elevator room only has a single door, which is true for GDC.
00037           facing_door = params[1];
00038           break;
00039         }
00040       }
00041     }
00042 
00043     if (facing_door.empty()) {
00044       ROS_ERROR_STREAM("Unable to retrieve door we're facing for destination " << dest_room << ". Cannot complete action!");
00045       failed = true;
00046       done = true;
00047     } else {
00048 
00049       if (!robot_teleported) {
00050 
00051         // Resolve the location to which the robot needs to be teleported to.
00052         ros::NodeHandle n;
00053         ros::ServiceClient change_floor_resolution_client = 
00054           n.serviceClient<bwi_msgs::ResolveChangeFloor>("resolve_change_floor");
00055         change_floor_resolution_client.waitForExistence();
00056 
00057         bwi_msgs::ResolveChangeFloor rcf;
00058         rcf.request.new_room = dest_room;
00059         rcf.request.facing_door = facing_door;
00060         if (change_floor_resolution_client.call(rcf) && rcf.response.success) {
00061 
00062           // Teleport robot to resolved location.
00063           ros::ServiceClient robot_teleporter_client = 
00064             n.serviceClient<bwi_msgs::RobotTeleporterInterface>("teleport_robot");
00065           robot_teleporter_client.waitForExistence();
00066 
00067           bwi_msgs::RobotTeleporterInterface rti;
00068           rti.request.pose = rcf.response.pose.pose.pose;
00069 
00070           if (robot_teleporter_client.call(rti) && rti.response.success) {
00071             robot_teleported = true;
00072             robot_teleportation_start_time = ros::Time::now();
00073           } else {
00074             ROS_ERROR_STREAM("Failed robot teleportation to pose " << rti.request.pose);
00075             failed = true;
00076             done = true;
00077           }
00078         } else {
00079           ROS_ERROR_STREAM("Change floor resolution failed for room " << dest_room << " and door " << facing_door);
00080           failed = true;
00081           done = true;
00082         }
00083 
00084       } else {
00085 
00086         if (ros::Time::now() - robot_teleportation_start_time > ros::Duration(10.0f)) {
00087 
00088           // Open Elevator door.
00089           ros::NodeHandle n;
00090           ros::ServiceClient door_client = n.serviceClient<bwi_msgs::DoorHandlerInterface> ("/update_doors");
00091           door_client.waitForExistence();
00092 
00093           bwi_msgs::DoorHandlerInterface dhi;
00094 
00095           dhi.request.all_doors = false;
00096           dhi.request.door = facing_door;
00097           dhi.request.open = true;
00098           dhi.request.open_timeout = 30.0f;
00099 
00100           door_client.call(dhi);
00101 
00102           // Attempt to change the robot's location to this floor and location.
00103           boost::shared_ptr<actionlib::SimpleActionClient<bwi_msgs::LogicalNavigationAction> > lnac;
00104           lnac.reset(new actionlib::SimpleActionClient<bwi_msgs::LogicalNavigationAction>("execute_logical_goal",
00105                                                                                                            true));
00106           lnac->waitForServer();
00107           bwi_msgs::LogicalNavigationGoal goal;
00108           goal.command.name = "changefloor";
00109           goal.command.value.push_back(dest_room);
00110           goal.command.value.push_back(facing_door);
00111           lnac->sendGoal(goal);
00112           lnac->waitForResult();
00113 
00114           // Update knowledge base to reflect change in position.
00115           ros::ServiceClient krClient = n.serviceClient<bwi_kr_execution::UpdateFluents> ( "update_fluents" );
00116           krClient.waitForExistence();
00117           bwi_kr_execution::UpdateFluents uf;
00118 
00119           bwi_kr_execution::AspFluent open_door;
00120           open_door.name = "open";
00121           open_door.variables.push_back(facing_door);
00122 
00123           bwi_kr_execution::AspFluent face_door;
00124           face_door.name = "facing";
00125           face_door.variables.push_back(facing_door);
00126 
00127           bwi_kr_execution::AspFluent beside_door;
00128           beside_door.name = "beside";
00129           beside_door.variables.push_back(facing_door);
00130 
00131           bwi_kr_execution::AspFluent at_loc;
00132           at_loc.name = "at";
00133           at_loc.variables.push_back(dest_room);
00134 
00135           uf.request.fluents.push_back(open_door);
00136           uf.request.fluents.push_back(face_door);
00137           uf.request.fluents.push_back(beside_door);
00138           uf.request.fluents.push_back(at_loc);
00139           krClient.call(uf);
00140 
00141           done = true;
00142         }
00143       }
00144     }
00145   }
00146 
00147 }
00148 
00149 bool SimulatedChangeFloor::hasFinished() const {
00150   return done;
00151 }
00152 
00153 bool SimulatedChangeFloor::hasFailed() const {
00154   return failed;
00155 }
00156 
00157 actasp::Action *SimulatedChangeFloor::cloneAndInit(const actasp::AspFluent & fluent) const {
00158   SimulatedChangeFloor *other = new SimulatedChangeFloor();
00159   other->dest_room = fluent.getParameters().at(0);
00160   return other;
00161 }
00162 
00163 std::vector<std::string> SimulatedChangeFloor::getParameters() const {
00164   return std::vector<std::string>(1, dest_room);
00165 }
00166 
00167 //if you want the action to be available only in simulation, or only
00168 //on the robot, use the constructor that also takes a boolean.
00169 ActionFactory simulatedChangeFloor(new SimulatedChangeFloor(), true);
00170 
00171 }


bwi_kr_execution
Author(s): Matteo Leonetti, Piyush Khandelwal
autogenerated on Thu Jun 6 2019 17:57:37