00001 #include "tidyup_actions/actionExecutorDetectObjects.h"
00002 #include <pluginlib/class_list_macros.h>
00003 #include <tidyup_msgs/RequestObjectsGraspability.h>
00004 #include "tidyup_utils/planning_scene_interface.h"
00005
00006 PLUGINLIB_DECLARE_CLASS(tidyup_actions, action_executor_detect_objects,
00007 tidyup_actions::ActionExecutorDetectObjects,
00008 continual_planning_executive::ActionExecutorInterface)
00009
00010 namespace tidyup_actions
00011 {
00012 void ActionExecutorDetectObjects::initialize(const std::deque<std::string> & arguments)
00013 {
00014 ActionExecutorService<tidyup_msgs::DetectGraspableObjects>::initialize(arguments);
00015 requestGraspability = false;
00016 string graspabilityServiceName = "/learned_grasping/request_objects_graspability";
00017 tidyLocationName = "table1";
00018
00019 if (arguments.size() >= 3)
00020 {
00021 if (arguments[2] == "NULL")
00022 {
00023 requestGraspability = false;
00024 } else {
00025 graspabilityServiceName = arguments[2];
00026 }
00027 }
00028 if (arguments.size() >= 4)
00029 {
00030 tidyLocationName = arguments[3];
00031 }
00032
00033 ROS_ASSERT(_nh);
00034 if(requestGraspability) {
00035 serviceClientGraspability = _nh->serviceClient<tidyup_msgs::RequestObjectsGraspability>(
00036 graspabilityServiceName);
00037 if(!serviceClientGraspability) {
00038 ROS_FATAL("Could not initialize service for RequestObjectsGraspability.");
00039 }
00040 }
00041 }
00042
00043 bool ActionExecutorDetectObjects::fillGoal(tidyup_msgs::DetectGraspableObjects::Request & goal,
00044 const DurativeAction & a, const SymbolicState & current)
00045 {
00046 if(!PlanningSceneInterface::instance()->resetPlanningScene())
00047 ROS_ERROR("%s: PlanningScene reset failed.", __PRETTY_FUNCTION__);
00048
00049 ROS_ASSERT(a.parameters.size() == 1);
00050 goal.static_object = findStaticObjectForLocation(a.parameters[0], current);
00051 return true;
00052 }
00053
00054 void ActionExecutorDetectObjects::updateState(bool success,
00055 tidyup_msgs::DetectGraspableObjects::Response & response,
00056 const DurativeAction & a, SymbolicState & current)
00057 {
00058 ROS_INFO("DetectObjects returned result");
00059 if(success) {
00060 ROS_INFO("DetectObjects succeeded.");
00061 ROS_ASSERT(a.parameters.size() == 1);
00062 std::string location = a.parameters[0];
00063 current.setBooleanPredicate("searched", location, true);
00064 current.setBooleanPredicate("recent-detected-objects", location, true);
00065
00066 std::vector<tidyup_msgs::GraspableObject>& objects = response.objects;
00067 if(requestGraspability && false) {
00068 ROS_INFO("Requesting graspability.");
00069 tidyup_msgs::RequestObjectsGraspability request;
00070 request.request.objects = objects;
00071 if(!serviceClientGraspability.call(request)) {
00072 ROS_ERROR("Failed to call RequestObjectsGraspability service.");
00073 } else {
00074 objects = request.response.objects;
00075 }
00076 }
00077
00078
00079 string static_object = findStaticObjectForLocation(location, current);
00080 ROS_ASSERT(static_object != "");
00081
00082
00083 Predicate p;
00084 p.name = "on";
00085 p.parameters.push_back("object");
00086 p.parameters.push_back(static_object);
00087 pair<SymbolicState::TypedObjectConstIterator, SymbolicState::TypedObjectConstIterator> objectRange =
00088 current.getTypedObjects().equal_range("movable_object");
00089 for (SymbolicState::TypedObjectConstIterator objectIterator = objectRange.first;
00090 objectIterator != objectRange.second; objectIterator++)
00091 {
00092 string object = objectIterator->second;
00093 p.parameters[0] = object;
00094 bool onStatic = false;
00095 if(current.hasBooleanPredicate(p, &onStatic))
00096 {
00097 if(onStatic) {
00098 current.removeObject(object, true);
00099 }
00100 }
00101 }
00102
00103 for(std::vector<tidyup_msgs::GraspableObject>::iterator it = objects.begin(); it != objects.end(); it++)
00104 {
00105 tidyup_msgs::GraspableObject & object = *it;
00106 current.addObject(object.name, "movable_object");
00107 if(object.pose.header.frame_id.empty()) {
00108 ROS_ERROR("DetectGraspableObjects returned empty frame_id for object: %s", object.name.c_str());
00109 object.pose.header.frame_id = "INVALID_FRAME_ID";
00110 }
00111 current.addObject(object.pose.header.frame_id, "frameid");
00112 current.addObject(object.name, "pose");
00113 current.setObjectFluent("frame-id", object.name, object.pose.header.frame_id);
00114 current.setNumericalFluent("x", object.name, object.pose.pose.position.x);
00115 current.setNumericalFluent("y", object.name, object.pose.pose.position.y);
00116 current.setNumericalFluent("z", object.name, object.pose.pose.position.z);
00117 current.setNumericalFluent("qx", object.name, object.pose.pose.orientation.x);
00118 current.setNumericalFluent("qy", object.name, object.pose.pose.orientation.y);
00119 current.setNumericalFluent("qz", object.name, object.pose.pose.orientation.z);
00120 current.setNumericalFluent("qw", object.name, object.pose.pose.orientation.w);
00121 current.setNumericalFluent("timestamp", object.name, object.pose.header.stamp.toSec());
00122 current.setBooleanPredicate("on", object.name + " " + static_object, true);
00123
00124
00125 current.setBooleanPredicate("tidy-location", object.name + " " + tidyLocationName, true);
00126
00127
00128 if(requestGraspability || true)
00129 {
00130 current.setBooleanPredicate("graspable-from", object.name + " " + location + " left_arm",
00131 object.reachable_left_arm);
00132 current.setBooleanPredicate("graspable-from", object.name + " " + location + " right_arm",
00133 object.reachable_right_arm);
00134 }
00135 else
00136 {
00137 current.setBooleanPredicate("graspable-from", object.name + " " + location + " left_arm", true);
00138 current.setBooleanPredicate("graspable-from", object.name + " " + location + " right_arm", true);
00139 }
00140 }
00141
00142 std::set<std::string> wipeGoalNames;
00143 for(std::vector<tidyup_msgs::WipeGoal>::iterator it = response.wipe_goals.begin(); it != response.wipe_goals.end(); it++) {
00144 tidyup_msgs::WipeGoal & wg = *it;
00145 wipeGoalNames.insert(wg.name);
00146
00147
00148 current.addObject(wg.name, "wipe_point");
00149 if(wg.spot.header.frame_id.empty()) {
00150 ROS_ERROR("DetectGraspableObjects returned empty frame_id for wipe goal: %s", wg.name.c_str());
00151 wg.spot.header.frame_id = "INVALID_FRAME_ID";
00152 }
00153 current.addObject(wg.spot.header.frame_id, "frameid");
00154 current.setObjectFluent("frame-id", wg.name, wg.spot.header.frame_id);
00155 current.setNumericalFluent("x", wg.name, wg.spot.point.x);
00156 current.setNumericalFluent("y", wg.name, wg.spot.point.y);
00157 current.setNumericalFluent("z", wg.name, wg.spot.point.z);
00158 current.setNumericalFluent("timestamp", wg.name, wg.spot.header.stamp.toSec());
00159
00160 Predicate wipedPred;
00161 wipedPred.name = "wiped";
00162 wipedPred.parameters.push_back(wg.name);
00163 bool wiped;
00164 if(!current.hasBooleanPredicate(wipedPred, &wiped)) {
00165 current.setBooleanPredicate("wiped", wg.name, false);
00166 }
00167 current.setBooleanPredicate("wipe-point-on", wg.name + " " + static_object, true);
00168 }
00169
00170
00171
00172 pair<SymbolicState::TypedObjectConstIterator, SymbolicState::TypedObjectConstIterator> wipePointRange =
00173 current.getTypedObjects().equal_range("wipe_point");
00174 std::set<std::string> nonMatchedWipePoints;
00175 for(SymbolicState::TypedObjectConstIterator objectIterator = wipePointRange.first;
00176 objectIterator != wipePointRange.second; objectIterator++) {
00177
00178 Predicate p;
00179 p.name = "wipe-point-on";
00180 string object = objectIterator->second;
00181 p.parameters.push_back(object);
00182 p.parameters.push_back(static_object);
00183
00184 bool wpOn = false;
00185 if(!current.hasBooleanPredicate(p, &wpOn))
00186 continue;
00187 if(!wpOn)
00188 continue;
00189
00190
00191 if(wipeGoalNames.find(object) == wipeGoalNames.end()) {
00192 nonMatchedWipePoints.insert(object);
00193 }
00194 }
00195 for(std::set<std::string>::iterator it = nonMatchedWipePoints.begin(); it != nonMatchedWipePoints.end(); it++) {
00196 ROS_WARN("Removing non matched wipe point: %s.", it->c_str());
00197 current.removeObject(*it, false);
00198
00199
00200 }
00201
00202 if(!PlanningSceneInterface::instance()->resetPlanningScene())
00203 ROS_ERROR("%s: PlanningScene reset failed.", __PRETTY_FUNCTION__);
00204 }
00205 }
00206
00207 std::string ActionExecutorDetectObjects::findStaticObjectForLocation(const std::string& location, const SymbolicState & current) const
00208 {
00209 Predicate p;
00210 string static_object;
00211 p.name = "static-object-at-location";
00212 p.parameters.push_back("object");
00213 p.parameters.push_back(location);
00214 pair<SymbolicState::TypedObjectConstIterator, SymbolicState::TypedObjectConstIterator> objectRange =
00215 current.getTypedObjects().equal_range("static_object");
00216 for (SymbolicState::TypedObjectConstIterator objectIterator = objectRange.first;
00217 objectIterator != objectRange.second; objectIterator++)
00218 {
00219 string object = objectIterator->second;
00220 p.parameters[0] = object;
00221 bool value = false;
00222 if (current.hasBooleanPredicate(p, &value))
00223 {
00224 if (value)
00225 {
00226 static_object = object;
00227 break;
00228 }
00229 }
00230 }
00231 return static_object;
00232 }
00233
00234 };
00235