Home

Awesome

octomap_tutorial

What is an Octree?

What is an octomap?

It is an extension of the octree data strucutre, widely used for repsentating and quering 3D occupancy maps. It is commonly employed in robotics application especially for 3D planning. In OctoMap, each node of the octree represents a cubic region of space, similar to the basic octree structure. However, in addition to the occupancy state (either occupied or free), OctoMap also stores probabilistic information about the occupancy of each node. This probabilistic representation allows for more nuanced and accurate modeling of uncertain or unknown regions.

Now, you maybe wondering why use octree to represent a map as quering data in 3D array would much simpler and direct, but octrees offer advantages in handling sparse data, representing complex geometry, and adapting to varying object density. The choice between a 3D array and an octree depends on the specific requirements of your application and the characteristics of the data and environment you are working with.

Some key points:

Map Accesssing

for(OcTree::leaf_iterator it=octree.begin_leafs(),
	end=octree.end_leafs(); it!=end; ++it)
{
	// access node, eg:
	std::cout << "Node center: " << it.getCoordinate();
	std::cout << "value: " << it->getValue() << "\n";
}
octree.castRay(...)
OcTreeNode* n=octree.search(x, y, z);
if(n)
{
	std::cout << "value: " << n->getValue() << "\n";
}

Occupancy and Sensor Model

octree.setOccupancyThres(0.5);
octree.setProbHit(0.7);
octree.setProbMiss(0.3);
octree.setClampingThresMin(0.1);
octree.setClampingThresMax(0.95);
octree.isNodeOccupied(n);
octree.isNodeAtThreshold(n);

Reading Map Files(Deserialization)

AbstractOcTree* tree = AbstractOcTree::read(filename);
if(tree) // read error returs NULL
{ 
	OcTree* ot = dynamic_cast<OcTree*>(tree);
	if (ot) // cast succeeds if correct type
	{
		// do something
	}
}
OcTree* octree = new OcTree(filename);

(De-)Serialization in ROS

octomap_msgs::Octomap map_msg, bmap_msg;
octomap_msgs::fullMapToMsg(octree, map_msg); //(.ot)
octomap_msgs::binaryMapToMsg(octree, bmap_msg) //(.bt)
AbstractOcTree* tree = octomap_msgs::msgToMap(map_msg);
OcTree octree* = dynamic_cast<OcTree*>(tree);
if (octree) // can be NULL
{
	...;
}

Map Visualization

3D Mapping in ROS(outline)

Using Octomap in your project

find_package(octomap REQUIRED)
include_directories(${OCTOMAP_INCLUDE_DIRS})
link_libraries(${PROJECT_NAME} ${OCTOMAP_LIBRARIES})

# OR link each executable as below
add_executable (name file.cpp)
target_link_libraries(name octomap)

Running OctoMap with ROS2

ros2 launch octomap_server octomap_mapping.launch.xml

Note: This requires octomap-ros and octomap-msgs as dependencies

ros2 run octomap_server octomap_saver_node --ros-args -p octomap_path:=(path for saving octomap)

Note: The extension of octomap path should be .bt or .ot

Flexible Collision Checking(FCL)

Incase you also want to use FCL with Octrees, please follow the below steps:

git clone https://github.com/danfis/libccd
cd libccd
mkdir build && cd build
cmake -G "Unix Makefiles" -DBUILD_SHARED_LIBS=ON ..
make && sudo make install

git clone https://github.com/flexible-collision-library/fcl
cd fcl
mkdir build
cd build
cmake ..
sudo make install

Reference:

  1. ROSCon2013 Video giving a bried overview about the working and available classes and methods.
  2. https://github.com/ycaibb/octomap_rrt
  3. https://github.com/ayushgaud/path_planning