Go to the documentation of this file.00001 #include <math.h>
00002 #include <vector>
00003 #include <stdio.h>
00004 #include "nlj_laser/hist.h"
00005 #include "geometry_msgs/PolygonStamped.h"
00006 #include "geometry_msgs/Point32.h"
00007 #define SHIFT 1
00008
00009 Hist hist(sensor_msgs::LaserScan scan, int anglebins) {
00010 int angleHistBin = anglebins;
00011 double angleHistCoef = angleHistBin / (2 * M_PI);
00012 Hist hist(angleHistBin,0);
00013 double px1;
00014 double px2;
00015 double py1;
00016 double py2;
00017 double distance;
00018 px1 = scan.ranges[0] * sin(0 * scan.angle_increment + scan.angle_min);
00019 py1 = -scan.ranges[0] * cos(0 * scan.angle_increment + scan.angle_min);
00020 for(unsigned int i = 1; i < scan.ranges.size() - SHIFT ; i++) {
00021 px2 = scan.ranges[i+SHIFT] * sin((i+SHIFT) * scan.angle_increment + scan.angle_min);
00022 py2 = -scan.ranges[i+SHIFT] * cos((i+SHIFT) * scan.angle_increment + scan.angle_min);
00023 double ath = atan2(py1 - py2, px1 - px2);
00024 distance = sqrt((py1 - py2) * (py1 - py2) + (px1 - px2) * (px1 - px2));
00025 if (distance < 0.1) {
00026
00027
00028 hist[(int) floor((M_PI + ath) * angleHistCoef)]+= 1;
00029 }
00030 px1 = px2;
00031 py1 = py2;
00032 px1 = scan.ranges[i] * sin((i) * scan.angle_increment + scan.angle_min);
00033 py1 = -scan.ranges[i] * cos((i) * scan.angle_increment + scan.angle_min);
00034 }
00035 return hist;
00036 }
00037
00038 int crossCorrelationHist (Hist x , Hist y) {
00039 double sum;
00040 double max;
00041 int maxind;
00042 max = 0;
00043 maxind = 0;
00044 for (unsigned int shift=0; shift<x.size();shift++) {
00045
00046 sum = 0;
00047 for (unsigned int i=0; i<x.size();i++) {
00048 sum += x[i]*y[(i+shift)%y.size()];
00049 }
00050 if (sum > max) {
00051 max = sum;
00052 maxind = shift;
00053 }
00054 }
00055
00056 return maxind;
00057 }
00058
00059
00060 geometry_msgs::Pose2D localize (sensor_msgs::LaserScan a, sensor_msgs::LaserScan b, int angls) {
00061 double transCoef = TRANSCOEF;
00062
00063 int angleHistBin = angls;
00064 double resolution = 2 * M_PI / a.ranges.size();
00065 double angleHistCoef = angleHistBin / (2 * M_PI);
00066
00067 Hist histax (HISTSIZE ,-1);
00068 Hist histay (HISTSIZE ,-1);
00069 Hist histbx (HISTSIZE ,-1);
00070 Hist histby (HISTSIZE ,-1);
00071 Hist histA = hist(a,angleHistBin);
00072 Hist histB = hist(b,angleHistBin);
00073 int angleIndex = crossCorrelationHist(histA,histB);
00074
00075 int histAngleMaxIndex=0;
00076 int histMax = 0;
00077 for (unsigned int i = 0; i < histA.size(); i++) {
00078 if (histMax < histA[i]) {
00079 histMax = histA[i];
00080 histAngleMaxIndex = i;
00081 }
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 for (unsigned int i = 0; i < a.ranges.size(); i++) {
00111 if (a.ranges[i] < 7.9) {
00112 histax[(int) floor(transCoef * a.ranges[i] * cos(i * resolution - histAngleMaxIndex / angleHistCoef)) + HISTSIZEHALF]++;
00113 histay[(int) floor(transCoef * a.ranges[i] * sin(i * resolution - histAngleMaxIndex / angleHistCoef)) + HISTSIZEHALF]++;
00114 }
00115 }
00116
00117 for (unsigned int i = 0; i < b.ranges.size(); i++) {
00118 if (b.ranges[i] < 7.9) {
00119 histbx[(int) floor(transCoef * b.ranges[i] * cos(i * resolution - histAngleMaxIndex / angleHistCoef - (angleIndex) / angleHistCoef)) + HISTSIZEHALF]++;
00120 histby[(int) floor(transCoef * b.ranges[i] * sin(i * resolution - histAngleMaxIndex / angleHistCoef - (angleIndex) / angleHistCoef)) + HISTSIZEHALF]++;
00121 }
00122 }
00123 int xIndex = crossCorrelationHist(histax, histbx);
00124 int yIndex = crossCorrelationHist(histay, histby);
00125 if (xIndex > HISTSIZEHALF) xIndex -= HISTSIZE;
00126 if (yIndex > HISTSIZEHALF) yIndex -= HISTSIZE;
00127
00128 geometry_msgs::Pose2D ret ;
00129 double ty = cos(-histAngleMaxIndex / angleHistCoef) * yIndex / transCoef - sin(-histAngleMaxIndex / angleHistCoef) * xIndex / transCoef;
00130 double tx = (xIndex / transCoef + sin(-histAngleMaxIndex / angleHistCoef) * ty) / cos(-histAngleMaxIndex / angleHistCoef);
00131 ret.x = tx;
00132 ret.y = ty;
00133 ret.theta= 2*M_PI-angleIndex/angleHistCoef;
00134
00135
00136
00137 return ret;
00138 }
00139
00140 double error(sensor_msgs::LaserScan scan,sensor_msgs::LaserScan reference, geometry_msgs::Pose2D goal) {
00141 double rx, ry,sx,sy;
00142 double error = 0;
00143 double distance ;
00144 double min = 9000000;
00145 int count = 0;
00146 geometry_msgs::PolygonStamped poly;
00147 poly.header.frame_id="/mf";
00148 geometry_msgs::PolygonStamped poly2;
00149 poly2.header.frame_id="/mf";
00150 geometry_msgs::Point32 p;
00151 for (unsigned int i = 0 ; i < reference.ranges.size(); i++) {
00152 min = 90000000;
00153 if (reference.ranges[i] < 7.9) {
00154 rx = reference.ranges[i] * sin( (i * reference.angle_increment) + reference.angle_min + goal.theta ) + goal.y;
00155 ry = -reference.ranges[i] * cos( (i * reference.angle_increment) + reference.angle_min + goal.theta) - goal.x;
00156
00157 for (unsigned int j = 0 ; j < scan.ranges.size(); j++) {
00158 if (scan.ranges[j] < 7.9){
00159 sx = scan.ranges[j] * sin( (j * scan.angle_increment) + scan.angle_min);
00160 sy = -scan.ranges[j] * cos( (j * scan.angle_increment) + scan.angle_min);
00161 distance = sqrt((rx-sx)*(rx-sx) + (ry-sy)*(ry-sy));
00162 if (distance < min) {
00163 min = distance;
00164 }
00165 }
00166 }
00167 error += min;
00168 count++;
00169 }
00170 }
00171 return error/count;
00172 }
00173
00174
00175 double error(sensor_msgs::LaserScan scan,sensor_msgs::LaserScan reference, geometry_msgs::Pose2D goal, ros::Publisher draw, ros::Publisher drawRef ) {
00176 double rx, ry,sx,sy;
00177 double error = 0;
00178 double distance ;
00179 double min = 9000000;
00180 int count = 0;
00181 geometry_msgs::PolygonStamped poly;
00182 poly.header.frame_id="/mf";
00183 geometry_msgs::PolygonStamped poly2;
00184 poly2.header.frame_id="/mf";
00185 geometry_msgs::Point32 p;
00186 if (draw!= 0 )
00187 for (unsigned int i = 0 ; i < reference.ranges.size(); i++) {
00188 min = 90000000;
00189 if (reference.ranges[i] < 7.9) {
00190 rx = reference.ranges[i] * sin( (i * reference.angle_increment) + reference.angle_min + goal.theta ) + goal.y;
00191 ry = -reference.ranges[i] * cos( (i * reference.angle_increment) + reference.angle_min + goal.theta) - goal.x;
00192 p.x = rx;
00193 p.y =ry;
00194 poly.polygon.points.push_back(p);
00195 }
00196 if (scan.ranges[i] < 7.9){
00197 sx = scan.ranges[i] * sin( (i * scan.angle_increment) + scan.angle_min );
00198 sy = - scan.ranges[i] * cos( (i * scan.angle_increment) + scan.angle_min );
00199 p.x = sx;
00200 p.y =sy;
00201 poly2.polygon.points.push_back(p);
00202 }
00203 }
00204 for (unsigned int i = 0 ; i < reference.ranges.size(); i++) {
00205 min = 90000000;
00206 if (reference.ranges[i] < 7.9) {
00207 rx = reference.ranges[i] * sin( (i * reference.angle_increment) + reference.angle_min + goal.theta ) + goal.y;
00208 ry = -reference.ranges[i] * cos( (i * reference.angle_increment) + reference.angle_min + goal.theta) - goal.x;
00209
00210 for (unsigned int j = 0 ; j < scan.ranges.size(); j++) {
00211 if (scan.ranges[j] < 7.9){
00212 sx = scan.ranges[j] * sin( (j * scan.angle_increment) + scan.angle_min);
00213 sy = -scan.ranges[j] * cos( (j * scan.angle_increment) + scan.angle_min);
00214 distance = sqrt((rx-sx)*(rx-sx) + (ry-sy)*(ry-sy));
00215 if (distance < min) {
00216 min = distance;
00217 }
00218 }
00219 }
00220 error += min;
00221 count++;
00222 }
00223 }
00224 draw.publish(poly2);
00225 drawRef.publish(poly);
00226 return error/count;
00227 }
00228