coal 3.0.2
Coal, The Collision Detection Library. Previously known as HPP-FCL, fork of FCL -- The Flexible Collision Library
Loading...
Searching...
No Matches
octree.h
Go to the documentation of this file.
1/*
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2011-2014, Willow Garage, Inc.
5 * Copyright (c) 2014-2015, Open Source Robotics Foundation
6 * Copyright (c) 2022-2024, Inria
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * * Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 * * Neither the name of Open Source Robotics Foundation nor the names of its
20 * contributors may be used to endorse or promote products derived
21 * from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
38
39#ifndef COAL_OCTREE_H
40#define COAL_OCTREE_H
41
42#include <algorithm>
43
44#include <octomap/octomap.h>
45#include "coal/fwd.hh"
46#include "coal/BV/AABB.h"
48
49namespace coal {
50
53class COAL_DLLAPI OcTree : public CollisionGeometry {
54 protected:
55 shared_ptr<const octomap::OcTree> tree;
56
58
61
62 public:
63 typedef octomap::OcTreeNode OcTreeNode;
64
66 explicit OcTree(CoalScalar resolution)
67 : tree(shared_ptr<const octomap::OcTree>(
68 new octomap::OcTree(resolution))) {
69 default_occupancy = tree->getOccupancyThres();
70
71 // default occupancy/free threshold is consistent with default setting from
72 // octomap
73 occupancy_threshold = tree->getOccupancyThres();
75 }
76
78 explicit OcTree(const shared_ptr<const octomap::OcTree>& tree_)
79 : tree(tree_) {
80 default_occupancy = tree->getOccupancyThres();
81
82 // default occupancy/free threshold is consistent with default setting from
83 // octomap
84 occupancy_threshold = tree->getOccupancyThres();
86 }
87
95
97 OcTree* clone() const { return new OcTree(*this); }
98
100 shared_ptr<const octomap::OcTree> getTree() const { return tree; }
101
102 void exportAsObjFile(const std::string& filename) const;
103
106 typedef Eigen::Matrix<float, 3, 1> Vec3sloat;
107 Vec3sloat max_extent, min_extent;
108
109 octomap::OcTree::iterator it =
110 tree->begin((unsigned char)tree->getTreeDepth());
111 octomap::OcTree::iterator end = tree->end();
112
113 if (it == end) return;
114
115 {
116 const octomap::point3d& coord =
117 it.getCoordinate(); // getCoordinate returns a copy
118 max_extent = min_extent = Eigen::Map<const Vec3sloat>(&coord.x());
119 for (++it; it != end; ++it) {
120 const octomap::point3d& coord = it.getCoordinate();
121 const Vec3sloat pos = Eigen::Map<const Vec3sloat>(&coord.x());
122 max_extent = max_extent.array().max(pos.array());
123 min_extent = min_extent.array().min(pos.array());
124 }
125 }
126
127 // Account for the size of the boxes.
128 const CoalScalar resolution = tree->getResolution();
129 max_extent.array() += float(resolution / 2.);
130 min_extent.array() -= float(resolution / 2.);
131
133 AABB(min_extent.cast<CoalScalar>(), max_extent.cast<CoalScalar>());
134 aabb_center = aabb_local.center();
135 aabb_radius = (aabb_local.min_ - aabb_center).norm();
136 }
137
139 AABB getRootBV() const {
140 CoalScalar delta = (1 << tree->getTreeDepth()) * tree->getResolution() / 2;
141
142 // std::cout << "octree size " << delta << std::endl;
143 return AABB(Vec3s(-delta, -delta, -delta), Vec3s(delta, delta, delta));
144 }
145
147 unsigned int getTreeDepth() const { return tree->getTreeDepth(); }
148
150 unsigned long size() const { return tree->size(); }
151
153 CoalScalar getResolution() const { return tree->getResolution(); }
154
156 OcTreeNode* getRoot() const { return tree->getRoot(); }
157
159 bool isNodeOccupied(const OcTreeNode* node) const {
160 // return tree->isNodeOccupied(node);
161 return node->getOccupancy() >= occupancy_threshold;
162 }
163
165 bool isNodeFree(const OcTreeNode* node) const {
166 // return false; // default no definitely free node
167 return node->getOccupancy() <= free_threshold;
168 }
169
171 bool isNodeUncertain(const OcTreeNode* node) const {
172 return (!isNodeOccupied(node)) && (!isNodeFree(node));
173 }
174
178 std::vector<Vec6s> toBoxes() const {
179 std::vector<Vec6s> boxes;
180 boxes.reserve(tree->size() / 2);
181 for (octomap::OcTree::iterator
182 it = tree->begin((unsigned char)tree->getTreeDepth()),
183 end = tree->end();
184 it != end; ++it) {
185 // if(tree->isNodeOccupied(*it))
186 if (isNodeOccupied(&*it)) {
187 CoalScalar x = it.getX();
188 CoalScalar y = it.getY();
189 CoalScalar z = it.getZ();
190 CoalScalar size = it.getSize();
191 CoalScalar c = (*it).getOccupancy();
192 CoalScalar t = tree->getOccupancyThres();
193
194 Vec6s box;
195 box << x, y, z, size, c, t;
196 boxes.push_back(box);
197 }
198 }
199 return boxes;
200 }
201
203 std::vector<uint8_t> tobytes() const {
204 typedef Eigen::Matrix<float, 3, 1> Vec3sloat;
205 const size_t total_size = (tree->size() * sizeof(CoalScalar) * 3) / 2;
206 std::vector<uint8_t> bytes;
207 bytes.reserve(total_size);
208
209 for (octomap::OcTree::iterator
210 it = tree->begin((unsigned char)tree->getTreeDepth()),
211 end = tree->end();
212 it != end; ++it) {
213 const Vec3s box_pos =
214 Eigen::Map<Vec3sloat>(&it.getCoordinate().x()).cast<CoalScalar>();
215 if (isNodeOccupied(&*it))
216 std::copy(box_pos.data(), box_pos.data() + sizeof(CoalScalar) * 3,
217 std::back_inserter(bytes));
218 }
219
220 return bytes;
221 }
222
226
230
232
234
236
238
240 OcTreeNode* getNodeChild(OcTreeNode* node, unsigned int childIdx) {
241 return tree->getNodeChild(node, childIdx);
242 }
243
246 unsigned int childIdx) const {
247 return tree->getNodeChild(node, childIdx);
248 }
249
251 bool nodeChildExists(const OcTreeNode* node, unsigned int childIdx) const {
252 return tree->nodeChildExists(node, childIdx);
253 }
254
256 bool nodeHasChildren(const OcTreeNode* node) const {
257 return tree->nodeHasChildren(node);
258 }
259
262
264 NODE_TYPE getNodeType() const { return GEOM_OCTREE; }
265
266 private:
267 virtual bool isEqual(const CollisionGeometry& _other) const {
268 const OcTree* other_ptr = dynamic_cast<const OcTree*>(&_other);
269 if (other_ptr == nullptr) return false;
270 const OcTree& other = *other_ptr;
271
272 return (tree.get() == other.tree.get() || toBoxes() == other.toBoxes()) &&
273 default_occupancy == other.default_occupancy &&
274 occupancy_threshold == other.occupancy_threshold &&
275 free_threshold == other.free_threshold;
276 }
277
278 public:
279 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
280};
281
283static inline void computeChildBV(const AABB& root_bv, unsigned int i,
284 AABB& child_bv) {
285 if (i & 1) {
286 child_bv.min_[0] = (root_bv.min_[0] + root_bv.max_[0]) * 0.5;
287 child_bv.max_[0] = root_bv.max_[0];
288 } else {
289 child_bv.min_[0] = root_bv.min_[0];
290 child_bv.max_[0] = (root_bv.min_[0] + root_bv.max_[0]) * 0.5;
291 }
292
293 if (i & 2) {
294 child_bv.min_[1] = (root_bv.min_[1] + root_bv.max_[1]) * 0.5;
295 child_bv.max_[1] = root_bv.max_[1];
296 } else {
297 child_bv.min_[1] = root_bv.min_[1];
298 child_bv.max_[1] = (root_bv.min_[1] + root_bv.max_[1]) * 0.5;
299 }
300
301 if (i & 4) {
302 child_bv.min_[2] = (root_bv.min_[2] + root_bv.max_[2]) * 0.5;
303 child_bv.max_[2] = root_bv.max_[2];
304 } else {
305 child_bv.min_[2] = root_bv.min_[2];
306 child_bv.max_[2] = (root_bv.min_[2] + root_bv.max_[2]) * 0.5;
307 }
308}
309
318COAL_DLLAPI OcTreePtr_t
319makeOctree(const Eigen::Matrix<CoalScalar, Eigen::Dynamic, 3>& point_cloud,
320 const CoalScalar resolution);
321
322} // namespace coal
323
324#endif
A class describing the AABB collision structure, which is a box in 3D space determined by two diagona...
Definition AABB.h:55
The geometry for the object for collision or distance computation.
Definition collision_object.h:94
Octree is one type of collision geometry which can encode uncertainty information in the sensor data.
Definition octree.h:53
CoalScalar getFreeThres() const
the threshold used to decide whether one node is free, this is NOT the octree free_threshold
Definition octree.h:229
OBJECT_TYPE getObjectType() const
return object type, it is an octree
Definition octree.h:261
std::vector< Vec6s > toBoxes() const
transform the octree into a bunch of boxes; uncertainty information is kept in the boxes....
Definition octree.h:178
bool nodeChildExists(const OcTreeNode *node, unsigned int childIdx) const
return true if the child at childIdx exists
Definition octree.h:251
AABB getRootBV() const
get the bounding volume for the root
Definition octree.h:139
OcTree(const OcTree &other)
&#160;
Definition octree.h:89
void computeLocalAABB()
compute the AABB for the octree in its local coordinate system
Definition octree.h:105
void setFreeThres(CoalScalar d)
Definition octree.h:237
void exportAsObjFile(const std::string &filename) const
void setOccupancyThres(CoalScalar d)
Definition octree.h:235
OcTreeNode * getNodeChild(OcTreeNode *node, unsigned int childIdx)
Definition octree.h:240
CoalScalar getDefaultOccupancy() const
Definition octree.h:231
shared_ptr< const octomap::OcTree > getTree() const
Returns the tree associated to the underlying octomap OcTree.
Definition octree.h:100
shared_ptr< const octomap::OcTree > tree
Definition octree.h:55
OcTree * clone() const
Clone *this into a new Octree.
Definition octree.h:97
CoalScalar default_occupancy
Definition octree.h:57
OcTreeNode * getRoot() const
get the root node of the octree
Definition octree.h:156
OcTree(CoalScalar resolution)
construct octree with a given resolution
Definition octree.h:66
unsigned int getTreeDepth() const
Returns the depth of the octree.
Definition octree.h:147
void setCellDefaultOccupancy(CoalScalar d)
Definition octree.h:233
CoalScalar getOccupancyThres() const
the threshold used to decide whether one node is occupied, this is NOT the octree occupied_thresold
Definition octree.h:225
const OcTreeNode * getNodeChild(const OcTreeNode *node, unsigned int childIdx) const
Definition octree.h:245
bool nodeHasChildren(const OcTreeNode *node) const
return true if node has at least one child
Definition octree.h:256
bool isNodeUncertain(const OcTreeNode *node) const
whether one node is uncertain
Definition octree.h:171
OcTree(const shared_ptr< const octomap::OcTree > &tree_)
construct octree from octomap
Definition octree.h:78
unsigned long size() const
Returns the size of the octree.
Definition octree.h:150
CoalScalar getResolution() const
Returns the resolution of the octree.
Definition octree.h:153
CoalScalar free_threshold
Definition octree.h:60
octomap::OcTreeNode OcTreeNode
Definition octree.h:63
bool isNodeFree(const OcTreeNode *node) const
whether one node is completely free
Definition octree.h:165
CoalScalar occupancy_threshold
Definition octree.h:59
NODE_TYPE getNodeType() const
return node type, it is an octree
Definition octree.h:264
std::vector< uint8_t > tobytes() const
Returns a byte description of *this.
Definition octree.h:203
bool isNodeOccupied(const OcTreeNode *node) const
whether one node is completely occupied
Definition octree.h:159
AABB aabb_local
AABB in local coordinate, used for tight AABB when only translation transform.
Definition collision_object.h:158
@ GEOM_OCTREE
Definition collision_object.h:83
@ OT_OCTREE
Definition collision_object.h:56
Vec3s aabb_center
AABB center in local coordinate.
Definition collision_object.h:151
CollisionGeometry()
Definition collision_object.h:96
CoalScalar aabb_radius
AABB radius.
Definition collision_object.h:154
Main namespace.
Definition broadphase_bruteforce.h:44
Eigen::Matrix< CoalScalar, 6, 1 > Vec6s
Definition data_types.h:79
bool isEqual(const Eigen::MatrixBase< Derived > &lhs, const Eigen::MatrixBase< OtherDerived > &rhs, const CoalScalar tol=std::numeric_limits< CoalScalar >::epsilon() *100)
Definition tools.h:204
OcTreePtr_t makeOctree(const Eigen::Matrix< CoalScalar, Eigen::Dynamic, 3 > &point_cloud, const CoalScalar resolution)
Build an OcTree from a point cloud and a given resolution.
NODE_TYPE
traversal node type: bounding volume (AABB, OBB, RSS, kIOS, OBBRSS, KDOP16, KDOP18,...
Definition collision_object.h:64
shared_ptr< OcTree > OcTreePtr_t
Definition fwd.hh:145
OBJECT_TYPE
object type: BVH (mesh, points), basic geometry, octree
Definition collision_object.h:52
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition data_types.h:77
double CoalScalar
Definition data_types.h:76