AI prompts
base on Fast, hierarchical, sparse Voxel Grid ![Bonxai](doc/bonxai.png)
Bonxai is a library that implements a compact hierarchical data structure that
can store and manipulate volumetric data, discretized on a three-dimensional
grid (AKA, a "Voxel Grid").
Bonxai data structure is:
- **Sparse**: it uses only a fraction of the memory that a dense 3D voxel grid would use.
- **Unbounded**: you don't need to define the boundary of the 3D space (*).
>(*) The dimension of the 3D space is virtually "infinite":
since **32-bits indices** are used, given a voxel size of **1 cm**,
the maximum range of the X, Y and Z coordinates would be about **40.000 Km**.
As a reference **the diameter of planet Earth is 12.000 Km**.
If you are familiar with [Octomap](https://octomap.github.io/) and Octrees, you know
that those data structures are also sparse and unbounded.
On the other hand, Bonxai is **much faster** and, in some cases, even more memory-efficient
than an Octree.
This work is strongly influenced by [OpenVDB](https://www.openvdb.org/) and it can be considered
an implementation of the original paper, with a couple of non-trivial changes:
K. Museth,
“VDB: High-Resolution Sparse Volumes with Dynamic Topology”,
ACM Transactions on Graphics 32(3), 2013. Presented at SIGGRAPH 2013.
You can read the previous paper [here](http://www.museth.org/Ken/Publications_files/Museth_TOG13.pdf).
There is also some overlap with this other paper, but their implementation is much** simpler,
even if conceptually similar:
Eurico Pedrosa, Artur Pereira, Nuno Lau
"A Sparse-Dense Approach for Efficient Grid Mapping"
2018 IEEE International Conference on Autonomous Robot Systems and Competitions (ICARSC)
**Bonxai** is currently under development and I am building this mostly for fun and for
educational purposes. Don't expect any API stability for the time being.
# Benchmark (preliminary)
Take these numbers with a grain of salt, since they are preliminary and the benchmark is
strongly influenced by the way the data is stored.
Anyway, they gave you a fair idea of what you may expect, in terms of performance.
```
-------------------------------------------
Benchmark Time
-------------------------------------------
Bonxai_Create 1165 us
Octomap_Create 25522 us
Bonxai_Update 851 us
Octomap_Update 3824 us
Bonxai_IterateAllCells 124 us
Octomap_IterateAllCells 698 us
```
- **Create** refers to creating a new VoxelGrid from scratch
- **Update** means modifying the value of an already allocated VoxelGrid.
- **IterateAllCells** will get the value and the coordinates of all the existing cells.
# How to use it
The core of **Bonxai** is a header-only library that you can simply copy into your project
and include like this:
```c++
#include "bonxai/bonxai.hpp"
```
To create a VoxelGrid, where each cell contains an integer value and has size 0.05.
```c++
double voxel_resolution = 0.05;
Bonxai::VoxelGrid<int> grid( voxel_resolution );
```
Nothing prevents you from having more complex cell values, for instance:
```c++
Bonxai::VoxelGrid<Eigen::Vector4d> vector_grid( voxel_resolution );
// or
struct Foo {
int a;
double b;
};
Bonxai::VoxelGrid<Foo> foo_grid( voxel_resolution );
```
To insert values into a cell with coordinates x, y and z, use a
`VoxelGrid::Accessor` object.
In the next code sample, we will create a dense cube of cells with value 42:
```c++
// Each cell will contain a `float` and it will have size 0.05
double voxel_resolution = 0.05;
Bonxai::VoxelGrid<float> grid( voxel_resolution );
// Create this accessor once, and reuse it as much as possible.
auto accessor = grid.createAccessor();
// Create cells with value 42.0 in a 1x1x1 cube.
// Given voxel_resolution = 0.05, this will be equivalent
// to 20x20x20 cells in the grid.
for( double x = 0; x < 1.0; x += voxel_resolution ) {
for( double y = 0; y < 1.0; y += voxel_resolution ) {
for( double z = 0; z < 1.0; z += voxel_resolution ) {
// discretize the position {x,y,z}
Bonxai::CoordT coord = grid.posToCoord(x, y, z);
accessor.setValue( coord, 42.0 );
}
}
}
// You can read (or update) the value of a cell as shown below.
// If the cell doesn't exist, `value_ptr` will be `nullptr`,
Bonxai::CoordT coord = grid.posToCoord(x, y, z);
float* value_ptr = accessor.value( coord );
```
## Note about multi-threading
`Bonxai::VoxelGrid` is **not** thread-safe, for write operations.
If you want to access the grid in **read-only** mode, you can
use multi-threading, but each thread should have its own
`accessor`.
# Roadmap
- [x] serialization to/from file.
- [x] full implementation of the Octomap algorithm (ray casting + probability map).
- [x] integration with ROS 2.
- [ ] RViz2 visualization messages.
- [ ] integration with [FCL](https://github.com/flexible-collision-library/fcl) for collision detection (?)
# Frequently Asked Question
**What is the point of reimplementing OpenVDB?**
- The number one reason is to have fun and to learn something new :)
- I want this library to be small and easy to integrate into larger projects.
The core data structure is less than 1000 lines of code.
- It is not an "exact" rewrite, I modified a few important aspects of the algorithm
to make it slightly faster, at least for my specific use cases.
**How much memory does it use, compared with Octomap?**
It is... complicated.
If you need to store very sparse point clouds, you should expect Bonxai to use more memory (20-40% more).
If the point cloud is relatively dense, Bonxai might use less memory than Octomap (less than half).
", Assign "at most 3 tags" to the expected json: {"id":"2012","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"