Skip to content

Commit ccbb539

Browse files
committed
Add function to load a point cloud as obstacle.
1 parent 985e0eb commit ccbb539

File tree

3 files changed

+105
-0
lines changed

3 files changed

+105
-0
lines changed

idl/hpp/corbaserver/obstacle.idl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,20 @@ module hpp
5050
void loadObstacleModelFromString (in string urdfString, in string prefix)
5151
raises (Error);
5252

53+
/// Load (or update if it exists) a point cloud from a filename.
54+
///
55+
/// \param filename a filename whose format must be compatible with Octomap
56+
void loadPointCloudFromFilename (in string objectName, in string filename)
57+
raises (Error);
58+
59+
/// Load (or update if it exists) a point cloud from a set of points
60+
///
61+
/// \param resolution OcTree resolution. See Octomap::OcTree for more info.
62+
/// \param points a Nx3 matrix representing the point cloud.
63+
void loadPointCloudFromPoints (in string objectName, in double resolution,
64+
in floatSeqSeq points)
65+
raises (Error);
66+
5367
/// \brief Remove an obstacle
5468
///
5569
/// \param objectName name of the object to remove

src/obstacle.impl.cc

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <coal/BVH/BVH_model.h>
3737
#include <coal/mesh_loader/loader.h>
3838
#include <coal/shape/geometric_shapes.h>
39+
#include <coal/octree.h>
3940

4041
#include <hpp/corbaserver/server-plugin.hh>
4142
#include <hpp/pinocchio/collision-object.hh>
@@ -82,6 +83,89 @@ void Obstacle::loadObstacleModelFromString(const char* urdfString,
8283
}
8384
}
8485

86+
void Obstacle::loadPointCloudFromFilename(const char* objectName,
87+
const char* filename) {
88+
try {
89+
core::ProblemSolverPtr_t ps = problemSolver();
90+
pinocchio::GeomModelPtr_t gm = ps->obstacleGeomModel();
91+
92+
if (gm->existGeometryName(objectName)) {
93+
// check that the existing geometry is of type coal::OcTree
94+
::pinocchio::GeomIndex id = gm->getGeometryId(objectName);
95+
coal::shared_ptr<coal::OcTree> octree =
96+
coal::dynamic_pointer_cast<coal::OcTree>
97+
(gm->geometryObjects[id].geometry);
98+
if (!octree) {
99+
HPP_THROW(Error, "Obstacle " << objectName << " exists but is not of the correct type.");
100+
}
101+
std::shared_ptr<octomap::OcTree> tree = std::const_pointer_cast<octomap::OcTree>(octree->getTree());
102+
// Update octree
103+
tree->clear();
104+
tree->readBinary(filename);
105+
octree->computeLocalAABB();
106+
} else {
107+
std::shared_ptr<octomap::OcTree> octree(new octomap::OcTree(filename));
108+
coal::CollisionObject colobj (
109+
coal::CollisionGeometryPtr_t(new coal::OcTree(octree))
110+
);
111+
ps->addObstacle(objectName, colobj, true, true);
112+
}
113+
114+
} catch (const std::exception& exc) {
115+
throw hpp::Error(exc.what());
116+
}
117+
}
118+
119+
void Obstacle::loadPointCloudFromPoints(const char* objectName,
120+
const CORBA::Double resolution,
121+
const floatSeqSeq& points) {
122+
auto N = points.length();
123+
if (N > 0 && points[0].length() != 3) {
124+
HPP_THROW(Error, "points must be a Nx3 matrix (or an empty matrix).");
125+
}
126+
try {
127+
core::ProblemSolverPtr_t ps = problemSolver();
128+
pinocchio::GeomModelPtr_t gm = ps->obstacleGeomModel();
129+
130+
coal::shared_ptr<coal::OcTree> octree;
131+
std::shared_ptr<octomap::OcTree> tree;
132+
if (gm->existGeometryName(objectName)) {
133+
// check that the existing geometry is of type coal::OcTree
134+
::pinocchio::GeomIndex id = gm->getGeometryId(objectName);
135+
octree = coal::dynamic_pointer_cast<coal::OcTree> (gm->geometryObjects[id].geometry);
136+
if (!octree) {
137+
HPP_THROW(Error, "Obstacle " << objectName << " exists but is not of the correct type.");
138+
}
139+
tree = std::const_pointer_cast<octomap::OcTree>(octree->getTree());
140+
if (tree->getResolution() != resolution) {
141+
HPP_THROW(Error, "A point cloud with name " << objectName <<
142+
" exists with resolution " << tree->getResolution() <<
143+
", which is different from the asked resolution (" << resolution
144+
<< ").\nYou can either remove the obstacle or stick the existing "
145+
"resolution."
146+
);
147+
}
148+
tree->clear();
149+
} else {
150+
tree = std::make_shared<octomap::OcTree>(resolution);
151+
octree = std::make_shared<coal::OcTree>(tree);
152+
coal::CollisionObject colobj (
153+
octree,
154+
false // Dont compute the local AABB as the octree is not ready yet.
155+
);
156+
ps->addObstacle(objectName, colobj, true, true);
157+
}
158+
159+
for (decltype(N) i = 0; i < N; ++i) {
160+
tree->updateNode(points[i][0], points[i][1], points[i][2], true, true);
161+
}
162+
tree->updateInnerOccupancy();
163+
octree->computeLocalAABB();
164+
} catch (const std::exception& exc) {
165+
throw hpp::Error(exc.what());
166+
}
167+
}
168+
85169
void Obstacle::loadPolyhedron(const char* name, const char* resourcename) {
86170
try {
87171
coal::MeshLoader loader(coal::BV_OBBRSS);

src/obstacle.impl.hh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ class Obstacle : public virtual POA_hpp::corbaserver::Obstacle {
5757
virtual void loadObstacleModelFromString(const char* urdfString,
5858
const char* prefix);
5959

60+
virtual void loadPointCloudFromFilename(const char* objectName,
61+
const char* filename);
62+
63+
virtual void loadPointCloudFromPoints(const char* objectName,
64+
const CORBA::Double resolution,
65+
const floatSeqSeq& points);
66+
6067
virtual void loadPolyhedron(const char* name, const char* filename);
6168

6269
virtual void removeObstacleFromJoint(const char* objectName,

0 commit comments

Comments
 (0)