35 #include "nav2_amcl/pf/pf_vector.hpp"
36 #include "nav2_amcl/pf/pf_kdtree.hpp"
40 static int pf_kdtree_equal(
pf_kdtree_t *
self,
int key_a[],
int key_b[]);
53 static void pf_kdtree_cluster_node(
79 self->size[2] = (10 * M_PI / 180);
84 self->node_max_count = max_size;
107 self->leaf_count = 0;
108 self->node_count = 0;
118 key[0] = floor(pose.v[0] / self->size[0]);
119 key[1] = floor(pose.v[1] / self->size[1]);
120 key[2] = floor(pose.v[2] / self->size[2]);
122 self->root = pf_kdtree_insert_node(
self, NULL, self->root, key, value);
174 key[0] = floor(pose.v[0] / self->size[0]);
175 key[1] = floor(pose.v[1] / self->size[1]);
176 key[2] = floor(pose.v[2] / self->size[2]);
178 node = pf_kdtree_find_node(
self, self->root, key);
182 return node->cluster;
188 int pf_kdtree_equal(
pf_kdtree_t *
self,
int key_a[],
int key_b[])
193 if (key_a[0] != key_b[0]) {
196 if (key_a[1] != key_b[1]) {
200 if (key_a[2] != key_b[2]) {
226 int64_t split, max_split;
230 assert(self->node_count < self->node_max_count);
231 node =
self->nodes +
self->node_count++;
236 if (parent == NULL) {
239 node->depth = parent->depth + 1;
242 for (i = 0; i < 3; i++) {
243 node->key[i] = key[i];
247 self->leaf_count += 1;
248 }
else if (node->leaf) {
250 if (pf_kdtree_equal(
self, key, node->key)) {
251 node->value += value;
256 node->pivot_dim = -1;
257 for (i = 0; i < 3; i++) {
258 split = llabs((int64_t)key[i] - node->key[i]);
259 if (split > max_split) {
264 assert(node->pivot_dim >= 0);
267 ((double)key[node->pivot_dim] + node->key[node->pivot_dim]) / 2.0;
269 if (key[node->pivot_dim] < node->pivot_value) {
270 node->children[0] = pf_kdtree_insert_node(
self, node, NULL, key, value);
271 node->children[1] = pf_kdtree_insert_node(
self, node, NULL, node->key, node->value);
273 node->children[0] = pf_kdtree_insert_node(
self, node, NULL, node->key, node->value);
274 node->children[1] = pf_kdtree_insert_node(
self, node, NULL, key, value);
278 self->leaf_count -= 1;
281 assert(node->children[0] != NULL);
282 assert(node->children[1] != NULL);
284 if (key[node->pivot_dim] < node->pivot_value) {
285 pf_kdtree_insert_node(
self, node, node->children[0], key, value);
287 pf_kdtree_insert_node(
self, node, node->children[1], key, value);
303 if (pf_kdtree_equal(
self, key, node->key)) {
311 assert(node->children[0] != NULL);
312 assert(node->children[1] != NULL);
315 if (key[node->pivot_dim] < node->pivot_value) {
316 return pf_kdtree_find_node(
self, node->children[0], key);
318 return pf_kdtree_find_node(
self, node->children[1], key);
352 int queue_count, cluster_count;
356 queue = calloc(self->node_count,
sizeof(queue[0]));
359 for (i = 0; i <
self->node_count; i++) {
360 node =
self->nodes + i;
365 assert(node == pf_kdtree_find_node(
self, self->root, node->key));
372 for (i = self->node_count - 1; i >= 0; i--) {
373 node =
self->nodes + i;
376 if (!node->leaf || node->cluster >= 0) {
381 node->cluster = cluster_count++;
384 assert(queue_count < self->node_count);
385 queue[queue_count++] = node;
386 while (queue_count > 0) {
387 node = queue[--queue_count];
388 pf_kdtree_cluster_node(
self, node, queue, &queue_count);
398 void pf_kdtree_cluster_node(
406 for (i = 0; i < 3 * 3 * 3; i++) {
407 nkey[0] = node->key[0] + (i / 9) - 1;
408 nkey[1] = node->key[1] + ((i % 9) / 3) - 1;
409 nkey[2] = node->key[2] + ((i % 9) % 3) - 1;
411 nnode = pf_kdtree_find_node(
self, self->root, nkey);
420 if (nnode->cluster >= 0) {
421 assert(nnode->cluster == node->cluster);
426 nnode->cluster = node->cluster;
427 assert(*queue_count < self->node_count);
428 queue[(*queue_count)++] = nnode;
433 #ifdef INCLUDE_RTKGUI
437 void pf_kdtree_draw(
pf_kdtree_t *
self, rtk_fig_t * fig)
439 if (self->root != NULL) {
440 pf_kdtree_draw_node(
self, self->root, fig);
453 ox = (node->key[0] + 0.5) * self->size[0];
454 oy = (node->key[1] + 0.5) *
self->size[1];
456 rtk_fig_rectangle(fig, ox, oy, 0.0, self->size[0], self->size[1], 0);
461 snprintf(text,
sizeof(text),
"%d", node->cluster);
462 rtk_fig_text(fig, ox, oy, 0.0, text);
464 assert(node->children[0] != NULL);
465 assert(node->children[1] != NULL);
466 pf_kdtree_draw_node(
self, node->children[0], fig);
467 pf_kdtree_draw_node(
self, node->children[1], fig);