00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <assert.h>
00029 #include <math.h>
00030 #include <stdlib.h>
00031 #include <time.h>
00032
00033 #include "pf.h"
00034 #include "pf_pdf.h"
00035 #include "pf_kdtree.h"
00036
00037
00038
00039
00040 static int pf_resample_limit(pf_t *pf, int k);
00041
00042
00043 static void pf_cluster_stats(pf_t *pf, pf_sample_set_t *set);
00044
00045
00046
00047 pf_t *pf_alloc(int min_samples, int max_samples,
00048 double alpha_slow, double alpha_fast,
00049 pf_init_model_fn_t random_pose_fn, void *random_pose_data)
00050 {
00051 int i, j;
00052 pf_t *pf;
00053 pf_sample_set_t *set;
00054 pf_sample_t *sample;
00055
00056 srand48(time(NULL));
00057
00058 pf = calloc(1, sizeof(pf_t));
00059
00060 pf->random_pose_fn = random_pose_fn;
00061 pf->random_pose_data = random_pose_data;
00062
00063 pf->min_samples = min_samples;
00064 pf->max_samples = max_samples;
00065
00066
00067
00068
00069
00070
00071 pf->pop_err = 0.01;
00072 pf->pop_z = 3;
00073 pf->dist_threshold = 0.5;
00074
00075 pf->current_set = 0;
00076 for (j = 0; j < 2; j++)
00077 {
00078 set = pf->sets + j;
00079
00080 set->sample_count = max_samples;
00081 set->samples = calloc(max_samples, sizeof(pf_sample_t));
00082
00083 for (i = 0; i < set->sample_count; i++)
00084 {
00085 sample = set->samples + i;
00086 sample->pose.v[0] = 0.0;
00087 sample->pose.v[1] = 0.0;
00088 sample->pose.v[2] = 0.0;
00089 sample->weight = 1.0 / max_samples;
00090 }
00091
00092
00093 set->kdtree = pf_kdtree_alloc(3 * max_samples);
00094
00095 set->cluster_count = 0;
00096 set->cluster_max_count = max_samples;
00097 set->clusters = calloc(set->cluster_max_count, sizeof(pf_cluster_t));
00098
00099 set->mean = pf_vector_zero();
00100 set->cov = pf_matrix_zero();
00101 }
00102
00103 pf->w_slow = 0.0;
00104 pf->w_fast = 0.0;
00105
00106 pf->alpha_slow = alpha_slow;
00107 pf->alpha_fast = alpha_fast;
00108
00109
00110 pf_init_converged(pf);
00111
00112 return pf;
00113 }
00114
00115
00116 void pf_free(pf_t *pf)
00117 {
00118 int i;
00119
00120 for (i = 0; i < 2; i++)
00121 {
00122 free(pf->sets[i].clusters);
00123 pf_kdtree_free(pf->sets[i].kdtree);
00124 free(pf->sets[i].samples);
00125 }
00126 free(pf);
00127
00128 return;
00129 }
00130
00131
00132 void pf_init(pf_t *pf, pf_vector_t mean, pf_matrix_t cov)
00133 {
00134 int i;
00135 pf_sample_set_t *set;
00136 pf_sample_t *sample;
00137 pf_pdf_gaussian_t *pdf;
00138
00139 set = pf->sets + pf->current_set;
00140
00141
00142 pf_kdtree_clear(set->kdtree);
00143
00144 set->sample_count = pf->max_samples;
00145
00146 pdf = pf_pdf_gaussian_alloc(mean, cov);
00147
00148
00149 for (i = 0; i < set->sample_count; i++)
00150 {
00151 sample = set->samples + i;
00152 sample->weight = 1.0 / pf->max_samples;
00153 sample->pose = pf_pdf_gaussian_sample(pdf);
00154
00155
00156 pf_kdtree_insert(set->kdtree, sample->pose, sample->weight);
00157 }
00158
00159 pf->w_slow = pf->w_fast = 0.0;
00160
00161 pf_pdf_gaussian_free(pdf);
00162
00163
00164 pf_cluster_stats(pf, set);
00165
00166
00167 pf_init_converged(pf);
00168
00169 return;
00170 }
00171
00172
00173
00174 void pf_init_model(pf_t *pf, pf_init_model_fn_t init_fn, void *init_data)
00175 {
00176 int i;
00177 pf_sample_set_t *set;
00178 pf_sample_t *sample;
00179
00180 set = pf->sets + pf->current_set;
00181
00182
00183 pf_kdtree_clear(set->kdtree);
00184
00185 set->sample_count = pf->max_samples;
00186
00187
00188 for (i = 0; i < set->sample_count; i++)
00189 {
00190 sample = set->samples + i;
00191 sample->weight = 1.0 / pf->max_samples;
00192 sample->pose = (*init_fn) (init_data);
00193
00194
00195 pf_kdtree_insert(set->kdtree, sample->pose, sample->weight);
00196 }
00197
00198 pf->w_slow = pf->w_fast = 0.0;
00199
00200
00201 pf_cluster_stats(pf, set);
00202
00203
00204 pf_init_converged(pf);
00205
00206 return;
00207 }
00208
00209 void pf_init_converged(pf_t *pf){
00210 pf_sample_set_t *set;
00211 set = pf->sets + pf->current_set;
00212 set->converged = 0;
00213 pf->converged = 0;
00214 }
00215
00216 int pf_update_converged(pf_t *pf)
00217 {
00218 int i;
00219 pf_sample_set_t *set;
00220 pf_sample_t *sample;
00221 double total;
00222
00223 set = pf->sets + pf->current_set;
00224 double mean_x = 0, mean_y = 0;
00225
00226 for (i = 0; i < set->sample_count; i++){
00227 sample = set->samples + i;
00228
00229 mean_x += sample->pose.v[0];
00230 mean_y += sample->pose.v[1];
00231 }
00232 mean_x /= set->sample_count;
00233 mean_y /= set->sample_count;
00234
00235 for (i = 0; i < set->sample_count; i++){
00236 sample = set->samples + i;
00237 if(fabs(sample->pose.v[0] - mean_x) > pf->dist_threshold ||
00238 fabs(sample->pose.v[1] - mean_y) > pf->dist_threshold){
00239 set->converged = 0;
00240 pf->converged = 0;
00241 return 0;
00242 }
00243 }
00244 set->converged = 1;
00245 pf->converged = 1;
00246 return 1;
00247 }
00248
00249
00250 void pf_update_action(pf_t *pf, pf_action_model_fn_t action_fn, void *action_data)
00251 {
00252 pf_sample_set_t *set;
00253
00254 set = pf->sets + pf->current_set;
00255
00256 (*action_fn) (action_data, set);
00257
00258 return;
00259 }
00260
00261
00262 #include <float.h>
00263
00264 void pf_update_sensor(pf_t *pf, pf_sensor_model_fn_t sensor_fn, void *sensor_data)
00265 {
00266 int i;
00267 pf_sample_set_t *set;
00268 pf_sample_t *sample;
00269 double total;
00270
00271 set = pf->sets + pf->current_set;
00272
00273
00274 total = (*sensor_fn) (sensor_data, set);
00275
00276 if (total > 0.0)
00277 {
00278
00279 double w_avg=0.0;
00280 for (i = 0; i < set->sample_count; i++)
00281 {
00282 sample = set->samples + i;
00283 w_avg += sample->weight;
00284 sample->weight /= total;
00285 }
00286
00287 w_avg /= set->sample_count;
00288 if(pf->w_slow == 0.0)
00289 pf->w_slow = w_avg;
00290 else
00291 pf->w_slow += pf->alpha_slow * (w_avg - pf->w_slow);
00292 if(pf->w_fast == 0.0)
00293 pf->w_fast = w_avg;
00294 else
00295 pf->w_fast += pf->alpha_fast * (w_avg - pf->w_fast);
00296
00297
00298 }
00299 else
00300 {
00301
00302 for (i = 0; i < set->sample_count; i++)
00303 {
00304 sample = set->samples + i;
00305 sample->weight = 1.0 / set->sample_count;
00306 }
00307 }
00308
00309 return;
00310 }
00311
00312
00313
00314 void pf_update_resample(pf_t *pf)
00315 {
00316 int i;
00317 double total;
00318 pf_sample_set_t *set_a, *set_b;
00319 pf_sample_t *sample_a, *sample_b;
00320
00321
00322
00323
00324 double* c;
00325
00326 double w_diff;
00327
00328 set_a = pf->sets + pf->current_set;
00329 set_b = pf->sets + (pf->current_set + 1) % 2;
00330
00331
00332
00333
00334 c = (double*)malloc(sizeof(double)*(set_a->sample_count+1));
00335 c[0] = 0.0;
00336 for(i=0;i<set_a->sample_count;i++)
00337 c[i+1] = c[i]+set_a->samples[i].weight;
00338
00339
00340 pf_kdtree_clear(set_b->kdtree);
00341
00342
00343 total = 0;
00344 set_b->sample_count = 0;
00345
00346 w_diff = 1.0 - pf->w_fast / pf->w_slow;
00347 if(w_diff < 0.0)
00348 w_diff = 0.0;
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 while(set_b->sample_count < pf->max_samples)
00362 {
00363 sample_b = set_b->samples + set_b->sample_count++;
00364
00365 if(drand48() < w_diff)
00366 sample_b->pose = (pf->random_pose_fn)(pf->random_pose_data);
00367 else
00368 {
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 double r;
00395 r = drand48();
00396 for(i=0;i<set_a->sample_count;i++)
00397 {
00398 if((c[i] <= r) && (r < c[i+1]))
00399 break;
00400 }
00401 assert(i<set_a->sample_count);
00402
00403 sample_a = set_a->samples + i;
00404
00405 assert(sample_a->weight > 0);
00406
00407
00408 sample_b->pose = sample_a->pose;
00409 }
00410
00411 sample_b->weight = 1.0;
00412 total += sample_b->weight;
00413
00414
00415 pf_kdtree_insert(set_b->kdtree, sample_b->pose, sample_b->weight);
00416
00417
00418 if (set_b->sample_count > pf_resample_limit(pf, set_b->kdtree->leaf_count))
00419 break;
00420 }
00421
00422
00423 if(w_diff > 0.0)
00424 pf->w_slow = pf->w_fast = 0.0;
00425
00426
00427
00428
00429 for (i = 0; i < set_b->sample_count; i++)
00430 {
00431 sample_b = set_b->samples + i;
00432 sample_b->weight /= total;
00433 }
00434
00435
00436 pf_cluster_stats(pf, set_b);
00437
00438
00439 pf->current_set = (pf->current_set + 1) % 2;
00440
00441 pf_update_converged(pf);
00442
00443 free(c);
00444 return;
00445 }
00446
00447
00448
00449
00450 int pf_resample_limit(pf_t *pf, int k)
00451 {
00452 double a, b, c, x;
00453 int n;
00454
00455 if (k <= 1)
00456 return pf->max_samples;
00457
00458 a = 1;
00459 b = 2 / (9 * ((double) k - 1));
00460 c = sqrt(2 / (9 * ((double) k - 1))) * pf->pop_z;
00461 x = a - b + c;
00462
00463 n = (int) ceil((k - 1) / (2 * pf->pop_err) * x * x * x);
00464
00465 if (n < pf->min_samples)
00466 return pf->min_samples;
00467 if (n > pf->max_samples)
00468 return pf->max_samples;
00469
00470 return n;
00471 }
00472
00473
00474
00475 void pf_cluster_stats(pf_t *pf, pf_sample_set_t *set)
00476 {
00477 int i, j, k, cidx;
00478 pf_sample_t *sample;
00479 pf_cluster_t *cluster;
00480
00481
00482 double m[4], c[2][2];
00483 size_t count;
00484 double weight;
00485
00486
00487 pf_kdtree_cluster(set->kdtree);
00488
00489
00490 set->cluster_count = 0;
00491
00492 for (i = 0; i < set->cluster_max_count; i++)
00493 {
00494 cluster = set->clusters + i;
00495 cluster->count = 0;
00496 cluster->weight = 0;
00497 cluster->mean = pf_vector_zero();
00498 cluster->cov = pf_matrix_zero();
00499
00500 for (j = 0; j < 4; j++)
00501 cluster->m[j] = 0.0;
00502 for (j = 0; j < 2; j++)
00503 for (k = 0; k < 2; k++)
00504 cluster->c[j][k] = 0.0;
00505 }
00506
00507
00508 count = 0;
00509 weight = 0.0;
00510 set->mean = pf_vector_zero();
00511 set->cov = pf_matrix_zero();
00512 for (j = 0; j < 4; j++)
00513 m[j] = 0.0;
00514 for (j = 0; j < 2; j++)
00515 for (k = 0; k < 2; k++)
00516 c[j][k] = 0.0;
00517
00518
00519 for (i = 0; i < set->sample_count; i++)
00520 {
00521 sample = set->samples + i;
00522
00523
00524
00525
00526 cidx = pf_kdtree_get_cluster(set->kdtree, sample->pose);
00527 assert(cidx >= 0);
00528 if (cidx >= set->cluster_max_count)
00529 continue;
00530 if (cidx + 1 > set->cluster_count)
00531 set->cluster_count = cidx + 1;
00532
00533 cluster = set->clusters + cidx;
00534
00535 cluster->count += 1;
00536 cluster->weight += sample->weight;
00537
00538 count += 1;
00539 weight += sample->weight;
00540
00541
00542 cluster->m[0] += sample->weight * sample->pose.v[0];
00543 cluster->m[1] += sample->weight * sample->pose.v[1];
00544 cluster->m[2] += sample->weight * cos(sample->pose.v[2]);
00545 cluster->m[3] += sample->weight * sin(sample->pose.v[2]);
00546
00547 m[0] += sample->weight * sample->pose.v[0];
00548 m[1] += sample->weight * sample->pose.v[1];
00549 m[2] += sample->weight * cos(sample->pose.v[2]);
00550 m[3] += sample->weight * sin(sample->pose.v[2]);
00551
00552
00553 for (j = 0; j < 2; j++)
00554 for (k = 0; k < 2; k++)
00555 {
00556 cluster->c[j][k] += sample->weight * sample->pose.v[j] * sample->pose.v[k];
00557 c[j][k] += sample->weight * sample->pose.v[j] * sample->pose.v[k];
00558 }
00559 }
00560
00561
00562 for (i = 0; i < set->cluster_count; i++)
00563 {
00564 cluster = set->clusters + i;
00565
00566 cluster->mean.v[0] = cluster->m[0] / cluster->weight;
00567 cluster->mean.v[1] = cluster->m[1] / cluster->weight;
00568 cluster->mean.v[2] = atan2(cluster->m[3], cluster->m[2]);
00569
00570 cluster->cov = pf_matrix_zero();
00571
00572
00573 for (j = 0; j < 2; j++)
00574 for (k = 0; k < 2; k++)
00575 cluster->cov.m[j][k] = cluster->c[j][k] / cluster->weight -
00576 cluster->mean.v[j] * cluster->mean.v[k];
00577
00578
00579
00580 cluster->cov.m[2][2] = -2 * log(sqrt(cluster->m[2] * cluster->m[2] +
00581 cluster->m[3] * cluster->m[3]));
00582
00583
00584
00585
00586 }
00587
00588
00589 set->mean.v[0] = m[0] / weight;
00590 set->mean.v[1] = m[1] / weight;
00591 set->mean.v[2] = atan2(m[3], m[2]);
00592
00593
00594 for (j = 0; j < 2; j++)
00595 for (k = 0; k < 2; k++)
00596 set->cov.m[j][k] = c[j][k] / weight - set->mean.v[j] * set->mean.v[k];
00597
00598
00599
00600 set->cov.m[2][2] = -2 * log(sqrt(m[2] * m[2] + m[3] * m[3]));
00601
00602 return;
00603 }
00604
00605
00606
00607 void pf_get_cep_stats(pf_t *pf, pf_vector_t *mean, double *var)
00608 {
00609 int i;
00610 double mn, mx, my, mrr;
00611 pf_sample_set_t *set;
00612 pf_sample_t *sample;
00613
00614 set = pf->sets + pf->current_set;
00615
00616 mn = 0.0;
00617 mx = 0.0;
00618 my = 0.0;
00619 mrr = 0.0;
00620
00621 for (i = 0; i < set->sample_count; i++)
00622 {
00623 sample = set->samples + i;
00624
00625 mn += sample->weight;
00626 mx += sample->weight * sample->pose.v[0];
00627 my += sample->weight * sample->pose.v[1];
00628 mrr += sample->weight * sample->pose.v[0] * sample->pose.v[0];
00629 mrr += sample->weight * sample->pose.v[1] * sample->pose.v[1];
00630 }
00631
00632 mean->v[0] = mx / mn;
00633 mean->v[1] = my / mn;
00634 mean->v[2] = 0.0;
00635
00636 *var = mrr / mn - (mx * mx / (mn * mn) + my * my / (mn * mn));
00637
00638 return;
00639 }
00640
00641
00642
00643 int pf_get_cluster_stats(pf_t *pf, int clabel, double *weight,
00644 pf_vector_t *mean, pf_matrix_t *cov)
00645 {
00646 pf_sample_set_t *set;
00647 pf_cluster_t *cluster;
00648
00649 set = pf->sets + pf->current_set;
00650
00651 if (clabel >= set->cluster_count)
00652 return 0;
00653 cluster = set->clusters + clabel;
00654
00655 *weight = cluster->weight;
00656 *mean = cluster->mean;
00657 *cov = cluster->cov;
00658
00659 return 1;
00660 }
00661
00662