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 <string.h>
00032
00033
00034 #include "nav2d_localizer/pf_vector.h"
00035 #include "nav2d_localizer/pf_kdtree.h"
00036
00037
00038
00039 static int pf_kdtree_equal(pf_kdtree_t *self, int key_a[], int key_b[]);
00040
00041
00042 static pf_kdtree_node_t *pf_kdtree_insert_node(pf_kdtree_t *self, pf_kdtree_node_t *parent,
00043 pf_kdtree_node_t *node, int key[], double value);
00044
00045
00046 static pf_kdtree_node_t *pf_kdtree_find_node(pf_kdtree_t *self, pf_kdtree_node_t *node, int key[]);
00047
00048
00049 static void pf_kdtree_cluster_node(pf_kdtree_t *self, pf_kdtree_node_t *node, int depth);
00050
00051
00052
00053
00054
00055 #ifdef INCLUDE_RTKGUI
00056
00057
00058 static void pf_kdtree_draw_node(pf_kdtree_t *self, pf_kdtree_node_t *node, rtk_fig_t *fig);
00059
00060 #endif
00061
00062
00063
00065
00066 pf_kdtree_t *pf_kdtree_alloc(int max_size)
00067 {
00068 pf_kdtree_t *self;
00069
00070 self = calloc(1, sizeof(pf_kdtree_t));
00071
00072 self->size[0] = 0.50;
00073 self->size[1] = 0.50;
00074 self->size[2] = (10 * M_PI / 180);
00075
00076 self->root = NULL;
00077
00078 self->node_count = 0;
00079 self->node_max_count = max_size;
00080 self->nodes = calloc(self->node_max_count, sizeof(pf_kdtree_node_t));
00081
00082 self->leaf_count = 0;
00083
00084 return self;
00085 }
00086
00087
00089
00090 void pf_kdtree_free(pf_kdtree_t *self)
00091 {
00092 free(self->nodes);
00093 free(self);
00094 return;
00095 }
00096
00097
00099
00100 void pf_kdtree_clear(pf_kdtree_t *self)
00101 {
00102 self->root = NULL;
00103 self->leaf_count = 0;
00104 self->node_count = 0;
00105
00106 return;
00107 }
00108
00109
00111
00112 void pf_kdtree_insert(pf_kdtree_t *self, pf_vector_t pose, double value)
00113 {
00114 int key[3];
00115
00116 key[0] = floor(pose.v[0] / self->size[0]);
00117 key[1] = floor(pose.v[1] / self->size[1]);
00118 key[2] = floor(pose.v[2] / self->size[2]);
00119
00120 self->root = pf_kdtree_insert_node(self, NULL, self->root, key, value);
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 return;
00144 }
00145
00146
00148
00149
00150 double pf_kdtree_get_prob(pf_kdtree_t *self, pf_vector_t pose)
00151 {
00152 int key[3];
00153 pf_kdtree_node_t *node;
00154
00155 key[0] = floor(pose.v[0] / self->size[0]);
00156 key[1] = floor(pose.v[1] / self->size[1]);
00157 key[2] = floor(pose.v[2] / self->size[2]);
00158
00159 node = pf_kdtree_find_node(self, self->root, key);
00160 if (node == NULL)
00161 return 0.0;
00162 return node->value;
00163 }
00164
00165
00167
00168 int pf_kdtree_get_cluster(pf_kdtree_t *self, pf_vector_t pose)
00169 {
00170 int key[3];
00171 pf_kdtree_node_t *node;
00172
00173 key[0] = floor(pose.v[0] / self->size[0]);
00174 key[1] = floor(pose.v[1] / self->size[1]);
00175 key[2] = floor(pose.v[2] / self->size[2]);
00176
00177 node = pf_kdtree_find_node(self, self->root, key);
00178 if (node == NULL)
00179 return -1;
00180 return node->cluster;
00181 }
00182
00183
00185
00186 int pf_kdtree_equal(pf_kdtree_t *self, int key_a[], int key_b[])
00187 {
00188
00189
00190 if (key_a[0] != key_b[0])
00191 return 0;
00192 if (key_a[1] != key_b[1])
00193 return 0;
00194
00195 if (key_a[2] != key_b[2])
00196 return 0;
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 return 1;
00210 }
00211
00212
00214
00215 pf_kdtree_node_t *pf_kdtree_insert_node(pf_kdtree_t *self, pf_kdtree_node_t *parent,
00216 pf_kdtree_node_t *node, int key[], double value)
00217 {
00218 int i;
00219 int split, max_split;
00220
00221
00222 if (node == NULL)
00223 {
00224 assert(self->node_count < self->node_max_count);
00225 node = self->nodes + self->node_count++;
00226 memset(node, 0, sizeof(pf_kdtree_node_t));
00227
00228 node->leaf = 1;
00229
00230 if (parent == NULL)
00231 node->depth = 0;
00232 else
00233 node->depth = parent->depth + 1;
00234
00235 for (i = 0; i < 3; i++)
00236 node->key[i] = key[i];
00237
00238 node->value = value;
00239 self->leaf_count += 1;
00240 }
00241
00242
00243 else if (node->leaf)
00244 {
00245
00246 if (pf_kdtree_equal(self, key, node->key))
00247 {
00248 node->value += value;
00249 }
00250
00251
00252 else
00253 {
00254
00255
00256 max_split = 0;
00257 node->pivot_dim = -1;
00258 for (i = 0; i < 3; i++)
00259 {
00260 split = abs(key[i] - node->key[i]);
00261 if (split > max_split)
00262 {
00263 max_split = split;
00264 node->pivot_dim = i;
00265 }
00266 }
00267 assert(node->pivot_dim >= 0);
00268
00269 node->pivot_value = (key[node->pivot_dim] + node->key[node->pivot_dim]) / 2.0;
00270
00271 if (key[node->pivot_dim] < node->pivot_value)
00272 {
00273 node->children[0] = pf_kdtree_insert_node(self, node, NULL, key, value);
00274 node->children[1] = pf_kdtree_insert_node(self, node, NULL, node->key, node->value);
00275 }
00276 else
00277 {
00278 node->children[0] = pf_kdtree_insert_node(self, node, NULL, node->key, node->value);
00279 node->children[1] = pf_kdtree_insert_node(self, node, NULL, key, value);
00280 }
00281
00282 node->leaf = 0;
00283 self->leaf_count -= 1;
00284 }
00285 }
00286
00287
00288 else
00289 {
00290 assert(node->children[0] != NULL);
00291 assert(node->children[1] != NULL);
00292
00293 if (key[node->pivot_dim] < node->pivot_value)
00294 pf_kdtree_insert_node(self, node, node->children[0], key, value);
00295 else
00296 pf_kdtree_insert_node(self, node, node->children[1], key, value);
00297 }
00298
00299 return node;
00300 }
00301
00302
00304
00305 pf_kdtree_node_t *pf_kdtree_find_node(pf_kdtree_t *self, pf_kdtree_node_t *node, int key[])
00306 {
00307 if (node->leaf)
00308 {
00309
00310
00311
00312 if (pf_kdtree_equal(self, key, node->key))
00313 return node;
00314 else
00315 return NULL;
00316 }
00317 else
00318 {
00319
00320
00321 assert(node->children[0] != NULL);
00322 assert(node->children[1] != NULL);
00323
00324
00325 if (key[node->pivot_dim] < node->pivot_value)
00326 return pf_kdtree_find_node(self, node->children[0], key);
00327 else
00328 return pf_kdtree_find_node(self, node->children[1], key);
00329 }
00330
00331 return NULL;
00332 }
00333
00334
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00357
00358 void pf_kdtree_cluster(pf_kdtree_t *self)
00359 {
00360 int i;
00361 int queue_count, cluster_count;
00362 pf_kdtree_node_t **queue, *node;
00363
00364 queue_count = 0;
00365 queue = calloc(self->node_count, sizeof(queue[0]));
00366
00367
00368 for (i = 0; i < self->node_count; i++)
00369 {
00370 node = self->nodes + i;
00371 if (node->leaf)
00372 {
00373 node->cluster = -1;
00374 assert(queue_count < self->node_count);
00375 queue[queue_count++] = node;
00376
00377
00378 assert(node == pf_kdtree_find_node(self, self->root, node->key));
00379 }
00380 }
00381
00382 cluster_count = 0;
00383
00384
00385 while (queue_count > 0)
00386 {
00387 node = queue[--queue_count];
00388
00389
00390 if (node->cluster >= 0)
00391 continue;
00392
00393
00394 node->cluster = cluster_count++;
00395
00396
00397 pf_kdtree_cluster_node(self, node, 0);
00398 }
00399
00400 free(queue);
00401 return;
00402 }
00403
00404
00406
00407 void pf_kdtree_cluster_node(pf_kdtree_t *self, pf_kdtree_node_t *node, int depth)
00408 {
00409 int i;
00410 int nkey[3];
00411 pf_kdtree_node_t *nnode;
00412
00413 for (i = 0; i < 3 * 3 * 3; i++)
00414 {
00415 nkey[0] = node->key[0] + (i / 9) - 1;
00416 nkey[1] = node->key[1] + ((i % 9) / 3) - 1;
00417 nkey[2] = node->key[2] + ((i % 9) % 3) - 1;
00418
00419 nnode = pf_kdtree_find_node(self, self->root, nkey);
00420 if (nnode == NULL)
00421 continue;
00422
00423 assert(nnode->leaf);
00424
00425
00426
00427 if (nnode->cluster >= 0)
00428 {
00429 assert(nnode->cluster == node->cluster);
00430 continue;
00431 }
00432
00433
00434 nnode->cluster = node->cluster;
00435
00436 pf_kdtree_cluster_node(self, nnode, depth + 1);
00437 }
00438 return;
00439 }
00440
00441
00442
00443 #ifdef INCLUDE_RTKGUI
00444
00446
00447 void pf_kdtree_draw(pf_kdtree_t *self, rtk_fig_t *fig)
00448 {
00449 if (self->root != NULL)
00450 pf_kdtree_draw_node(self, self->root, fig);
00451 return;
00452 }
00453
00454
00456
00457 void pf_kdtree_draw_node(pf_kdtree_t *self, pf_kdtree_node_t *node, rtk_fig_t *fig)
00458 {
00459 double ox, oy;
00460 char text[64];
00461
00462 if (node->leaf)
00463 {
00464 ox = (node->key[0] + 0.5) * self->size[0];
00465 oy = (node->key[1] + 0.5) * self->size[1];
00466
00467 rtk_fig_rectangle(fig, ox, oy, 0.0, self->size[0], self->size[1], 0);
00468
00469
00470
00471
00472 snprintf(text, sizeof(text), "%d", node->cluster);
00473 rtk_fig_text(fig, ox, oy, 0.0, text);
00474 }
00475 else
00476 {
00477 assert(node->children[0] != NULL);
00478 assert(node->children[1] != NULL);
00479 pf_kdtree_draw_node(self, node->children[0], fig);
00480 pf_kdtree_draw_node(self, node->children[1], fig);
00481 }
00482
00483 return;
00484 }
00485
00486 #endif