11 #include <std_srvs/EmptyRequest.h> 12 #include <std_srvs/EmptyResponse.h> 13 #include <boost/thread.hpp> 14 #include <boost/thread/mutex.hpp> 15 #include <octomap_server/OctomapServer.h> 19 #define SAFE_DELETE(x) if((x)) { delete (x); x = NULL; } 20 bool is_equal (
double a,
double b,
double epsilon = 1.0e-7)
22 return std::abs(a - b) < epsilon;
27 OctomapInterface::OctomapInterface(ros::NodeHandle& nodeHandle, OpenRAVE::EnvironmentBasePtr env):
28 SensorSystemBase(env), OctomapServer(nodeHandle), m_shouldExit(false)
31 m_pointCloudSub->unsubscribe();
33 delete m_tfPointCloudSub;
35 m_pointCloudSub =
new message_filters::Subscriber<sensor_msgs::PointCloud2> (m_nh,
"/cloud_in", 1, ros::TransportHints(), &
m_queue);
36 m_tfPointCloudSub =
new tf::MessageFilter<sensor_msgs::PointCloud2> (*m_pointCloudSub, m_tfListener, m_worldFrameId, 1, m_nh, ros::Duration(0.01));
39 ROS_INFO(
"Frame ID: %s", m_worldFrameId.c_str());
40 ROS_INFO(
"Topic: %s", m_pointCloudSub->getTopic().c_str());
43 "Begin collision testing octomap");
45 "Stop collision testing octomap.");
47 "Mask an object out of the octomap");
49 "Toggles the octomap to being paused/unpaused for collecting data");
51 "Save the OcTree to a file.");
53 "Reset the octomap.");
55 "Reset the point cloud topic.");
57 "Reset the octomap resolution.");
59 "Reset the octomap frame_id.");
63 m_reconfigureServer.clearCallback();
67 octomap_server::OctomapServerConfig config;
69 ros::param::get(
"or_octomap/max_depth", max_tree_depth);
70 m_maxTreeDepth = unsigned(max_tree_depth);
71 ros::param::get(
"or_octomap/pointcloud_min_z", m_pointcloudMinZ);
72 ros::param::get(
"or_octomap/pointcloud_max_z", m_pointcloudMaxZ);
73 ros::param::get(
"or_octomap/occupancy_min_z", m_occupancyMinZ);
74 ros::param::get(
"or_octomap/occupancy_max_z", m_occupancyMaxZ);
75 ros::param::get(
"or_octomap/filter_speckles", m_filterSpeckles);
76 ros::param::get(
"or_octomap/filter_ground", m_filterGroundPlane);
77 ros::param::get(
"or_octomap/compress_map", m_compressMap);
78 ros::param::get(
"or_octomap/incremental_2D_projection", m_incrementalUpdate);
79 ros::param::get(
"or_octomap/ground_filter_distance", m_groundFilterDistance);
80 ros::param::get(
"or_octomap/ground_filter_angle", m_groundFilterAngle);
81 ros::param::get(
"or_octomap/ground_filter_plane_distance", m_groundFilterPlaneDistance);
82 ros::param::get(
"or_octomap/sensor_model_max_range", m_maxRange);
84 double sensor_model_min;
85 double sensor_model_max;
86 double sensor_model_hit;
87 double sensor_model_miss;
88 ros::param::get(
"or_octomap/sensor_model_min", sensor_model_min);
89 ros::param::get(
"or_octomap/sensor_model_max", sensor_model_max);
90 ros::param::get(
"or_octomap/sensor_model_hit", sensor_model_hit);
91 ros::param::get(
"or_octomap/sensor_model_miss", sensor_model_miss);
92 m_octree->setClampingThresMin(sensor_model_min);
93 m_octree->setClampingThresMax(sensor_model_max);
95 if (
is_equal(sensor_model_hit, 1.0)) sensor_model_hit -= 1.0e-6;
96 m_octree->setProbHit(sensor_model_hit);
97 if (
is_equal(sensor_model_miss, 0.0)) sensor_model_miss += 1.0e-6;
98 m_octree->setProbMiss(sensor_model_miss);
99 config.max_depth = max_tree_depth;
100 config.pointcloud_min_z = m_pointcloudMinZ;
101 config.pointcloud_max_z = m_pointcloudMaxZ;
102 config.occupancy_min_z = m_occupancyMinZ;
103 config.occupancy_max_z = m_occupancyMaxZ;
104 config.filter_speckles = m_filterSpeckles;
105 config.filter_ground = m_filterGroundPlane;
106 config.compress_map = m_compressMap;
107 config.incremental_2D_projection = m_incrementalUpdate;
108 config.ground_filter_distance = m_groundFilterDistance;
109 config.ground_filter_angle = m_groundFilterAngle;
110 config.ground_filter_plane_distance = m_groundFilterPlaneDistance;
111 config.sensor_model_max_range = m_maxRange;
112 config.sensor_model_min = sensor_model_min;
113 config.sensor_model_max = sensor_model_max;
114 config.sensor_model_hit = sensor_model_hit;
115 config.sensor_model_miss = sensor_model_miss;
117 boost::recursive_mutex::scoped_lock reconf_lock(m_config_mutex);
118 m_reconfigureServer.updateConfig(config);
119 reconf_lock.unlock();
146 bool lastCollisionState =
false;
150 OpenRAVE::CollisionReportPtr report(
new OpenRAVE::CollisionReport());
151 OpenRAVE::KinBodyConstPtr fakeBody = GetEnv()->GetKinBody(
"_OCTOMAP_MAP_");
152 OpenRAVE::KinBodyPtr fuze = GetEnv()->GetKinBody(
"fuze_bottle");
156 bool collides = GetEnv()->CheckCollision(fakeBody, report);
158 ROS_INFO(
"Collides: %s", collides ?
"true" :
"false");
160 OpenRAVE::Transform t;
163 float r = 0.1 * cos(timey * 0.1f);
164 t.trans = OpenRAVE::Vector(r * sin(timey) + 0.5f, r * cos(timey), 0.0f);
168 fuze->SetTransform(t);
170 lastCollisionState = collides;
178 ros::WallDuration timeout(0.01);
195 ROS_DEBUG(
"Set enabled called!");
206 OpenRAVE::CollisionCheckerBasePtr collisionCheckerBase = RaveCreateCollisionChecker(GetEnv(),
"or_octomap_checker");
213 GetEnv()->SetCollisionChecker(collisionCheckerBase);
228 OpenRAVE::KinBodyPtr kinBody = GetEnv()->GetKinBody(
"_OCTOMAP_MAP_");
232 GetEnv()->Remove(kinBody);
238 ROS_DEBUG(
"Creating fake body!");
239 OpenRAVE::KinBodyPtr kinbody = RaveCreateKinBody(GetEnv(),
"");
240 kinbody->SetName(
"_OCTOMAP_MAP_");
241 GetEnv()->Add(kinbody);
246 return SensorSystemBase::SendCommand(os, is);
251 std_srvs::EmptyRequest req;
252 std_srvs::EmptyResponse res;
258 ROS_DEBUG(
"Reset the octomap.");
263 ros::Duration(0.1).sleep();
264 std_srvs::EmptyRequest req;
265 std_srvs::EmptyResponse res;
277 ROS_INFO(
"Reset resolution as %f", std::atof(strRes.c_str()));
278 double resolution = std::atof(strRes.c_str());
284 ros::Duration(0.1).sleep();
286 m_octree->setResolution(resolution);
287 std_srvs::EmptyRequest req;
288 std_srvs::EmptyResponse res;
300 ROS_INFO(
"Reset frame_id as %s", frameID.c_str());
306 ros::Duration(0.1).sleep();
312 m_worldFrameId = frameID;
313 delete m_tfPointCloudSub;
315 m_tfPointCloudSub =
new tf::MessageFilter<sensor_msgs::PointCloud2> (*m_pointCloudSub, m_tfListener, m_worldFrameId, 1, m_nh, ros::Duration(0.1));
318 std_srvs::EmptyRequest req;
319 std_srvs::EmptyResponse res;
330 std::string objectName;
333 ROS_DEBUG(
"Masking object %s", objectName.c_str());
346 std::string file_name;
349 ROS_DEBUG(
"Saving the tree to the file: %s", file_name.c_str());
356 std::size_t octomapSize = m_octree->size();
358 if (octomapSize <= 1){
359 ROS_WARN(
"The octree is empty, could not save the octomap to the file %s.", file_name.c_str());
363 std::string vrmlFilename =
"";
364 vrmlFilename = file_name +
".wrl";
366 std::ofstream outfile (vrmlFilename.c_str());
367 outfile <<
"#VRML V2.0 utf8\n#\n";
368 outfile <<
"# created from OctoMap \n";
370 octomap::OcTree* tree =
GetTree();
372 std::size_t count(0);
373 for(octomap::OcTree::iterator it = tree->begin(m_maxTreeDepth), end=tree->end(); it!= end; ++it) {
374 if(tree->isNodeOccupied(*it)){
376 double size = it.getSize();
377 double x = it.getX();
378 double y = it.getY();
379 double z = it.getZ();
381 geometry_msgs::Point cubeCenter;
386 double minX, minY, minZ, maxX, maxY, maxZ;
387 m_octree->getMetricMin(minX, minY, minZ);
388 m_octree->getMetricMax(maxX, maxY, maxZ);
389 double h = (1.0 -
std::min(
std::max((cubeCenter.z-minZ)/ (maxZ - minZ), 0.0), 1.0)) *m_colorFactor;
390 std_msgs::ColorRGBA _color = heightMapColor(h);
392 outfile <<
"Transform { translation " 393 << it.getX() <<
" " << it.getY() <<
" " << it.getZ()
394 <<
" \n children [ Shape { " 395 <<
"appearance Appearance { material Material { diffuseColor " 396 << _color.r <<
" "<< _color.g <<
" " << _color.b <<
" } } " 397 <<
"geometry Box { size " << size <<
" " << size <<
" " << size <<
" }" 402 std::cout <<
"Finished writing "<< count <<
" voxels to " << vrmlFilename << std::endl;
408 std::string topic_name;
411 ROS_INFO(
"Reset the point cloud topic as: %s",topic_name.c_str());
418 m_pointCloudSub->unsubscribe();
421 delete m_tfPointCloudSub;
423 m_pointCloudSub =
new message_filters::Subscriber<sensor_msgs::PointCloud2> (m_nh, topic_name, 1, ros::TransportHints(), &
m_queue);
424 m_tfPointCloudSub =
new tf::MessageFilter<sensor_msgs::PointCloud2> (*m_pointCloudSub, m_tfListener, m_worldFrameId, 1, m_nh, ros::Duration(0.1));
427 ROS_DEBUG(
"Topic: %s", m_pointCloudSub->getTopic().c_str());
void SetWrappedChecker(OpenRAVE::CollisionCheckerBasePtr checker)
boost::mutex m_cloudQueueMutex
bool MaskObject(std::ostream &os, std::istream &i)
float max(float a, float b, float c)
bool TogglePause(std::ostream &os, std::istream &i)
virtual ~OctomapInterface()
bool Disable(std::ostream &os, std::istream &i)
void SetInterface(OctomapInterface *interface)
bool ResetTopic(std::ostream &os, std::istream &i)
octomap::OcTree * GetTree()
bool Enable(std::ostream &os, std::istream &i)
std::vector< sensor_msgs::PointCloud2ConstPtr > m_cloudQueue
bool ResetTree(std::ostream &os, std::istream &i)
float min(float a, float b, float c)
ros::CallbackQueue m_queue
OctomapCollisionChecker * m_collisionChecker
void InsertCloudWrapper(const sensor_msgs::PointCloud2::ConstPtr &cloud)
bool is_equal(double a, double b, double epsilon=1.0e-7)
bool MaskObject(std::string name)
bool SaveTree(std::ostream &os, std::istream &i)
bool ResetFrame(std::ostream &os, std::istream &i)
void SetEnabled(bool enabled)
bool ResetResolution(std::ostream &os, std::istream &i)
OpenRAVE::CollisionCheckerBasePtr GetWrappedChecker()
virtual bool SendCommand(std::ostream &os, std::istream &is)