Go to the documentation of this file.00001
00002
00003 #include <geometry_msgs/Twist.h>
00004 #include <nav_msgs/Path.h>
00005 #include <nav_msgs/GetPlan.h>
00006
00007 #include <tf/LinearMath/Matrix3x3.h>
00008 #include <tf/LinearMath/Transform.h>
00009 #include <tf/transform_datatypes.h>
00010
00011
00012 #include "SearchPlanner.h"
00013
00014 #include <fstream>
00015
00016 #define SCENE_ANALYZATION_COST (60)
00017
00018 geometry_msgs::PoseWithCovarianceStamped curr_position;
00019
00020
00021
00022
00023
00024 void callbackCurrPos(const geometry_msgs::PoseWithCovarianceStamped::ConstPtr& msg) {
00025 curr_position = *msg;
00026 }
00027
00028
00029 SearchPlannerSimple::SearchPlannerSimple(ros::NodeHandle *node_handle) {
00030
00031 nh = node_handle;
00032
00033 doors.push_back("d3_414b1");
00034 doors.push_back("d3_414b2");
00035 doors.push_back("d3_414a1");
00036 doors.push_back("d3_414a2");
00037
00038 client = new KrClient("/action_executor/execute_plan", true);
00039 client->waitForServer();
00040 goal_door = 0;
00041 srand(time(NULL));
00042 busy = false;
00043 }
00044
00045 bool SearchPlannerSimple::cancelCurrentGoal() {
00046
00047 ros::Publisher pub1 = nh->advertise<actionlib_msgs::GoalID>
00048 ("/move_base/cancel", 1000);
00049 ros::Publisher pub2 = nh->advertise<actionlib_msgs::GoalID>
00050 ("/move_base_interruptable/cancel", 1000);
00051 actionlib_msgs::GoalID msg;
00052
00053 ros::spinOnce();
00054 pub1.publish(msg);
00055
00056 ros::spinOnce();
00057 pub2.publish(msg);
00058
00059 ros::spinOnce();
00060
00061 client->cancelAllGoals();
00062
00063 }
00064
00065 bool SearchPlannerSimple::moveToNextDoor() {
00066
00067 goal_door = (goal_door + rand()) % doors.size();
00068
00069 ROS_INFO_STREAM("going to " << doors.at(goal_door));
00070 bwi_kr_execution::ExecutePlanGoal goal;
00071 bwi_kr_execution::AspRule rule;
00072 bwi_kr_execution::AspFluent fluent;
00073 fluent.name = "not beside";
00074 fluent.variables.push_back(doors.at(goal_door));
00075 rule.body.push_back(fluent);
00076 goal.aspGoal.push_back(rule);
00077
00078 ROS_INFO("sending goal");
00079 client->sendGoalAndWait(goal);
00080 busy = true;
00081
00082 if (client->getState() == actionlib::SimpleClientGoalState::ABORTED) {
00083 ROS_INFO("Aborted");
00084 } else if (client->getState() == actionlib::SimpleClientGoalState::PREEMPTED) {
00085 ROS_INFO("Preempted");
00086 }
00087
00088 else if (client->getState() == actionlib::SimpleClientGoalState::SUCCEEDED) {
00089 ROS_INFO("Succeeded!");
00090 } else
00091 ROS_INFO("Terminated");
00092
00093 busy = false;
00094 return 0;
00095 }
00096
00097
00098 SearchPlanner::SearchPlanner(ros::NodeHandle *node_handle, std::string path_to_yaml, float goal_tolerance) :
00099 tolerance(goal_tolerance) {
00100
00101 nh = node_handle;
00102 client = new KrClient("/action_executor/execute_plan", true);
00103 client->waitForServer();
00104
00105 YAML::Node yaml_positions;
00106 std::ifstream fin(path_to_yaml.c_str());
00107
00108 #ifdef HAVE_NEW_YAMLCPP
00109 yaml_positions = YAML::Load(fin);
00110 #else
00111 YAML::Parser parser(fin);
00112 parser.GetNextDocument(yaml_positions);
00113 #endif
00114
00115
00116
00117 belief = std::vector<float> (yaml_positions.size(), 1.0/yaml_positions.size());
00118
00119 client_make_plan = nh->serviceClient <nav_msgs::GetPlan> ("move_base/GlobalPlanner/make_plan");
00120
00121 pub_simple_goal = nh->advertise<geometry_msgs::PoseStamped>("/move_base_interruptable_simple/goal", 100);
00122
00123 sub_amcl_pose = nh->subscribe("amcl_pose", 100, callbackCurrPos);
00124 ros::Duration(1.0).sleep();
00125
00126 for (int i=0; i<yaml_positions.size(); i++) {
00127 #ifdef HAVE_NEW_YAMLCPP
00128 geometry_msgs::PoseStamped tmp_pose;
00129 tmp_pose.header.frame_id = "level_mux/map";
00130 tmp_pose.pose.position.x = yaml_positions[i][0].as<double>();
00131 tmp_pose.pose.position.y = yaml_positions[i][1].as<double>();
00132 tmp_pose.pose.orientation.z = yaml_positions[i][2].as<double>();
00133 tmp_pose.pose.orientation.w = yaml_positions[i][3].as<double>();
00134 positions.push_back(tmp_pose);
00135 #else
00136 #warning "yaml-cpp version < 0.5.0 does not work"
00137
00138
00139
00140 #endif
00141
00142 }
00143
00144 busy = false;
00145 setTargetDetection(false);
00146 ros::spinOnce();
00147 }
00148
00149 geometry_msgs::PoseStamped SearchPlanner::selectNextScene(const std::vector<float> &belief, int &next_goal_index) {
00150
00151 geometry_msgs::PoseStamped nextScene;
00152
00153 nav_msgs::GetPlan srv;
00154
00155 std::vector<float> distances(belief.size(), 0.0);
00156 std::vector<float> fitness(belief.size(), 0.0);
00157
00158 for (unsigned i=0; i<positions.size(); i++) {
00159
00160 srv.request.tolerance = tolerance;
00161 srv.request.start.header.frame_id = "level_mux/map";
00162 srv.request.start.pose.position.x = curr_position.pose.pose.position.x;
00163 srv.request.start.pose.position.y = curr_position.pose.pose.position.y;
00164
00165 srv.request.goal.header.frame_id = "level_mux/map";
00166 srv.request.goal.pose.position.x = positions[i].pose.position.x;
00167 srv.request.goal.pose.position.y = positions[i].pose.position.y;
00168
00169 client_make_plan.waitForExistence();
00170 if (false == client_make_plan.call(srv))
00171 ROS_ERROR("Failed in calling service for making a path");
00172
00173 distances[i] = srv.response.plan.poses.size();
00174 }
00175
00176 next_goal_index = -1;
00177 float max_value = -1.0;
00178
00179 float resolution;
00180 ros::param::param <float> ("/move_base/local_costmap/resolution", resolution, 0.05);
00181
00182 for (unsigned i=0; i<positions.size(); i++) {
00183
00184 fitness[i] = belief[i] / (distances[i]*resolution + SCENE_ANALYZATION_COST);
00185 next_goal_index = (fitness[i] >= max_value) ? i : next_goal_index;
00186 max_value = (fitness[i] >= max_value) ? fitness[i] : max_value;
00187 }
00188
00189 nextScene = positions[next_goal_index];
00190 nextScene.header.frame_id = "level_mux/map";
00191 return nextScene;
00192 }
00193
00194 void SearchPlanner::moveToNextScene(const geometry_msgs::PoseStamped &msg_goal) {
00195
00196 bool hasArrived = false;
00197 ROS_INFO("Moving to next scene");
00198
00199 busy = true;
00200 ros::Rate r(2);
00201 while (ros::ok() and r.sleep() and !hasArrived and false == getTargetDetection()) {
00202
00203 ros::spinOnce();
00204 float x = msg_goal.pose.position.x - curr_position.pose.pose.position.x;
00205 float y = msg_goal.pose.position.y - curr_position.pose.pose.position.y;
00206 float dis = pow(x*x + y*y, 0.5);
00207
00208
00209
00210 hasArrived = dis < tolerance;
00211
00212
00213
00214 pub_simple_goal.publish(msg_goal);
00215 }
00216 ROS_INFO("Arrived");
00217 busy = false;
00218 }
00219
00220 void SearchPlanner::analyzeScene(float angle, float angular_vel) {
00221
00222 ros::Publisher pub = nh->advertise <geometry_msgs::Twist> ("/cmd_vel", 100);
00223 geometry_msgs::Twist vel;
00224 vel.linear.x = 0;
00225 vel.linear.y = 0;
00226
00227 busy = true;
00228 for (int i=0; i<170; i++) {
00229 if (i<10 or i>160) {
00230 vel.angular.z = 0;
00231 } else if (i<60) {
00232
00233 vel.angular.z = angular_vel;
00234 } else if (i<160) {
00235
00236 vel.angular.z = (-1.0) * angular_vel;
00237 }
00238 ros::spinOnce();
00239 pub.publish(vel);
00240 ros::Duration(0.1).sleep();
00241
00242 if (getTargetDetection())
00243 break;
00244 }
00245 busy = false;
00246 }
00247
00248 void SearchPlanner::updateBelief(int next_goal_index) {
00249
00250 float true_positive_rate, true_negative_rate;
00251 true_positive_rate = true_negative_rate = 0.95;
00252
00253 std::vector <float> tmp_belief (belief);
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 tmp_belief[next_goal_index] = tmp_belief[next_goal_index] *
00265 (1.0 - true_positive_rate) /
00266 ( (tmp_belief[next_goal_index] * (1.0 - true_positive_rate)) +
00267 ((1.0 - tmp_belief[next_goal_index]) * true_negative_rate)
00268 );
00269 float normalizer = 0.0;
00270
00271 for (int i = 0; i < tmp_belief.size(); i++)
00272 normalizer += tmp_belief[i];
00273
00274 for (int i = 0; i < tmp_belief.size(); i++)
00275 belief[i] = tmp_belief[i] / normalizer;
00276 }
00277