00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <srs_env_model/but_server/plugins/octomap_plugin.h>
00029 #include <srs_env_model/topics_list.h>
00030 #include <srs_env_model/but_server/plugins/point_cloud_plugin.h>
00031
00032
00033 #include <pcl_ros/transforms.h>
00034 #include <pcl/io/io.h>
00035
00036
00037 #include <visualization_msgs/MarkerArray.h>
00038 #include <visualization_msgs/Marker.h>
00039
00040
00041 #include <srs_interaction_primitives/AddUnknownObject.h>
00042
00043 #define DEFAULT_RESOLUTION 0.1
00044
00045 void srs_env_model::COctoMapPlugin::setDefaults()
00046 {
00047
00048 m_mapParameters.resolution = DEFAULT_RESOLUTION;
00049 m_mapParameters.treeDepth = 0;
00050 m_mapParameters.probHit = 0.7;
00051 m_mapParameters.probMiss = 0.4;
00052 m_mapParameters.thresMin = 0.12;
00053 m_mapParameters.thresMax = 0.97;
00054 m_mapParameters.thresOccupancy = 0.5;
00055 m_mapParameters.maxRange = 7;
00056
00057
00058 m_filterGroundPlane = false;
00059 m_removeSpecles = false;
00060 m_mapParameters.frameId = "/map";
00061 m_bPublishOctomap = true;
00062
00063
00064 m_bRemoveOutdated = true;
00065 m_removeTester = 0;
00066 m_testerLife = 1;
00067
00068
00069 m_crawlDepth = 0;
00070 m_bMapLoaded = false;
00071 m_bNotFirst = false;
00072
00073 m_probDeleted = m_mapParameters.probMiss * 0.1;
00074 m_r = m_g = m_b = 128;
00075 }
00076
00077 srs_env_model::COctoMapPlugin::COctoMapPlugin(const std::string & name)
00078 : srs_env_model::CServerPluginBase(name)
00079 , CDataHolderBase< tButServerOcMap >( new tButServerOcMap(DEFAULT_RESOLUTION) )
00080 , filecounter(0)
00081 , m_filterSingleSpecles("/map")
00082 , m_filterRaycast("/map")
00083 , m_filterGround("/map")
00084 , m_bFilterWithInput(false)
00085 , m_bNewDataToFilter(false)
00086 , m_bMapLoaded(false)
00087 {
00088
00089 setDefaults();
00090
00091 assert( m_data != 0 );
00092
00093
00094 m_data->getTree().setProbHit(m_mapParameters.probHit);
00095 m_data->getTree().setProbMiss(m_mapParameters.probMiss);
00096 m_data->getTree().setClampingThresMin(m_mapParameters.thresMin);
00097 m_data->getTree().setClampingThresMax(m_mapParameters.thresMax);
00098 m_data->getTree().setOccupancyThres(m_mapParameters.thresOccupancy);
00099 m_mapParameters.treeDepth = m_data->getTree().getTreeDepth();
00100 m_mapParameters.map = m_data;
00101 m_mapParameters.crawlDepth = m_crawlDepth;
00102 }
00103
00104 srs_env_model::COctoMapPlugin::COctoMapPlugin(const std::string & name, const std::string & filename)
00105 : srs_env_model::CServerPluginBase(name)
00106 , CDataHolderBase< tButServerOcMap >( new tButServerOcMap(DEFAULT_RESOLUTION) )
00107 , m_filterSingleSpecles("/map")
00108 , m_filterRaycast("/map")
00109 , m_filterGround("/map")
00110 , m_bFilterWithInput(false)
00111 , m_filterCloudPlugin(new CPointCloudPlugin("PCFILTER", false ))
00112 , m_bNewDataToFilter(false)
00113 , m_bMapLoaded(false)
00114 {
00115 setDefaults();
00116
00117 assert( m_data != 0 );
00118
00119
00120 m_data->getTree().setProbHit(m_mapParameters.probHit);
00121 m_data->getTree().setProbMiss(m_mapParameters.probMiss);
00122 m_data->getTree().setClampingThresMin(m_mapParameters.thresMin);
00123 m_data->getTree().setClampingThresMax(m_mapParameters.thresMax);
00124 m_data->getTree().setOccupancyThres(m_mapParameters.thresOccupancy);
00125 m_mapParameters.treeDepth = m_data->getTree().getTreeDepth();
00126 m_mapParameters.map = m_data;
00127 m_mapParameters.crawlDepth = m_crawlDepth;
00128
00129
00130 if (filename.length() > 0) {
00131
00132 if (m_data->getTree().readBinary(filename)) {
00133 ROS_INFO("Octomap file %s loaded (%zu nodes).", filename.c_str(), m_data->getTree().size());
00134
00135
00136 m_mapParameters.treeDepth = m_data->getTree().getTreeDepth();
00137
00138
00139 m_mapParameters.resolution = m_data->getTree().getResolution();
00140
00141
00142 m_bMapLoaded = true;
00143
00144
00145 invalidate();
00146
00147 } else {
00148
00149
00150 ROS_ERROR("Could not open requested file %s, continuing in standard mode.", filename.c_str());
00151 PERROR( "Transform error.");
00152 }
00153 }
00154 }
00155
00159 srs_env_model::COctoMapPlugin::~COctoMapPlugin()\
00160 {
00161
00162 if (m_removeTester != 0)
00163 delete m_removeTester;
00164 }
00165
00167 void srs_env_model::COctoMapPlugin::init(ros::NodeHandle & node_handle)
00168 {
00169 PERROR( "Initializing OctoMapPlugin" );
00170
00171 reset(false);
00172
00173 node_handle.param("ocmap_resolution", m_mapParameters.resolution,
00174 m_mapParameters.resolution);
00175 int td( m_mapParameters.treeDepth);
00176 node_handle.param("ocmap_treedepth", td, td );
00177 m_mapParameters.treeDepth = ( td < 0 ) ? 0 : td;
00178 node_handle.param("ocmap_sensor_model/hit", m_mapParameters.probHit,
00179 m_mapParameters.probHit);
00180 node_handle.param("ocmap_sensor_model/miss", m_mapParameters.probMiss,
00181 m_mapParameters.probMiss);
00182 node_handle.param("ocmap_sensor_model/min", m_mapParameters.thresMin,
00183 m_mapParameters.thresMin);
00184 node_handle.param("ocmap_sensor_model/max", m_mapParameters.thresMax,
00185 m_mapParameters.thresMax);
00186 node_handle.param("ocmap_max_range", m_mapParameters.maxRange,
00187 m_mapParameters.maxRange);
00188
00189 node_handle.param("ocmap_frame_id", m_mapParameters.frameId, m_mapParameters.frameId );
00190
00191
00192 {
00193 m_data->getTree().setResolution(m_mapParameters.resolution);
00194 m_data->getTree().setProbHit(m_mapParameters.probHit);
00195 m_data->getTree().setProbMiss(m_mapParameters.probMiss);
00196 m_data->getTree().setClampingThresMin(m_mapParameters.thresMin);
00197 m_data->getTree().setClampingThresMax(m_mapParameters.thresMax);
00198 }
00199
00200
00201 int c;
00202 c = m_r; node_handle.param("pointcloud_default_color_r", c, c); m_r = c;
00203 c = m_g; node_handle.param("pointcloud_default_color_g", c, c); m_g = c;
00204 c = m_b; node_handle.param("pointcloud_default_color_b", c, c); m_b = c;
00205
00206
00207 node_handle.param("ocmap_filter_ground", m_filterGroundPlane, m_filterGroundPlane);
00208
00209
00210 node_handle.param("ocmap_filter_outdated", m_bRemoveOutdated, m_bRemoveOutdated );
00211
00212
00213 node_handle.param("use_input_for_filter", m_bFilterWithInput, m_bFilterWithInput );
00214
00215
00216 node_handle.param("ocmap_publishing_topic", m_ocPublisherName,
00217 OCTOMAP_PUBLISHER_NAME);
00218
00219
00220 m_serviceResetOctomap = node_handle.advertiseService(ResetOctomap_SRV,
00221 &srs_env_model::COctoMapPlugin::resetOctomapCB, this);
00222
00223 m_serviceRemoveCube = node_handle.advertiseService(RemoveCubeOctomap_SRV,
00224 &srs_env_model::COctoMapPlugin::removeCubeCB, this);
00225
00226 m_serviceAddCube = node_handle.advertiseService( AddCubeOctomap_SRV,
00227 &srs_env_model::COctoMapPlugin::addCubeCB, this);
00228
00229 m_serviceSetCrawlDepth = node_handle.advertiseService( SetCrawlDepth_SRV,
00230 &srs_env_model::COctoMapPlugin::setCrawlingDepthCB, this );
00231
00232 m_serviceGetTreeDepth = node_handle.advertiseService( GetTreeDepth_SRV,
00233 &srs_env_model::COctoMapPlugin::getTreeDepthCB, this );
00234
00235 m_serviceLoadMap = node_handle.advertiseService( LoadMap_SRV,
00236 &srs_env_model::COctoMapPlugin::loadOctreeCB, this);
00237
00238 m_serviceSaveMap = node_handle.advertiseService( SaveMap_SRV,
00239 &srs_env_model::COctoMapPlugin::saveOctreeCB, this);
00240
00241 m_serviceLoadFullMap = node_handle.advertiseService( LoadFullMap_SRV,
00242 &srs_env_model::COctoMapPlugin::loadFullOctreeCB, this);
00243
00244 m_serviceSaveFullMap = node_handle.advertiseService( SaveFullMap_SRV,
00245 &srs_env_model::COctoMapPlugin::saveFullOctreeCB, this);
00246
00247
00248
00249 m_ocPublisher = node_handle.advertise<octomap_ros::OctomapBinary> (
00250 m_ocPublisherName, 5, m_latchedTopics);
00251
00252 m_registration.init( node_handle );
00253
00254 PERROR( "OctoMapPlugin initialized..." );
00255
00256 m_bNotFirst = false;
00257
00258 m_probDeleted = m_mapParameters.probMiss * 0.1;
00259
00260
00261 m_filterSingleSpecles.setTreeFrameId(m_mapParameters.frameId);
00262 m_filterRaycast.setTreeFrameId(m_mapParameters.frameId);
00263 m_filterRaycast.init(node_handle);
00264 m_filterGround.setTreeFrameId(m_mapParameters.frameId);
00265 m_filterGround.init(node_handle);
00266
00267
00268 m_filterSingleSpecles.setRunMode( COcTreeFilterBase::FILTER_TEST_TIME );
00269 m_filterSingleSpecles.setTimerLap(20);
00270
00271
00272 if(!m_bFilterWithInput)
00273 {
00274
00275 std::cerr << "Initializing filter-in pointcloud plugin." << std::endl;
00276 m_filterCloudPlugin->init(node_handle, SUBSCRIBER_FILTERING_CLOUD_NAME);
00277
00278
00279 m_filterCloudPlugin->enable(false);
00280
00281
00282 m_filterCloudPlugin->getSigDataChanged().connect( boost::bind( &COctoMapPlugin::filterCloud, this, _1 ));
00283 }
00284 }
00285
00286 void srs_env_model::COctoMapPlugin::insertCloud(tPointCloud::ConstPtr cloud)
00287 {
00288
00289
00290
00291 boost::mutex::scoped_lock lock(m_lockData);
00292
00293
00294 tPointCloud used_cloud;
00295 pcl::copyPointCloud( *cloud, used_cloud );
00296
00297
00298 Eigen::Matrix4f registration_transform( Eigen::Matrix4f::Identity() );
00299
00300
00301 {
00302 if( m_registration.isRegistering() && cloud->size() > 0 && m_bNotFirst )
00303 {
00304
00305
00306 tPointCloudPtr cloudPtr( new tPointCloud );
00307 pcl::copyPointCloud( *cloud, *cloudPtr );
00308
00309 if( m_registration.registerCloud( cloudPtr, m_mapParameters ) )
00310 {
00311
00312
00313 registration_transform = m_registration.getTransform();
00314
00315
00316
00317
00318 }
00319 else
00320 {
00321
00322 return;
00323 }
00324 }
00325 }
00326
00327
00328
00329 tPointCloud pc_ground;
00330 tPointCloud pc_nonground;
00331
00332 if (m_filterGroundPlane)
00333 {
00334 m_filterGround.setCloud(&used_cloud);
00335 m_filterGround.filter(m_data->getTree());
00336 pc_ground = *m_filterGround.getGroundPc();
00337 pc_nonground = *m_filterGround.getNongroundPc();
00338
00339
00340 } else {
00341 pc_nonground = used_cloud;
00342 pc_ground.clear();
00343 pc_ground.header = used_cloud.header;
00344 pc_nonground.header = used_cloud.header;
00345 }
00346
00347 tf::StampedTransform cloudToMapTf;
00348
00349
00350
00351
00352 try {
00353
00354 m_tfListener.waitForTransform(m_mapParameters.frameId,
00355 cloud->header.frame_id, cloud->header.stamp, ros::Duration(5));
00356
00357 m_tfListener.lookupTransform(m_mapParameters.frameId,
00358 cloud->header.frame_id, cloud->header.stamp, cloudToMapTf);
00359
00360 } catch (tf::TransformException& ex) {
00361 ROS_ERROR_STREAM("Transform error: " << ex.what() << ", quitting callback");
00362 PERROR( "Transform error.");
00363 return;
00364 }
00365
00366
00367 if (m_mapParameters.frameId != cloud->header.frame_id)
00368 {
00369 Eigen::Matrix4f c2mTM;
00370
00371
00372
00373 pcl_ros::transformAsMatrix(cloudToMapTf, c2mTM);
00374 pcl::transformPointCloud(pc_ground, pc_ground, c2mTM);
00375 pcl::transformPointCloud(pc_nonground, pc_nonground, c2mTM);
00376 }
00377
00378
00379 pcl::transformPointCloud( pc_ground, pc_ground, registration_transform );
00380
00381 pc_ground.header = cloud->header;
00382 pc_ground.header.frame_id = m_mapParameters.frameId;
00383
00384 pc_nonground.header = cloud->header;
00385 pc_nonground.header.frame_id = m_mapParameters.frameId;
00386
00387
00388 m_DataTimeStamp = cloud->header.stamp;
00389 ROS_DEBUG("COctoMapPlugin::insertCloud(): Stamp = %f", cloud->header.stamp.toSec());
00390
00391 insertScan(cloudToMapTf.getOrigin(), pc_ground, pc_nonground);
00392
00393 if (m_removeSpecles)
00394 {
00395
00396 m_filterSingleSpecles.filter(m_data->getTree());
00397 m_filterSingleSpecles.writeLastRunInfo();
00398 }
00399
00400
00401 if (m_bRemoveOutdated && m_bFilterWithInput)
00402 {
00403
00404
00405
00406
00407
00408
00409
00410 }
00411 else
00412 m_bNewDataToFilter = true;
00413
00414
00415 ROS_DEBUG("Point cloud insertion in OctomapServer done (%zu+%zu pts (ground/nonground).)", pc_ground.size(),
00416 pc_nonground.size());
00417
00418
00419 if (m_removeTester != 0) {
00420 long removed = doObjectTesting(m_removeTester);
00421
00422 PERROR( "Removed leafs: " << removed);
00423
00424 if (removed > 0)
00425 m_data->getTree().prune();
00426
00427 --m_testerLifeCounter;
00428
00429 if (m_testerLifeCounter <= 0) {
00430 delete m_removeTester;
00431 m_removeTester = 0;
00432 }
00433 }
00434
00435
00436 lock.unlock();
00437
00438
00439
00440 m_bNotFirst = true;
00441
00442
00443 invalidate();
00444
00445
00446 }
00447
00451 void srs_env_model::COctoMapPlugin::insertScan(const tf::Point & sensorOriginTf,
00452 const tPointCloud & ground,
00453 const tPointCloud & nonground)
00454 {
00455 octomap::point3d sensorOrigin = octomap::pointTfToOctomap(sensorOriginTf);
00456
00457 double maxRange(m_mapParameters.maxRange);
00458
00459
00460
00461
00462
00463 m_data->getTree().insertColoredScan(nonground, sensorOrigin, maxRange, true);
00464 }
00465
00466 void srs_env_model::COctoMapPlugin::reset(bool clearLoaded)
00467 {
00468 if( m_bMapLoaded && (!clearLoaded) )
00469 return;
00470
00471
00472 boost::mutex::scoped_lock lock(m_lockData);
00473 m_data->getTree().clear();
00474 setDefaults();
00475 }
00476
00480 void srs_env_model::COctoMapPlugin::filterCloud( tPointCloudConstPtr & cloud)
00481 {
00482
00483
00484 if (m_bNewDataToFilter && m_bRemoveOutdated && (!m_bFilterWithInput))
00485 {
00486
00487 boost::mutex::scoped_lock lock(m_lockData);
00488
00489
00490
00491 m_filterRaycast.setCloud(cloud);
00492 m_filterRaycast.filter(m_data->getTree());
00493 m_filterRaycast.writeLastRunInfo();
00494
00495
00496 }
00497 }
00498
00500
00502
00504 void srs_env_model::COctoMapPlugin::crawl(const ros::Time & currentTime)
00505 {
00506
00507 fillMapParameters(currentTime);
00508
00509
00510 m_sigOnNewData( m_mapParameters );
00511
00512 }
00513
00515 bool srs_env_model::COctoMapPlugin::shouldPublish()
00516 {
00517 return (m_bPublishOctomap && m_ocPublisher.getNumSubscribers() > 0);
00518 }
00519
00523 void srs_env_model::COctoMapPlugin::publishInternal(const ros::Time & timestamp)
00524 {
00525 if( !shouldPublish() )
00526 return;
00527
00528
00529
00530 boost::mutex::scoped_lock lock(m_lockData);
00531
00532
00533 octomap_ros::OctomapBinary map;
00534 map.header.frame_id = m_mapParameters.frameId;
00535 map.header.stamp = timestamp;
00536
00537 octomap::octomapMapToMsgData(m_data->getTree(), map.data);
00538
00539 m_ocPublisher.publish(map);
00540
00541
00542 }
00543
00545 void srs_env_model::COctoMapPlugin::fillMapParameters(const ros::Time & time)
00546 {
00547 m_mapParameters.currentTime = time;
00548 m_mapParameters.mapSize = m_data->getTree().size();
00549 m_mapParameters.treeDepth = m_data->getTree().getTreeDepth();
00550 }
00551
00553
00558 bool srs_env_model::COctoMapPlugin::resetOctomapCB(std_srvs::Empty::Request& request, std_srvs::Empty::Response& response)
00559 {
00560 std::cerr << "Reset octomap service called..." << std::endl;
00561
00562
00563 reset(true);
00564
00565 std::cerr << "Reset done..." << std::endl;
00566
00567 invalidate();
00568
00569 return true;
00570 }
00571
00572
00573
00574
00578 long int srs_env_model::COctoMapPlugin::doObjectTesting(srs_env_model::CTestingObjectBase * object)
00579 {
00580 if (object == 0) {
00581 PERROR( "Wrong testing object - NULL. ");
00582 return 0;
00583 }
00584
00585
00586 long int counter(0);
00587
00588 float probMiss(m_data->getTree().getProbMissLog());
00589
00590
00591 for (srs_env_model::tButServerOcTree::leaf_iterator it =
00592 m_data->getTree().begin_leafs(), end = m_data->getTree().end_leafs(); it
00593 != end; ++it) {
00594
00595 if (m_data->getTree().isNodeOccupied(*it))
00596 {
00597
00598 if (object->isIn(it.getX(), it.getY(), it.getZ())) {
00599
00600
00601 (*it).setValue(probMiss);
00602
00603 ++counter;
00604 }
00605
00606 }
00607 }
00608
00609 return counter;
00610 }
00614 #define G2EPOINT( gp ) (Eigen::Vector3f( gp.x, gp.y, gp.z ))
00615
00616 #define G2EQUAT( gp ) (Eigen::Quaternionf( gp.w, gp.x, gp.y, gp.z ))
00617 bool srs_env_model::COctoMapPlugin::removeCubeCB(
00618 srs_env_model::RemoveCube::Request & req,
00619 srs_env_model::RemoveCube::Response & res) {
00620
00621 PERROR( "Remove cube from octomap: " << req.pose << " --- " << req.size );
00622
00623
00624
00625
00626 if (m_removeTester != 0)
00627 delete m_removeTester;
00628
00629
00630 if (req.frame_id != m_mapParameters.frameId) {
00631
00632 geometry_msgs::PoseStamped ps, psout;
00633 ps.header.frame_id = req.frame_id;
00634 ps.header.stamp = m_mapParameters.currentTime;
00635 ps.pose = req.pose;
00636
00637 m_tfListener.transformPose(m_mapParameters.frameId, ps, psout);
00638 req.pose = psout.pose;
00639
00640
00641 geometry_msgs::PointStamped vs, vsout;
00642 vs.header.frame_id = req.frame_id;
00643 vs.header.stamp = m_mapParameters.currentTime;
00644 vs.point = req.size;
00645
00646 m_tfListener.transformPoint(m_mapParameters.frameId, vs, vsout);
00647 req.size = vsout.point;
00648
00649 PERROR( "Transformed cube from octomap: " << req.pose << " --- " << req.size );
00650 }
00651
00652
00653 double d(m_mapParameters.resolution);
00654
00655
00656 m_removeTester = new srs_env_model::CTestingPolymesh(
00657 G2EPOINT( req.pose.position ), G2EQUAT( req.pose.orientation ),
00658 G2EPOINT( req.size ) + Eigen::Vector3f(d, d, d));
00659
00660
00661 m_testerLifeCounter = m_testerLife;
00662
00663 return true;
00664 }
00665
00666 bool srs_env_model::COctoMapPlugin::addCubeCB(
00667 srs_env_model::AddCube::Request & req,
00668 srs_env_model::AddCube::Response & res) {
00669
00670 PERROR( "Add cube to octomap: " << req.pose << " --- \n size: \n" << req.size );
00671
00672
00673
00674
00675
00676 if (req.frame_id != m_mapParameters.frameId) {
00677
00678 geometry_msgs::PoseStamped ps, psout;
00679 ps.header.frame_id = req.frame_id;
00680 ps.header.stamp = m_mapParameters.currentTime;
00681 ps.pose = req.pose;
00682
00683 m_tfListener.transformPose(m_mapParameters.frameId, ps, psout);
00684 req.pose = psout.pose;
00685
00686
00687 geometry_msgs::PointStamped vs, vsout;
00688 vs.header.frame_id = req.frame_id;
00689 vs.header.stamp = m_mapParameters.currentTime;
00690 vs.point = req.size;
00691
00692 m_tfListener.transformPoint(m_mapParameters.frameId, vs, vsout);
00693 req.size = vsout.point;
00694
00695
00696 }
00697
00698 PERROR( "Computing sizes..." );
00699
00700
00701 octomap::point3d pmin, pmax;
00702 pmin(0) = req.pose.position.x - req.size.x * 0.5;
00703 pmin(1) = req.pose.position.y - req.size.y * 0.5;
00704 pmin(2) = req.pose.position.z - req.size.z * 0.5;
00705
00706 pmax(0) = req.pose.position.x + req.size.x * 0.5;
00707 pmax(1) = req.pose.position.y + req.size.y * 0.5;
00708 pmax(2) = req.pose.position.z + req.size.z * 0.5;
00709
00710 PERROR( "Sizes computed. Computing steps ");
00711
00712 float diff[3];
00713 unsigned int steps[3];
00714 for (int i=0;i<3;++i)
00715 {
00716 diff[i] = pmax(i) - pmin(i);
00717 steps[i] = floor(diff[i] / m_mapParameters.resolution);
00718
00719 std::cerr << "bbx " << i << " size: " << diff[i] << " " << steps[i] << " steps\n";
00720 }
00721
00722 PERROR("Rendering... Resolution: " << m_mapParameters.resolution );
00723
00724 long counter(0);
00725 octomap::point3d p = pmin;
00726 octomap::OcTreeKey key;
00727
00728 for (unsigned int x = 0; x < steps[0]; ++x)
00729 {
00730 p.x() += m_mapParameters.resolution;
00731 p.y() = pmin.y();
00732
00733 for (unsigned int y = 0; y < steps[1]; ++y)
00734 {
00735 p.y() += m_mapParameters.resolution;
00736 p.z() = pmin.z();
00737
00738 for (unsigned int z = 0; z < steps[2]; ++z)
00739 {
00740
00741 p.z() += m_mapParameters.resolution;
00742 ++counter;
00743
00744
00745 if (!m_data->getTree().genKey(p, key)) continue;
00746
00747
00748 m_data->getTree().updateNode(key, true, true);
00749
00750 m_data->getTree().setNodeColor(key, m_r, m_g, m_b, 255);
00751 }
00752 }
00753 }
00754
00755 PERROR( "Added. Changed nodes: " << counter );
00756 return true;
00757 }
00758
00762 void srs_env_model::COctoMapPlugin::addCubeGizmo(
00763 const geometry_msgs::Pose & pose, const geometry_msgs::Point & size) {
00764 srs_interaction_primitives::AddUnknownObject gizmo;
00765 gizmo.request.pose = pose;
00766 gizmo.request.scale.x = size.x;
00767 gizmo.request.scale.y = size.y;
00768 gizmo.request.scale.z = size.z;
00769 gizmo.request.frame_id = m_mapParameters.frameId;
00770 gizmo.request.name = "OctomapGizmo";
00771
00772 ros::service::call("but_interaction_primitives/add_unknown_object", gizmo);
00773 }
00774
00778 void srs_env_model::COctoMapPlugin::pause( bool bPause, ros::NodeHandle & node_handle )
00779 {
00780 boost::mutex::scoped_lock lock(m_lockData);
00781
00782 if( bPause )
00783 {
00784 m_ocPublisher.shutdown();
00785
00786
00787 }
00788 else
00789 {
00790 m_ocPublisher = node_handle.advertise<octomap_ros::OctomapBinary> ( m_ocPublisherName, 5, m_latchedTopics);
00791
00792
00793
00794
00795
00796
00797 }
00798 }
00799
00803 bool srs_env_model::COctoMapPlugin::setCrawlingDepthCB( srs_env_model::SetCrawlingDepth::Request & req, srs_env_model::SetCrawlingDepth::Response & res )
00804 {
00805 boost::mutex::scoped_lock lock(m_lockData);
00806 m_crawlDepth = req.depth;
00807
00808
00809 unsigned char td( m_data->getTree().getTreeDepth() );
00810 if( m_crawlDepth > td)
00811 m_crawlDepth = td;
00812
00813 m_mapParameters.crawlDepth = m_crawlDepth;
00814
00815 return true;
00816 }
00817
00821 bool srs_env_model::COctoMapPlugin::getTreeDepthCB( srs_env_model::GetTreeDepth::Request & req, srs_env_model::GetTreeDepth::Response & res )
00822 {
00823 res.depth = m_data->getTree().getTreeDepth();
00824
00825 return true;
00826 }
00827
00831 bool srs_env_model::COctoMapPlugin::loadOctreeCB( srs_env_model::LoadSaveRequest & req, srs_env_model::LoadSaveResponse & res )
00832 {
00833
00834 reset(true);
00835
00836 boost::mutex::scoped_lock lock(m_lockData);
00837
00838 setDefaults();
00839
00840 assert( m_data != 0 );
00841
00842
00843 m_data->getTree().setProbHit(m_mapParameters.probHit);
00844 m_data->getTree().setProbMiss(m_mapParameters.probMiss);
00845 m_data->getTree().setClampingThresMin(m_mapParameters.thresMin);
00846 m_data->getTree().setClampingThresMax(m_mapParameters.thresMax);
00847 m_data->getTree().setOccupancyThres(m_mapParameters.thresOccupancy);
00848 m_mapParameters.treeDepth = m_data->getTree().getTreeDepth();
00849 m_mapParameters.map = m_data;
00850 m_mapParameters.crawlDepth = m_crawlDepth;
00851
00852
00853 if (req.filename.length() > 0) {
00854
00855 if (m_data->getTree().readBinary(req.filename)) {
00856 ROS_INFO("Octomap file %s loaded (%zu nodes).", req.filename.c_str(), m_data->getTree().size());
00857
00858
00859 m_mapParameters.treeDepth = m_data->getTree().getTreeDepth();
00860
00861
00862 m_mapParameters.resolution = m_data->getTree().getResolution();
00863
00864
00865 m_bMapLoaded = true;
00866
00867
00868 lock.unlock();
00869
00870
00871 invalidate();
00872
00873 res.all_ok = true;
00874
00875 m_bNotFirst = m_data->getTree().getNumLeafNodes() > 0;
00876
00877 } else {
00878
00879
00880 ROS_ERROR("Could not open requested file %s, continuing in standard mode.", req.filename.c_str());
00881 PERROR( "Transform error.");
00882
00883 res.all_ok = false;
00884 }
00885 }
00886
00887 return true;
00888 }
00889
00893 bool srs_env_model::COctoMapPlugin::saveOctreeCB( srs_env_model::LoadSaveRequest & req, srs_env_model::LoadSaveResponse & res )
00894 {
00895 if(req.filename.length() == 0 )
00896 {
00897 ROS_ERROR("Wrong filename: Zero length string.");
00898 res.all_ok = false;
00899 return false;
00900 }
00901
00902 bool rv(m_data->getTree().writeBinaryConst(req.filename));
00903
00904 if( !rv )
00905 {
00906 ROS_ERROR("Could not save file: %s", req.filename.c_str());
00907 res.all_ok = false;
00908 return false;
00909 }
00910
00911 res.all_ok = true;
00912 return true;
00913 }
00914
00918 bool srs_env_model::COctoMapPlugin::loadFullOctreeCB( srs_env_model::LoadSaveRequest & req, srs_env_model::LoadSaveResponse & res )
00919 {
00920
00921 reset(true);
00922
00923 boost::mutex::scoped_lock lock(m_lockData);
00924
00925 setDefaults();
00926
00927 assert( m_data != 0 );
00928
00929
00930 m_data->getTree().setProbHit(m_mapParameters.probHit);
00931 m_data->getTree().setProbMiss(m_mapParameters.probMiss);
00932 m_data->getTree().setClampingThresMin(m_mapParameters.thresMin);
00933 m_data->getTree().setClampingThresMax(m_mapParameters.thresMax);
00934 m_data->getTree().setOccupancyThres(m_mapParameters.thresOccupancy);
00935 m_mapParameters.treeDepth = m_data->getTree().getTreeDepth();
00936 m_mapParameters.map = m_data;
00937 m_mapParameters.crawlDepth = m_crawlDepth;
00938
00939
00940 if (req.filename.length() > 0) {
00941
00942 srs_env_model::tButServerOcTree * tree = dynamic_cast<tButServerOcTree *>( tButServerOcTree::read( req.filename ) );
00943 if (tree != 0 )
00944 {
00945
00946 m_data->setTree( tree );
00947 tree->prune();
00948
00949 ROS_INFO("Octomap file %s loaded (%zu nodes).", req.filename.c_str(), m_data->getTree().size());
00950
00951
00952 m_mapParameters.treeDepth = tree->getTreeDepth();
00953
00954
00955 m_mapParameters.resolution = tree->getResolution();
00956
00957
00958 m_mapParameters.probHit = tree->getProbHit();
00959
00960
00961 m_mapParameters.probMiss = tree->getProbMiss();
00962
00963
00964 m_mapParameters.thresMin = tree->getClampingThresMin();
00965
00966
00967 m_mapParameters.thresMax = tree->getClampingThresMax();
00968
00969
00970 m_mapParameters.thresOccupancy = tree->getOccupancyThres();
00971
00972
00973
00974 m_bMapLoaded = true;
00975
00976
00977 lock.unlock();
00978
00979
00980 invalidate();
00981
00982 res.all_ok = true;
00983
00984 m_bNotFirst = m_data->getTree().getNumLeafNodes() > 0;
00985
00986 } else {
00987
00988
00989 ROS_ERROR("Could not open requested file %s, continuing in standard mode.", req.filename.c_str());
00990 PERROR( "Transform error.");
00991
00992 res.all_ok = false;
00993 }
00994 }
00995
00996 return true;
00997 }
00998
01002 bool srs_env_model::COctoMapPlugin::saveFullOctreeCB( srs_env_model::LoadSaveRequest & req, srs_env_model::LoadSaveResponse & res )
01003 {
01004 if(req.filename.length() == 0 )
01005 {
01006 ROS_ERROR("Wrong filename: Zero length string.");
01007 res.all_ok = false;
01008 return false;
01009 }
01010
01011 bool rv(m_data->getTree().write(req.filename));
01012
01013 if( !rv )
01014 {
01015 ROS_ERROR("Could not save file: %s", req.filename.c_str());
01016 res.all_ok = false;
01017 return false;
01018 }
01019
01020 res.all_ok = true;
01021 return true;
01022 }