Tesseract
Motion Planning Environment
Loading...
Searching...
No Matches
octree.h
Go to the documentation of this file.
1
26#ifndef TESSERACT_GEOMETRY_OCTREE_H
27#define TESSERACT_GEOMETRY_OCTREE_H
28
31#include <boost/serialization/access.hpp>
32#include <boost/serialization/export.hpp>
33#include <Eigen/Geometry>
34#include <memory>
35#include <octomap/octomap.h>
37
39
40namespace tesseract_geometry
41{
42class Octree : public Geometry
43{
44public:
45 using Ptr = std::shared_ptr<Octree>;
46 using ConstPtr = std::shared_ptr<const Octree>;
47
49 {
53 };
54
55 Octree(std::shared_ptr<const octomap::OcTree> octree, const SubType sub_type)
56 : Geometry(GeometryType::OCTREE), octree_(std::move(octree)), sub_type_(sub_type)
57 {
58 }
59
60 template <typename PointT>
61 Octree(const PointT& point_cloud,
62 const double resolution,
63 const SubType sub_type,
64 const bool prune,
65 const bool binary = true)
66 : Geometry(GeometryType::OCTREE), sub_type_(sub_type), resolution_(resolution)
67 {
68 auto ot = std::make_shared<octomap::OcTree>(resolution);
69
70 for (auto& point : point_cloud.points)
71 ot->updateNode(point.x, point.y, point.z, true, true);
72
73 // Per the documentation for overload updateNode above with lazy_eval enabled this must be called after all points
74 // are added
75 ot->updateInnerOccupancy();
76 if (binary)
77 {
78 ot->toMaxLikelihood();
79 binary_octree_ = binary;
80 }
81
82 if (prune)
83 {
85 pruned_ = prune;
86 }
87
88 octree_ = ot;
89 }
90
91 Octree() = default;
92 ~Octree() override = default;
93
94 const std::shared_ptr<const octomap::OcTree>& getOctree() const { return octree_; }
95
96 SubType getSubType() const { return sub_type_; }
97
98 bool getPruned() const { return pruned_; }
99
100 Geometry::Ptr clone() const override final { return std::make_shared<Octree>(octree_, sub_type_); }
101 bool operator==(const Octree& rhs) const;
102 bool operator!=(const Octree& rhs) const;
103
108 void update() { assert(false); } // NOLINT
109
117 long calcNumSubShapes() const
118 {
119 long cnt = 0;
120 double occupancy_threshold = octree_->getOccupancyThres();
121 for (auto it = octree_->begin(static_cast<unsigned char>(octree_->getTreeDepth())), end = octree_->end(); it != end;
122 ++it)
123 if (it->getOccupancy() >= occupancy_threshold)
124 ++cnt;
125
126 return cnt;
127 }
128
129private:
130 std::shared_ptr<const octomap::OcTree> octree_;
132 double resolution_{ 0.01 };
133 bool pruned_{ false };
134 bool binary_octree_{ false };
135
136 static bool isNodeCollapsible(octomap::OcTree& octree, octomap::OcTreeNode* node)
137 {
138 if (!octree.nodeChildExists(node, 0))
139 return false;
140
141 double occupancy_threshold = octree.getOccupancyThres();
142
143 const octomap::OcTreeNode* firstChild = octree.getNodeChild(node, 0);
144 if (octree.nodeHasChildren(firstChild) || firstChild->getOccupancy() < occupancy_threshold)
145 return false;
146
147 for (unsigned int i = 1; i < 8; i++)
148 {
149 // comparison via getChild so that casts of derived classes ensure
150 // that the right == operator gets called
151 if (!octree.nodeChildExists(node, i))
152 return false;
153
154 if (octree.nodeHasChildren(octree.getNodeChild(node, i)))
155 return false;
156
157 if (octree.getNodeChild(node, i)->getOccupancy() < occupancy_threshold)
158 return false;
159 }
160
161 return true;
162 }
163
164 static bool pruneNode(octomap::OcTree& octree, octomap::OcTreeNode* node)
165 {
166 if (!isNodeCollapsible(octree, node))
167 return false;
168
169 // set value to children's values (all assumed equal)
170 node->copyData(*(octree.getNodeChild(node, 0)));
171
172 // delete children (known to be leafs at this point!)
173 for (unsigned int i = 0; i < 8; i++)
174 {
175 octree.deleteNodeChild(node, i);
176 }
177
178 return true;
179 }
180
181 // NOLINTNEXTLINE(misc-no-recursion)
182 static void pruneRecurs(octomap::OcTree& octree,
183 octomap::OcTreeNode* node,
184 unsigned int depth,
185 unsigned int max_depth,
186 unsigned int& num_pruned)
187 {
188 assert(node);
189
190 if (depth < max_depth)
191 {
192 for (unsigned int i = 0; i < 8; i++)
193 {
194 if (octree.nodeChildExists(node, i))
195 {
196 pruneRecurs(octree, octree.getNodeChild(node, i), depth + 1, max_depth, num_pruned);
197 }
198 }
199 } // end if depth
200
201 else
202 {
203 // max level reached
204 if (pruneNode(octree, node))
205 {
206 num_pruned++;
207 }
208 }
209 }
210
212 template <class Archive>
213 void save(Archive& ar, const unsigned int version) const; // NOLINT
214
215 template <class Archive>
216 void load(Archive& ar, const unsigned int version); // NOLINT
217
218 template <class Archive>
219 void serialize(Archive& ar, const unsigned int version); // NOLINT
220
221public:
230 static void prune(octomap::OcTree& octree)
231 {
232 if (octree.getRoot() == nullptr)
233 return;
234
235 for (unsigned int depth = octree.getTreeDepth() - 1; depth > 0; --depth)
236 {
237 unsigned int num_pruned = 0;
238 pruneRecurs(octree, octree.getRoot(), 0, depth, num_pruned);
239 if (num_pruned == 0)
240 break;
241 }
242 }
243};
244} // namespace tesseract_geometry
245
246BOOST_CLASS_EXPORT_KEY2(tesseract_geometry::Octree, "Octree")
247#endif
Definition: geometry.h:60
std::shared_ptr< Geometry > Ptr
Definition: geometry.h:62
Definition: octree.h:43
bool getPruned() const
Definition: octree.h:98
double resolution_
Definition: octree.h:132
std::shared_ptr< const Octree > ConstPtr
Definition: octree.h:46
bool operator!=(const Octree &rhs) const
Definition: octree.cpp:74
void update()
Octrees are typically generated from 3D sensor data so this method should be used to efficiently upda...
Definition: octree.h:108
std::shared_ptr< Octree > Ptr
Definition: octree.h:45
static bool isNodeCollapsible(octomap::OcTree &octree, octomap::OcTreeNode *node)
Definition: octree.h:136
Geometry::Ptr clone() const override final
Create a copy of this shape.
Definition: octree.h:100
bool operator==(const Octree &rhs) const
Definition: octree.cpp:40
SubType
Definition: octree.h:49
@ BOX
Definition: octree.h:50
@ SPHERE_OUTSIDE
Definition: octree.h:52
@ SPHERE_INSIDE
Definition: octree.h:51
static void prune(octomap::OcTree &octree)
A custom octree prune which will prune if all children are above the occupancy threshold.
Definition: octree.h:230
void load(Archive &ar, const unsigned int version)
Definition: octree.cpp:101
static void pruneRecurs(octomap::OcTree &octree, octomap::OcTreeNode *node, unsigned int depth, unsigned int max_depth, unsigned int &num_pruned)
Definition: octree.h:182
SubType sub_type_
Definition: octree.h:131
Octree(std::shared_ptr< const octomap::OcTree > octree, const SubType sub_type)
Definition: octree.h:55
~Octree() override=default
bool binary_octree_
Definition: octree.h:134
friend class boost::serialization::access
Definition: octree.h:211
std::shared_ptr< const octomap::OcTree > octree_
Definition: octree.h:130
void serialize(Archive &ar, const unsigned int version)
Definition: octree.cpp:133
Octree(const PointT &point_cloud, const double resolution, const SubType sub_type, const bool prune, const bool binary=true)
Definition: octree.h:61
const std::shared_ptr< const octomap::OcTree > & getOctree() const
Definition: octree.h:94
void save(Archive &ar, const unsigned int version) const
Definition: octree.cpp:77
bool pruned_
Definition: octree.h:133
long calcNumSubShapes() const
Calculate the number of sub shapes that would get generated for this octree.
Definition: octree.h:117
static bool pruneNode(octomap::OcTree &octree, octomap::OcTreeNode *node)
Definition: octree.h:164
SubType getSubType() const
Definition: octree.h:96
auto it
Definition: collision_core_unit.cpp:208
Common Tesseract Macros.
#define TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
Definition: macros.h:71
Definition: create_convex_hull.cpp:36
Definition: geometry.h:39
GeometryType
Definition: geometry.h:41
@ OCTREE
Definition: geometry.h:52
Tesseract Geometries.
auto octree
Definition: tesseract_geometry_unit.cpp:27