22 #define AUTHOR "Vincent Pierlot" 23 #define EMAIL "vpierlot@gmail.com" 25 #define DEFAULT_PROGNAME "triangulation" 34 int m,
tfloat sigmaAngle,
tfloat sigmaBeacon,
unsigned int n,
int O);
35 int test5 (
tfloat x1,
tfloat y1,
tfloat x2,
tfloat y2,
tfloat x3,
tfloat y3,
int m,
tfloat sigmaAngle,
tfloat sigmaBeacon,
unsigned int n,
38 void usage(
const char *progName);
49 void usage(
const char *progName )
52 DEFAULT_PROGNAME
" " VERSION
" by " AUTHOR
" [" EMAIL
"]\n" 53 "Three Object Triangulation algorithms implementation, simulation and benchmarking.\n" 54 "http://www2.ulg.ac.be/telecom/triangulation/\n" 55 "http://hdl.handle.net/2268/89435\n" 56 "Usage: %s [options]\n" 58 " -t int Test to execute (default=5):\n" 59 " 0: gets angles from robot pose (x;y;o). Displays angles (a;b;c).\n" 60 " 1: triangulates from measured angles (a;b;c). Displays robot pose (x;y;o).\n" 61 " 2: gets angles from robot pose (x;y;o) and triangulates with measured angles. Displays angles and pose.\n" 62 " 3: runs triangulation method n times from random positions in the grid [-x,X]*[y,Y]. Displays execution time.\n" 63 " 4: runs triangulation sensitivity analysis from robot position (x;y). (see -O for output).\n" 64 " 5: runs triangulation sensitivity analysis for each point in the grid [-x,X]*[y,Y]. (see -O for output).\n" 65 " Writes PGM images \"map.pgm\" and \"scale.pgm\" in current directory. Displays step, min and max values.\n" 66 " -m int Triangulation method to use (default=1). For all tests.\n" 67 " 1: Pierlot (ToTal) 2: Esteves 3: FontLlagunes (T) 4: Zalama\n" 68 " 5: McGillem (T) 6: McGillem (G) 7: Easton 8: Hmam\n" 69 " 9: Cohen (T) 10: Cohen (G) 11: Cohen (G)* 12: Tsukiyama\n" 70 " 13: Tsukiyama* 14: Madsen 15: Lukic 16: Lukic*\n" 71 " 17: Tienstra 18: Ligas 19: FontLlagunes (G) 20: Kaestner\n" 72 " 21: Collins 22: Cassini\n" 73 " (*) original method from the paper (typically slower than my implementation)\n" 74 " (G) Geometric solution\n" 75 " (T) Trigonometric solution\n" 76 " -x float X robot position. For tests 0, 2, 4. (default=0.0)\n" 77 " X min value of test grid. For tests 3, 5. (default=-2.0)\n" 78 " -y float Y robot position. For tests 0, 2, 4. (default=0.0)\n" 79 " Y min value of test grid. For tests 3, 5. (default=-2.0)\n" 80 " -o float Robot orientation relative to X axis [deg]. For tests 0, 2, 4. (default=0.0)\n" 81 " -a float alpha1 angle [deg]. For test 1. (default=+90)\n" 82 " -b float alpha2 angle [deg]. For test 1. (default=-150)\n" 83 " -c float alpha3 angle [deg]. For test 1. (default=-30)\n" 84 " -1 float X1 beacon1 position. For all tests. (default=0.0)\n" 85 " -2 float Y1 beacon1 position. For all tests. (default=+1.0)\n" 86 " -3 float X2 beacon2 position. For all tests. (default=-0.866)\n" 87 " -4 float Y2 beacon2 position. For all tests. (default=-0.5)\n" 88 " -5 float X3 beacon3 position. For all tests. (default=+0.866)\n" 89 " -6 float Y3 beacon3 position. For all tests. (default=-0.5)\n" 90 " -O int Output of the sensitivity analysis. For tests 4, 5. (default=1)\n" 91 " 1: std deviation of position error, 2: std deviation of orientation error, 3: return value of method.\n" 92 " -X float X max value of test grid. For tests 3, 5. (default=+2.0)\n" 93 " -Y float Y max value of test grid. For tests 3, 5. (default=+2.0)\n" 94 " -p float Discretization step of the test grid. For test 5. (default=0.02)\n" 95 " -A float Standard deviation of the gaussian noise applied to angles in [deg]. For tests 4, 5. (default=0.1)\n" 96 " -B float Standard deviation of the gaussian noise applied to beacons coordinates. For tests 4, 5. (default=0.0)\n" 97 " -n int Number of tests for the execution time and the sensitivity analysis. For tests 3, 4, 5. (default=100)\n" 98 " -M int Map used to display results from the sensitivity analysis. For test 5. (default=2)\n" 101 " 2: Histogram equalized.\n" 102 " 3: Linear after removing outliers (1 percent of the highest values).\n" 103 " 4: Logarithmic after removing outliers (1 percent of the highest values).\n" 104 " -T float Threshold for the sensitivity analysis output (must be >= 0 to be active). For test 5. (default=-1)\n" 105 " -h Displays this help and exit.\n" 112 int main (
int argc ,
char *argv[] )
126 tfloat a1 = 90.0 * DEG2RAD ;
127 tfloat a2 = -150.0 * DEG2RAD ;
128 tfloat a3 = -30.0 * DEG2RAD ;
133 tfloat x2 = -sqrt(3.0)/2 ;
135 tfloat x3 = +sqrt(3.0)/2 ;
139 tfloat sigmaAngle = 0.1 * DEG2RAD ;
140 tfloat sigmaBeacon = 0.0 ;
149 unsigned int n = 100 ;
152 unsigned int map = 2 ;
158 char optString[] =
"t:m:x:y:o:A:B:a:b:c:p:n:O:1:2:3:4:5:6:X:Y:M:T:h" ;
161 while( ( optionChar = getopt(argc, argv, optString) ) != -1 )
165 case '?' :
return -1 ; break ;
166 case 't' : t = atoi( optarg ) ; break ;
167 case 'm' : m = atoi( optarg ) ; break ;
168 case 'x' : xr = atof( optarg ) ; xstart = xr ; break ;
169 case 'y' : yr = atof( optarg ) ; ystart = yr ; break ;
170 case 'o' : or = atof( optarg )*DEG2RAD ; break ;
171 case 'A' : sigmaAngle = atof( optarg )*DEG2RAD ; break ;
172 case 'B' : sigmaBeacon = atof( optarg ) ; break ;
173 case 'a' : a1 = atof( optarg )*DEG2RAD ; break ;
174 case 'b' : a2 = atof( optarg )*DEG2RAD ; break ;
175 case 'c' : a3 = atof( optarg )*DEG2RAD ; break ;
176 case 'p' : step = atof( optarg ) ; break ;
177 case 'n' : n = atoi( optarg ) ; break ;
178 case 'O' : O = atoi( optarg ) ; break ;
179 case '1' : x1 = atof( optarg ) ; break ;
180 case '2' : y1 = atof( optarg ) ; break ;
181 case '3' : x2 = atof( optarg ) ; break ;
182 case '4' : y2 = atof( optarg ) ; break ;
183 case '5' : x3 = atof( optarg ) ; break ;
184 case '6' : y3 = atof( optarg ) ; break ;
185 case 'X' : xend = atof( optarg ) ; break ;
186 case 'Y' : yend = atof( optarg ) ; break ;
187 case 'M' : map = atoi( optarg ) ; break ;
188 case 'T' : thresh = atof( optarg ) ; break ;
189 case 'h' :
usage( argv[0] ) ;
return 0 ;
196 case 0:
return test0( xr , yr , or , x1 , y1 , x2 , y2 , x3 , y3 ) ;
197 case 1:
return test1( a1 , a2 , a3 , x1 , y1 , x2 , y2 , x3 , y3 , m ) ;
198 case 2:
return test2( xr , yr , or , x1 , y1 , x2 , y2 , x3 , y3 , m ) ;
199 case 3:
return test3( x1 , y1 , x2 , y2 , x3 , y3 , m , xstart , xend , ystart , yend , n ) ;
200 case 4:
return test4( xr , yr , or , x1 , y1 , x2 , y2 , x3 , y3 , m , sigmaAngle , sigmaBeacon , n , O ) ;
201 case 5:
return test5( x1 , y1 , x2 , y2 , x3 , y3 , m , sigmaAngle , sigmaBeacon , n , xstart , xend , ystart , yend , step , map , O , thresh ) ;
202 default: fprintf( stderr ,
"main(): Bad test number!\n" ) ;
return -1 ;
217 get_angles( &alpha1 , &alpha2 , &alpha3 , xr , yr , or , x1 , y1 , x2 , y2 , x3 , y3 ) ;
219 printf(
"\nMeasured angles:\n" ) ;
220 printf(
"a = %f [deg]\n" , alpha1*RAD2DEG ) ;
221 printf(
"b = %f [deg]\n" , alpha2*RAD2DEG ) ;
222 printf(
"c = %f [deg]\n\n" , alpha3*RAD2DEG ) ;
239 Q =
triangulationMethod( &x , &y , alpha1 , alpha2 , alpha3 , x1 , y1 , x2 , y2 , x3 , y3 , m ) ;
240 o = atan2( (y1-y) , (x1-x) ) - alpha1 ;
242 printf(
"\nComputed position:\n" ) ;
243 printf(
"x = %f\n", x ) ;
244 printf(
"y = %f\n", y ) ;
245 printf(
"o = %f [deg]\n\n" , o*RAD2DEG ) ;
246 printf(
"Error measure = %f\n\n" , Q) ;
267 get_angles( &alpha1 , &alpha2 , &alpha3 , xr , yr , or , x1 , y1 , x2 , y2 , x3 , y3 ) ;
269 Q =
triangulationMethod( &x , &y , alpha1 , alpha2 , alpha3 , x1 , y1 , x2 , y2 , x3 , y3 , m ) ;
270 o = atan2( (y1-y) , (x1-x) ) - alpha1 ;
272 printf(
"\nMeasured angles:\n" ) ;
273 printf(
"a = %f [deg]\n" , alpha1*RAD2DEG ) ;
274 printf(
"b = %f [deg]\n" , alpha2*RAD2DEG ) ;
275 printf(
"c = %f [deg]\n" , alpha3*RAD2DEG ) ;
276 printf(
"\nComputed position:\n") ;
277 printf(
"x = %f\n" , x ) ;
278 printf(
"y = %f\n" , y ) ;
279 printf(
"o = %f [deg]\n\n" , o*RAD2DEG ) ;
280 printf(
"Error measure = %f\n\n" , Q ) ;
295 tfloat *alpha1M = (
tfloat * ) malloc( n *
sizeof(
tfloat) ) ;
if( alpha1M == NULL )
return -1 ;
296 tfloat *alpha2M = (
tfloat * ) malloc( n *
sizeof(
tfloat) ) ;
if( alpha2M == NULL )
return -1 ;
297 tfloat *alpha3M = (
tfloat * ) malloc( n *
sizeof(
tfloat) ) ;
if( alpha3M == NULL )
return -1 ;
300 double t , tmin = 0.0 ;
305 for( i = 0 ; i < n ; ++i )
307 xi = ( ( (
tfloat) random() / (
tfloat) RAND_MAX ) * ( xend - xstart ) ) + xstart ;
308 yi = ( ( (
tfloat) random() / (
tfloat) RAND_MAX ) * ( yend - ystart ) ) + ystart ;
309 get_angles( &alpha1M[i] , &alpha2M[i] , &alpha3M[i] , xi , yi , 0.0 , x1 , y1 , x2 , y2 , x3 , y3 ) ;
312 for( j = 0 ; j < 10 ; ++j )
316 clock_t startClock = clock() ;
318 struct timespec startTime , endTime ;
319 clock_gettime( CLOCK_PROCESS_CPUTIME_ID , &startTime ) ;
322 for( i = 0 ; i < n ; ++i )
324 triangulationMethod( &xi , &yi , alpha1M[i] , alpha2M[i] , alpha3M[i] , x1 , y1 , x2 , y2 , x3 , y3 , m ) ;
328 clock_t endClock = clock() ;
329 t = ( (double) (endClock - startClock) ) / CLOCKS_PER_SEC ;
331 clock_gettime( CLOCK_PROCESS_CPUTIME_ID , &endTime ) ;
332 t = ( (double) ((endTime.tv_sec-startTime.tv_sec)+(endTime.tv_nsec-startTime.tv_nsec)/1000000000.0)) ;
336 if ( j == 0 ) tmin = t ;
337 if ( t < tmin ) tmin = t ;
340 printf(
"Duration = %10.5f [s]\n" , tmin ) ;
354 int m,
tfloat sigmaAngle,
tfloat sigmaBeacon,
unsigned int n,
int O)
362 get_angles( &alpha1 , &alpha2 , &alpha3 , xr , yr , or , x1 , y1 , x2 , y2 , x3 , y3 ) ;
364 s =
triangulationSensitivity( xr , yr , x1 , y1 , x2 , y2 , x3 , y3 , m , sigmaAngle , sigmaBeacon , n , O , -1 ) ;
366 printf(
"\nMeasured angles:\n" ) ;
367 printf(
"a = %f [deg]\n" , alpha1*RAD2DEG ) ;
368 printf(
"b = %f [deg]\n" , alpha2*RAD2DEG ) ;
369 printf(
"c = %f [deg]\n" , alpha3*RAD2DEG ) ;
373 case 1: printf(
"\nPosition error standard deviation: %f\n" , s ) ; break ;
374 case 2: printf(
"\nOrientation error standard deviation: %f [deg]\n" , s ) ; break ;
375 case 3: printf(
"\nMean error measure: %f\n" , s ) ; break ;
376 default: fprintf( stderr ,
"test4(): Bad output type!\n" ) ;
return -1 ;
386 int test5 (
tfloat x1 ,
tfloat y1 ,
tfloat x2 ,
tfloat y2 ,
tfloat x3 ,
tfloat y3 ,
int m ,
tfloat sigmaAngle ,
tfloat sigmaBeacon ,
unsigned int n ,
389 tfloat xi = 0.0 , yi = 0.0 ;
391 unsigned int p = round( ( xend - xstart ) / step ) + 1 ;
392 unsigned int q = round( ( yend - ystart ) / step ) + 1 ;
394 tfloat *errorPM = (
tfloat * ) malloc( p * q *
sizeof(
tfloat) ) ;
if( errorPM == NULL )
return -1 ;
398 printf(
"Angles standard deviation = %f [deg]\n" , sigmaAngle*RAD2DEG ) ;
399 printf(
"Beacons standard deviation = %f\n" , sigmaBeacon ) ;
400 printf(
"grid X limits = %f to %f\n" , xstart , xend ) ;
401 printf(
"grid Y limits = %f to %f\n" , ystart , yend ) ;
402 printf(
"grid step = %f\n" , step ) ;
404 for( yi = ystart, j = 0 ; j < q ; j++ )
406 for( xi = xstart, i = 0 ; i < p ; i++ )
411 errorPM[j*p + i] =
triangulationSensitivity( xi , yi , x1 , y1 , x2 , y2 , x3 , y3 , m , sigmaAngle , sigmaBeacon , n , O , thresh ) ;
void usage(const char *progName)
Print usage informations.
double tfloat
Defines the type for float/double.