Go to the documentation of this file.00001
00007 #include <iostream>
00008 #include <fstream>
00009 #include <vector>
00010
00011 #include "ros/ros.h"
00012 #include "geometry_msgs/Twist.h"
00013 #include "geometry_msgs/Pose2D.h"
00014 #include "geometry_msgs/PolygonStamped.h"
00015 #include "sensor_msgs/LaserScan.h"
00016 #include "lama_interfaces/lama_learning_jockey.h"
00017 #include "lama_interfaces/lama_navigating_jockey.h"
00018 #include "lama_interfaces/lmi_laser_descriptor_set.h"
00019 #include "lama_interfaces/lmi_laser_descriptor_get.h"
00020
00021 #include "hist.h"
00022 namespace li = lama_interfaces;
00023 ros::Publisher pub;
00024 ros::Publisher draw;
00025 ros::Publisher drawRef;
00026 sensor_msgs::LaserScan first;
00027 sensor_msgs::LaserScan last;
00028 std::vector<sensor_msgs::LaserScan> descriptor;
00029
00030 bool assigned;
00031 bool learning = false;
00032 bool navigating = false;
00033 bool interrupted = false;
00034 int angleHistBin=100;
00035 float max_error = 0.2;
00036 float max_distance = 0.3;
00037 float min_distance = 0.05;
00038 unsigned int navigation_index = 0;
00039
00040
00041 void handleLaser(sensor_msgs::LaserScan msg) {
00042 if (learning && !interrupted) {
00043 if (!assigned) {
00044 first = msg;
00045 descriptor.push_back(first);
00046 assigned = true;
00047 }
00048 ROS_DEBUG("LEARNING laser arrived %lu",msg.ranges.size());
00049 hist(msg,100);
00050 geometry_msgs::Pose2D goal = localize(msg, first, angleHistBin);
00051 geometry_msgs::Pose2D fix;
00052 fix.x= fix.y=fix.theta = 0;
00053 float err = error (msg,first,goal,draw,drawRef);
00054 float distance = sqrt (goal.x*goal.x+goal.y*goal.y) ;
00055 if (err > max_error) {
00056 ROS_INFO("error exceeds max limit");
00057 first = last;
00058 descriptor.push_back(first);
00059
00060 }
00061 if (distance > max_distance) {
00062 ROS_DEBUG("distance is longer than max");
00063 first = msg;
00064 descriptor.push_back(first);
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 last = msg;
00080 }
00081
00082 if (navigating) {
00083 if (!assigned) {
00084 navigation_index = 0;
00085 first = descriptor[navigation_index++];
00086 assigned = true;
00087 }
00088 hist(msg,100);
00089 geometry_msgs::Pose2D goal = localize(msg, first, angleHistBin);
00090 geometry_msgs::Pose2D fix;
00091 fix.x= fix.y=fix.theta = 0;
00092 float err = error (msg,first,goal,draw,drawRef);
00093 float distance = sqrt (goal.x*goal.x+goal.y*goal.y) ;
00094 ROS_INFO("error %f goal %f %f ", err, goal.x, goal.y);
00095
00096
00097
00098
00099
00100
00101 if (distance < min_distance) {
00102 ROS_INFO("distance shorter than min");
00103 if (navigation_index < descriptor.size()-1) {
00104 first = descriptor[navigation_index++];
00105 } else {
00106 navigating = false;
00107 }
00108
00109
00110 }
00111
00112
00113 float deviation = atan2(goal.y, goal.x)*0.5;
00114 if (deviation > 0.8) deviation = 0.8;
00115 if (deviation < -0.8) deviation = -0.8;
00116 float speed = 2*distance *(0.8-fabs(deviation)) ;
00117 if (speed < -0.05) speed = -0.05;
00118
00119
00120 geometry_msgs::Twist pub_msg;
00121 pub_msg.linear.x = 0.9*speed;
00122 pub_msg. angular.z = 1.1*deviation;
00123 pub.publish(pub_msg);
00124 last = msg;
00125
00126 }
00127
00128 }
00129
00130 bool navigationCallback(li::lama_navigating_jockeyRequest& request, li::lama_navigating_jockeyResponse& response){
00131 li::lmi_laser_descriptor_get ldg;
00132 switch (request.request_action.action) {
00133 case request.request_action.STOP:
00134 ROS_INFO("STOP");
00135 navigating = false;
00136 interrupted = false;
00137 response.actual_state.state = response.actual_state.DONE;
00138 break;
00139 case request.request_action.TRAVERSE:
00140 if (!interrupted) {
00141 ROS_INFO("navigation START");
00142 descriptor.clear();
00143 ldg.request.id = request.descriptor;
00144 ros::service::call("lmi_laser_descriptor_getter",ldg);
00145 descriptor = ldg.response.descriptor;
00146 assigned = false;
00147 navigating = true;
00148 response.actual_state.state = response.actual_state.TRAVERSING;
00149 } else {
00150 response.actual_state.state = response.actual_state.INTERRUPTED;
00151 }
00152
00153 break;
00154 }
00155 return true;
00156 }
00157
00158 bool serviceCallback(li::lama_learning_jockeyRequest& request, li::lama_learning_jockeyResponse& response){
00159
00160 li::LamaDescriptorIdentifier desc_id;
00161 li::lmi_laser_descriptor_set lds;
00162
00163 switch (request.request_action.action) {
00164 case request.request_action.STOP_LEARN:
00165 ROS_INFO("STOP");
00166 learning = false;
00167 interrupted = false;
00168 lds.request.descriptor = descriptor;
00169 ros::service::call("lmi_laser_descriptor_setter",lds);
00170 desc_id = lds.response.id;
00171 response.descriptor = desc_id;
00172 response.actual_state.state = response.actual_state.DONE;
00173 break;
00174 case request.request_action.START_LEARN:
00175 if (!interrupted) {
00176 descriptor.clear();
00177 assigned = false;
00178 learning = true;
00179 response.actual_state.state = response.actual_state.LEARNING;
00180 } else {
00181 response.actual_state.state = response.actual_state.INTERRUPTED;
00182 }
00183
00184 break;
00185 case request.request_action.INTERRUPT:
00186 if (learning) {
00187 interrupted = true;
00188 learning = false;
00189 response.actual_state.state = response.actual_state.INTERRUPTED;
00190 } else {
00191 response.actual_state.state = response.actual_state.DONE;
00192 }
00193 break;
00194 case request.request_action.CONTINUE:
00195 if (interrupted) {
00196 learning = true;
00197 interrupted = false;
00198 response.actual_state.state = response.actual_state.LEARNING;
00199 } else {
00200 response.actual_state.state = response.actual_state.DONE;
00201 }
00202 break;
00203 default:
00204 if (interrupted) {
00205 response.actual_state.state = response.actual_state.INTERRUPTED;
00206 }
00207 else {
00208 if (learning) {
00209 response.actual_state.state = response.actual_state.LEARNING;
00210 } else {
00211 response.actual_state.state = response.actual_state.DONE;
00212 }
00213 }
00214 }
00215 return true;
00216
00217 }
00218
00219 int main(int argc, char **argv) {
00220
00221 ros::init(argc, argv, "laser_navigating_jockey");
00222 assigned = false;
00223 ros::NodeHandle n;
00224 ros::Subscriber laserHandler = n.subscribe<sensor_msgs::LaserScan> ("base_scan", 50 , handleLaser);
00225 ros::ServiceServer learningJockey = n.advertiseService ( "learning_jockey", serviceCallback);
00226 ros::ServiceServer navigatingJockey = n.advertiseService ( "navigating_jockey", navigationCallback);
00227
00228 pub = n.advertise<geometry_msgs::Twist> ("nav_cmd",1,false);
00229 draw = n.advertise<geometry_msgs::PolygonStamped> ("draw",1,false);
00230 drawRef = n.advertise<geometry_msgs::PolygonStamped> ("draw_reference",1,false);
00231 ROS_INFO("started");
00232 ros::spin();
00233
00234 }
00235
00236 #undef intro
00237