34 #include "nav2_amcl/pf/pf_vector.hpp"
35 #include "nav2_amcl/pf/pf_kdtree.hpp"
39 static int pf_kdtree_equal(
pf_kdtree_t *
self,
int key_a[],
int key_b[]);
76 self->size[2] = (10 * M_PI / 180);
81 self->node_max_count = max_size;
104 self->leaf_count = 0;
105 self->node_count = 0;
115 key[0] = floor(pose.v[0] / self->size[0]);
116 key[1] = floor(pose.v[1] / self->size[1]);
117 key[2] = floor(pose.v[2] / self->size[2]);
119 self->root = pf_kdtree_insert_node(
self, NULL, self->root, key, value);
171 key[0] = floor(pose.v[0] / self->size[0]);
172 key[1] = floor(pose.v[1] / self->size[1]);
173 key[2] = floor(pose.v[2] / self->size[2]);
175 node = pf_kdtree_find_node(
self, self->root, key);
179 return node->cluster;
185 int pf_kdtree_equal(
pf_kdtree_t *
self,
int key_a[],
int key_b[])
190 if (key_a[0] != key_b[0]) {
193 if (key_a[1] != key_b[1]) {
197 if (key_a[2] != key_b[2]) {
223 int split, max_split;
227 assert(self->node_count < self->node_max_count);
228 node =
self->nodes +
self->node_count++;
233 if (parent == NULL) {
236 node->depth = parent->depth + 1;
239 for (i = 0; i < 3; i++) {
240 node->key[i] = key[i];
244 self->leaf_count += 1;
245 }
else if (node->leaf) {
247 if (pf_kdtree_equal(
self, key, node->key)) {
248 node->value += value;
253 node->pivot_dim = -1;
254 for (i = 0; i < 3; i++) {
255 split = abs(key[i] - node->key[i]);
256 if (split > max_split) {
261 assert(node->pivot_dim >= 0);
263 node->pivot_value = (key[node->pivot_dim] + node->key[node->pivot_dim]) / 2.0;
265 if (key[node->pivot_dim] < node->pivot_value) {
266 node->children[0] = pf_kdtree_insert_node(
self, node, NULL, key, value);
267 node->children[1] = pf_kdtree_insert_node(
self, node, NULL, node->key, node->value);
269 node->children[0] = pf_kdtree_insert_node(
self, node, NULL, node->key, node->value);
270 node->children[1] = pf_kdtree_insert_node(
self, node, NULL, key, value);
274 self->leaf_count -= 1;
277 assert(node->children[0] != NULL);
278 assert(node->children[1] != NULL);
280 if (key[node->pivot_dim] < node->pivot_value) {
281 pf_kdtree_insert_node(
self, node, node->children[0], key, value);
283 pf_kdtree_insert_node(
self, node, node->children[1], key, value);
299 if (pf_kdtree_equal(
self, key, node->key)) {
307 assert(node->children[0] != NULL);
308 assert(node->children[1] != NULL);
311 if (key[node->pivot_dim] < node->pivot_value) {
312 return pf_kdtree_find_node(
self, node->children[0], key);
314 return pf_kdtree_find_node(
self, node->children[1], key);
348 int queue_count, cluster_count;
352 queue = calloc(self->node_count,
sizeof(queue[0]));
355 for (i = 0; i <
self->node_count; i++) {
356 node =
self->nodes + i;
359 assert(queue_count < self->node_count);
360 queue[queue_count++] = node;
363 assert(node == pf_kdtree_find_node(
self, self->root, node->key));
370 while (queue_count > 0) {
371 node = queue[--queue_count];
374 if (node->cluster >= 0) {
379 node->cluster = cluster_count++;
382 pf_kdtree_cluster_node(
self, node, 0);
397 for (i = 0; i < 3 * 3 * 3; i++) {
398 nkey[0] = node->key[0] + (i / 9) - 1;
399 nkey[1] = node->key[1] + ((i % 9) / 3) - 1;
400 nkey[2] = node->key[2] + ((i % 9) % 3) - 1;
402 nnode = pf_kdtree_find_node(
self, self->root, nkey);
411 if (nnode->cluster >= 0) {
412 assert(nnode->cluster == node->cluster);
417 nnode->cluster = node->cluster;
419 pf_kdtree_cluster_node(
self, nnode, depth + 1);
424 #ifdef INCLUDE_RTKGUI
428 void pf_kdtree_draw(
pf_kdtree_t *
self, rtk_fig_t * fig)
430 if (self->root != NULL) {
431 pf_kdtree_draw_node(
self, self->root, fig);
444 ox = (node->key[0] + 0.5) * self->size[0];
445 oy = (node->key[1] + 0.5) *
self->size[1];
447 rtk_fig_rectangle(fig, ox, oy, 0.0, self->size[0], self->size[1], 0);
452 snprintf(text,
sizeof(text),
"%d", node->cluster);
453 rtk_fig_text(fig, ox, oy, 0.0, text);
455 assert(node->children[0] != NULL);
456 assert(node->children[1] != NULL);
457 pf_kdtree_draw_node(
self, node->children[0], fig);
458 pf_kdtree_draw_node(
self, node->children[1], fig);