Monte carlo locatization with robot Mikes - Tomas Kubla
From RoboWiki
Task
We implement MCL-Algorithm (Sebastian THRUN, Wolfram BURGARD, Dieter FOX: PROBABILISTIC ROBOTICS, 1999-2000, page 200)
Model of sensor reading of tag
We were putting robot to many positions in arena and we were logging:
- X position
- Y position
- azimuth
- list of seen tags
When we got data we tried create model of tag
Note: red circle is position of robot, blue cross is position of RFID sensor
Sensor use 4 antennas. Using all antennas sensor see tags around them.
We approximated data with function <math>max(-0.001*abs(x^2 + (2y)^2) + 0.9, 0 )</math>
If sensor is perpendicular to tag it look 2 timer better when sensor is tag parallel
Algorithm
INIT
int init_mcl(){
...
for(int i = 0; i< HYPO_COUNT; i++){
hypo[0][i].x = hypo[1][i].x = rand() % 280;
hypo[0][i].y = hypo[1][i].y = rand() % 280;
hypo[0][i].alpha = hypo[1][i].alpha = rand() % 360;
hypo[0][i].w = hypo[1][i].w = 0.3;
...
}
...
}
UPDATE
int mcl_update(double traveled, int heading){
...
activeHypo = 1-activeHypo;
...
for(int i = 0; i< HYPO_COUNT; i++){
hypo[1-activeHypo][i].x += traveled * cos(normAlpha(hypo[1-activeHypo][i].alpha+heading)*M_PI/180.0);
hypo[1-activeHypo][i].y -= traveled * sin(normAlpha(hypo[1-activeHypo][i].alpha+heading)*M_PI/180.0);
hypo[1-activeHypo][i].alpha = normAlpha(hypo[1-activeHypo][i].alpha + heading);
if((hypo[1-activeHypo][i].x < 0 )||(280 <hypo[1-activeHypo][i].x)||(hypo[1-activeHypo][i].y < 0)||(280 < hypo[1-activeHypo][i].y)){
hypo[1-activeHypo][i].w = 0;
continue;
}
//sensor position
double possx = hypo[1-activeHypo][i].x + cos(hypo[1-activeHypo][i].alpha*M_PI/180.0) * 22;
double possy = hypo[1-activeHypo][i].y - sin(hypo[1-activeHypo][i].alpha*M_PI/180.0) * 22;
//tag position
double minposx;
double minposy;
if(rfid_data.ntags == 0){
...
// searing for best tag
hypo[1-activeHypo][i].w = (1-getp(possx-minposx, possy-minposy)) * hypo[1-activeHypo][i].w / ((1600-636.173)/1600);
}else{
// we hope robot see only one tag
minposx = (rfid_data.x[0]-1)*40;
minposy = (rfid_data.y[0]-1)*40;
hypo[1-activeHypo][i].w = getp(possx-minposx, possy-minposy) * hypo[1-activeHypo][i].w /(636.173 /1600);
}
hypo[1-activeHypo][i].w = fmin(hypo[1-activeHypo][i].w, 1);
}
...
double cumP[HYPO_COUNT];
double last = 0;
for(int i = 0; i<= HYPO_COUNT; i++){
last += hypo[1-activeHypo][i].w;
cumP[i] = last;
}
int i;
for(i = 0; i < HYPO_COUNT*0.9; i++){
double next = (double)rand() / (double)RAND_MAX * last;
for(int j = 0; j< HYPO_COUNT; j++){
if( next <= cumP[j]){
hypo[activeHypo][i].x = hypo[1-activeHypo][j].x + generateGaussianNoise(0, 0.03*traveled);
hypo[activeHypo][i].y = hypo[1-activeHypo][j].y + generateGaussianNoise(0, 0.03*traveled);
hypo[activeHypo][i].alpha = normAlpha(hypo[1-activeHypo][j].alpha + generateGaussianNoise(0, heading*0.05));
hypo[activeHypo][i].w = hypo[1-activeHypo][j].w;
break;
}
}
}
for(; i< HYPO_COUNT; i++){
hypo[0][i].x = hypo[1][i].x = rand() % 280;
hypo[0][i].y = hypo[1][i].y = rand() % 280;
hypo[0][i].alpha = hypo[1][i].alpha = rand() % 360;
hypo[0][i].w = hypo[1][i].w = 0.01;
}
...
}
Source Code
Source code is located on [1]
Some of support scripts and data are here: data.tar
Photo documentation
Video documentation

