43 #include <opencv2/opencv_modules.hpp> 54 #include <pcl/common/common.h> 55 #include <pcl/filters/extract_indices.h> 56 #include <pcl/io/ply_io.h> 57 #include <pcl/io/obj_io.h> 58 #include <pcl/surface/poisson.h> 59 #include <pcl/surface/vtk_smoothing/vtk_mesh_quadric_decimation.h> 70 constexpr
int kTangoCoreMinimumVersion = 9377;
84 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapPublishLikelihood(), std::string(
"false")));
92 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kMemCompressionParallelized(), std::string(
"false")));
95 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kRGBDOptimizeFromGraphEnd(), std::string(
"true")));
99 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kRGBDProximityPathMaxNeighbors(), std::string(
"0")));
100 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kRGBDProximityBySpace(), std::string(
"false")));
104 if(parameters.find(rtabmap::Parameters::kOptimizerStrategy()) != parameters.end())
106 if(parameters.at(rtabmap::Parameters::kOptimizerStrategy()).compare(
"2") == 0)
111 else if(parameters.at(rtabmap::Parameters::kOptimizerStrategy()).compare(
"1") == 0)
129 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kIcpCorrespondenceRatio(), std::string(
"0.5")));
130 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kIcpMaxCorrespondenceDistance(), std::string(
"0.05")));
243 env->GetJavaVM(&
jvm);
246 LOGI(
"RTABMapApp::onCreate()");
289 LOGI(
"Set orientation: display=%d camera=%d -> %d", displayRotation, cameraRotation, (
int)rotation);
294 int RTABMapApp::openDatabase(
const std::string & databasePath,
bool databaseInMemory,
bool optimize,
const std::string & databaseSource)
296 LOGI(
"Opening database %s (inMemory=%d, optimize=%d)", databasePath.c_str(), databaseInMemory?1:0, optimize?1:0);
322 optMesh_.reset(
new pcl::TextureMesh);
331 std::vector<std::vector<std::vector<unsigned int> > > polygons;
332 #if PCL_VERSION_COMPARE(>=, 1, 8, 0) 333 std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > texCoords;
335 std::vector<std::vector<Eigen::Vector2f> > texCoords;
338 if(!databaseSource.empty())
345 if(!cloudMat.empty())
347 LOGI(
"Open: Found optimized mesh! Visualizing it.");
355 else if(
optMesh_->tex_polygons.size())
357 LOGI(
"Open: Polygon mesh");
360 else if(!
optMesh_->cloud.data.empty())
362 LOGI(
"Open: Point cloud");
368 LOGI(
"Open: No optimized mesh found.");
394 LOGI(
"Erasing database \"%s\"...", databasePath.c_str());
396 if(!databaseSource.empty())
398 LOGI(
"Copying database source \"%s\" to \"%s\"...", databaseSource.c_str(), databasePath.c_str());
408 LOGI(
"Initializing database...");
411 if(parameters.find(rtabmap::Parameters::kRtabmapDetectionRate()) != parameters.end())
417 std::map<int, rtabmap::Signature> signatures;
418 std::map<int, rtabmap::Transform> poses;
419 std::multimap<int, rtabmap::Link> links;
420 LOGI(
"Loading full map from database...");
429 if(signatures.size() && poses.empty())
431 LOGE(
"Failed to optimize the graph!");
436 LOGI(
"Creating the meshes (%d)....", (
int)poses.size());
441 for(std::map<int, rtabmap::Transform>::iterator iter=poses.begin(); iter!=poses.end() && status>=0; ++iter)
445 int id = iter->first;
446 if(!iter->second.isNull())
458 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
459 pcl::IndicesPtr indices(
new std::vector<int>);
461 if(cloud->size() && indices->size())
463 std::vector<pcl::Vertices> polygons;
464 std::vector<pcl::Vertices> polygonsLowRes;
473 std::pair<std::map<int, Mesh>::iterator,
bool> inserted =
createdMeshes_.insert(std::make_pair(
id,
Mesh()));
475 inserted.first->second.cloud = cloud;
476 inserted.first->second.indices = indices;
477 inserted.first->second.polygons = polygons;
478 inserted.first->second.polygonsLowRes = polygonsLowRes;
479 inserted.first->second.visible =
true;
480 inserted.first->second.cameraModel = data.
cameraModels()[0];
481 inserted.first->second.gains[0] = 1.0;
482 inserted.first->second.gains[1] = 1.0;
483 inserted.first->second.gains[2] = 1.0;
489 cv::resize(data.
imageRaw(), inserted.first->second.texture, reducedSize, 0, 0, CV_INTER_LINEAR);
493 inserted.first->second.texture = data.
imageRaw();
496 LOGI(
"Created cloud %d (%fs)",
id, timer.
ticks());
500 LOGI(
"Cloud %d not added to created meshes",
id);
505 UWARN(
"Cloud %d is empty",
id);
510 UERROR(
"Failed to uncompress data!");
516 UWARN(
"Data for node %d not found",
id);
521 UWARN(
"Pose %d is null !?",
id);
532 UERROR(
"Exception! msg=\"%s\"", e.what());
535 catch (
const cv::Exception & e)
537 UERROR(
"Exception! msg=\"%s\"", e.what());
540 catch (
const std::exception & e)
542 UERROR(
"Exception! msg=\"%s\"", e.what());
558 if(optimize && status>=0)
563 LOGI(
"Polygon filtering...");
568 if(iter->second.polygons.size())
577 LOGI(
"Open: add rtabmap event to update the scene");
602 LOGI(
"Start rtabmap thread");
613 if(poses.empty() || status>0)
625 LOGW(
"onTangoServiceConnected()");
630 if (TangoService_setBinder(env, iBinder) != TANGO_SUCCESS) {
631 UERROR(
"TangoHandler::ConnectTango, TangoService_setBinder error");
650 if(height >= 480 && width % 20 == 0 && height % 20 == 0)
654 else if(width % 10 == 0 && height % 10 == 0)
658 else if(width % 15 == 0 && height % 15 == 0)
664 UERROR(
"Could not set decimation to high (size=%dx%d)", width, height);
669 if(height >= 480 && width % 10 == 0 && height % 10 == 0)
673 else if(width % 5 == 0 && height % 5 == 0)
679 UERROR(
"Could not set decimation to medium (size=%dx%d)", width, height);
684 if(height >= 480 && width % 5 == 0 && height % 5 == 0)
688 else if(width % 3 == 0 && width % 3 == 0)
692 else if(width % 2 == 0 && width % 2 == 0)
698 UERROR(
"Could not set decimation to low (size=%dx%d)", width, height);
704 LOGI(
"Start camera thread");
712 UERROR(
"Failed camera initialization!");
729 TangoService_resetMotionTracking();
733 const std::vector<pcl::Vertices> & polygons,
736 std::vector<int> vertexToCluster(cloudSize, 0);
737 std::map<int, std::list<int> > clusters;
738 int lastClusterID = 0;
740 for(
unsigned int i=0; i<polygons.size(); ++i)
743 for(
unsigned int j=0;j<polygons[i].vertices.size(); ++j)
745 if(vertexToCluster[polygons[i].
vertices[j]]>0)
747 clusterID = vertexToCluster[polygons[i].vertices[j]];
753 clusters.at(clusterID).push_back(i);
757 clusterID = ++lastClusterID;
758 std::list<int> polygons;
759 polygons.push_back(i);
760 clusters.insert(std::make_pair(clusterID, polygons));
762 for(
unsigned int j=0;j<polygons[i].vertices.size(); ++j)
764 vertexToCluster[polygons[i].vertices[j]] = clusterID;
768 unsigned int biggestClusterSize = 0;
769 for(std::map<
int, std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
771 LOGD(
"cluster %d = %d", iter->first, (
int)iter->second.size());
773 if(iter->second.size() > biggestClusterSize)
775 biggestClusterSize = iter->second.size();
778 unsigned int minClusterSize = (
unsigned int)(
float(biggestClusterSize)*
clusterRatio_);
779 LOGI(
"Biggest cluster %d -> minClusterSize(ratio=%f)=%d",
782 std::vector<pcl::Vertices> filteredPolygons(polygons.size());
784 for(std::map<
int, std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
786 if(iter->second.size() >= minClusterSize)
788 for(std::list<int>::iterator jter=iter->second.begin(); jter!=iter->second.end(); ++jter)
790 filteredPolygons[oi++] = polygons[*jter];
794 filteredPolygons.resize(oi);
795 return filteredPolygons;
800 const std::vector<pcl::Vertices> & polygons,
804 std::vector<std::set<int> > neighbors;
805 std::vector<std::set<int> > vertexToPolygons;
813 unsigned int biggestClusterSize = 0;
814 for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
816 if(iter->size() > biggestClusterSize)
818 biggestClusterSize = iter->size();
821 unsigned int minClusterSize = (
unsigned int)(
float(biggestClusterSize)*
clusterRatio_);
822 LOGI(
"Biggest cluster = %d -> minClusterSize(ratio=%f)=%d",
825 std::vector<pcl::Vertices> filteredPolygons(polygons.size());
827 for(std::list<std::list<int> >::iterator jter=clusters.begin(); jter!=clusters.end(); ++jter)
829 if(jter->size() >= minClusterSize)
831 for(std::list<int>::iterator kter=jter->begin(); kter!=jter->end(); ++kter)
833 filteredPolygons[oi++] = polygons.at(*kter);
837 filteredPolygons.resize(oi);
838 return filteredPolygons;
869 delete rtabmapEvent_;
884 cv::Mat depth = cv::Mat::zeros(mesh.
cloud->height, mesh.
cloud->width, CV_32FC1);
886 for(
unsigned int i=0; i<mesh.
indices->size(); ++i)
888 int index = mesh.
indices->at(i);
890 if(mesh.
cloud->at(index).x > 0)
893 depth.at<
float>(index) = pt.z;
898 LOGI(
"smoothMesh() Bilateral filtering of %d, time=%fs",
id, t.
ticks());
900 if(!depth.empty() && mesh.
indices->size())
902 pcl::IndicesPtr newIndices(
new std::vector<int>(mesh.
indices->size()));
904 for(
unsigned int i=0; i<mesh.
indices->size(); ++i)
906 int index = mesh.
indices->at(i);
908 pcl::PointXYZRGB & pt = mesh.
cloud->at(index);
910 if(depth.at<
float>(index) > 0)
912 newPt.z = depth.at<
float>(index);
914 newIndices->at(oi++) = index;
918 newPt.x = newPt.y = newPt.z = std::numeric_limits<float>::quiet_NaN();
924 newIndices->resize(oi);
928 std::vector<pcl::Vertices> polygons;
933 LOGI(
"smoothMesh() Reconstructing the mesh of %d, time=%fs",
id, t.
ticks());
938 UERROR(
"smoothMesh() Failed to smooth surface %d",
id);
947 LOGI(
"Gain compensation...");
950 std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr > clouds;
951 std::map<int, pcl::IndicesPtr> indices;
954 clouds.insert(std::make_pair(iter->first, iter->second.cloud));
955 indices.insert(std::make_pair(iter->first, iter->second.indices));
957 std::map<int, rtabmap::Transform> poses;
958 std::multimap<int, rtabmap::Link> links;
964 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr>::const_iterator iter=clouds.begin(); iter!=clouds.end(); ++iter)
966 int from = iter->first;
967 std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr>::const_iterator jter = iter;
969 for(;jter!=clouds.end(); ++jter)
971 int to = jter->first;
979 if(clouds.size() > 1 && links.size())
981 compensator.
feed(clouds, indices, links);
982 LOGI(
"Gain compensation... compute gain: links=%d, time=%fs", (
int)links.size(), tGainCompensation.
ticks());
987 if(!iter->second.cloud->empty())
989 if(clouds.size() > 1 && links.size())
991 compensator.
getGain(iter->first, &iter->second.gains[0], &iter->second.gains[1], &iter->second.gains[2]);
992 LOGI(
"%d mesh has gain %f,%f,%f", iter->first, iter->second.gains[0], iter->second.gains[1], iter->second.gains[2]);
996 LOGI(
"Gain compensation... applying gain: meshes=%d, time=%fs", (
int)
createdMeshes_.size(), tGainCompensation.
ticks());
1002 std::list<rtabmap::RtabmapEvent*> rtabmapEvents;
1008 #ifdef DEBUG_RENDERING_PERFORMANCE 1013 bool notifyDataLoaded =
false;
1014 bool notifyCameraStarted =
false;
1044 notifyCameraStarted =
true;
1055 LOGI(
"Process odom events");
1060 notifyCameraStarted =
true;
1075 LOGI(
"Adding optimized mesh to opengl (%d points, %d polygons, %d tex_coords, materials=%d texture=%dx%d)...",
1078 optMesh_->tex_coordinates.size()!=1?0:(int)
optMesh_->tex_coordinates[0].size(),
1079 (int)
optMesh_->tex_materials.size(),
1085 mesh.
cloud.reset(
new pcl::PointCloud<pcl::PointXYZRGB>);
1086 mesh.
normals.reset(
new pcl::PointCloud<pcl::Normal>);
1091 if(
optMesh_->tex_coordinates.size())
1100 pcl::IndicesPtr indices(
new std::vector<int>);
1101 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
1102 pcl::fromPCLPointCloud2(
optMesh_->cloud, *cloud);
1118 std::list<rtabmap::RtabmapEvent*> visLocalizationEvents;
1124 if(visLocalizationEvents.size())
1132 std::map<int, rtabmap::Transform>::const_iterator iter = stats.
poses().find(
optRefId_);
1138 int fastMovement = (int)
uValue(stats.
data(), rtabmap::Statistics::kMemoryFast_movement(), 0.0f);
1139 int loopClosure = (int)
uValue(stats.
data(), rtabmap::Statistics::kLoopAccepted_hypothesis_id(), 0.0f);
1140 int rejected = (int)
uValue(stats.
data(), rtabmap::Statistics::kLoopRejectedHypothesis(), 0.0f);
1145 else if(!
paused_ && rejected>0)
1149 else if(!
paused_ && fastMovement)
1175 if(visLocalizationEvents.size())
1179 visLocalizationEvents.pop_back();
1181 for(std::list<rtabmap::RtabmapEvent*>::iterator iter=visLocalizationEvents.begin(); iter!=visLocalizationEvents.end(); ++iter)
1185 visLocalizationEvents.clear();
1194 optMesh_.reset(
new pcl::TextureMesh);
1211 if(rtabmapEvents.front()->getStats().refImageId()>0 && rtabmapEvents.front()->getStats().refImageId() <
createdMeshes_.rbegin()->first)
1213 LOGI(
"Detected new database! new=%d old=%d", rtabmapEvents.front()->getStats().refImageId(),
createdMeshes_.rbegin()->first);
1218 #ifdef DEBUG_RENDERING_PERFORMANCE 1219 if(rtabmapEvents.size())
1221 LOGW(
"begin and getting rtabmap events %fs", time.
ticks());
1228 LOGI(
"Clearing all rendering data...");
1242 LOGI(
"Clearing meshes...");
1247 notifyDataLoaded =
true;
1266 if(added.size() != meshes)
1268 LOGI(
"added (%d) != meshes (%d)", (
int)added.size(), meshes);
1275 LOGI(
"Re-add mesh %d to OpenGL context", iter->first);
1286 if(!textureRaw.empty())
1291 LOGD(
"resize image from %dx%d to %dx%d", textureRaw.cols, textureRaw.rows, reducedSize.width, reducedSize.height);
1292 cv::resize(textureRaw, iter->second.texture, reducedSize, 0, 0, CV_INTER_LINEAR);
1296 iter->second.texture = textureRaw;
1303 iter->second.texture = cv::Mat();
1308 else if(notifyDataLoaded)
1317 if(rtabmapEvents.size())
1319 #ifdef DEBUG_RENDERING_PERFORMANCE 1320 LOGW(
"Process rtabmap events %fs", time.
ticks());
1322 LOGI(
"Process rtabmap events");
1326 std::map<int, rtabmap::SensorData> bufferedSensorData;
1329 for(std::list<rtabmap::RtabmapEvent*>::iterator iter=rtabmapEvents.begin(); iter!=rtabmapEvents.end(); ++iter)
1334 int smallMovement = (int)
uValue(stats.
data(), rtabmap::Statistics::kMemorySmall_movement(), 0.0f);
1335 int fastMovement = (int)
uValue(stats.
data(), rtabmap::Statistics::kMemoryFast_movement(), 0.0f);
1336 int rehearsalMerged = (int)
uValue(stats.
data(), rtabmap::Statistics::kMemoryRehearsal_merged(), 0.0f);
1338 smallMovement == 0 && rehearsalMerged == 0 && fastMovement == 0)
1353 int loopClosure = (int)
uValue(stats.
data(), rtabmap::Statistics::kLoopAccepted_hypothesis_id(), 0.0f);
1354 int rejected = (int)
uValue(stats.
data(), rtabmap::Statistics::kLoopRejectedHypothesis(), 0.0f);
1359 else if(!
paused_ && rejected>0)
1363 else if(!
paused_ && rehearsalMerged>0)
1367 else if(!
paused_ && fastMovement)
1378 #ifdef DEBUG_RENDERING_PERFORMANCE 1379 LOGW(
"Looking fo data to load (%d) %fs", bufferedSensorData.size(), time.
ticks());
1382 std::map<int, rtabmap::Transform> poses = rtabmapEvents.back()->getStats().poses();
1383 if(!rtabmapEvents.back()->getStats().mapCorrection().isNull())
1385 mapToOdom_ = rtabmapEvents.back()->getStats().mapCorrection();
1389 for(std::map<int, rtabmap::Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
1393 std::map<int, rtabmap::Transform>::iterator jter =
rawPoses_.find(iter->first);
1405 const std::multimap<int, rtabmap::Link> & links = rtabmapEvents.back()->getStats().constraints();
1411 #ifdef DEBUG_RENDERING_PERFORMANCE 1412 LOGW(
"Update graph: %fs", time.
ticks());
1417 std::set<std::string> strIds;
1418 for(std::map<int, rtabmap::Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
1420 int id = iter->first;
1421 if(!iter->second.isNull())
1428 std::map<int, Mesh>::iterator meshIter =
createdMeshes_.find(
id);
1431 meshIter->second.visible =
true;
1436 bufferedSensorData.find(
id) != bufferedSensorData.end())
1440 cv::Mat tmpA, depth;
1442 #ifdef DEBUG_RENDERING_PERFORMANCE 1443 LOGW(
"Decompressing data: %fs", time.
ticks());
1449 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
1450 pcl::IndicesPtr indices(
new std::vector<int>);
1452 #ifdef DEBUG_RENDERING_PERFORMANCE 1455 if(cloud->size() && indices->size())
1457 std::vector<pcl::Vertices> polygons;
1458 std::vector<pcl::Vertices> polygonsLowRes;
1462 #ifdef DEBUG_RENDERING_PERFORMANCE 1463 LOGW(
"Creating mesh, %d polygons (%fs)", (
int)polygons.size(), time.
ticks());
1466 #ifdef DEBUG_RENDERING_PERFORMANCE 1467 LOGW(
"Creating mesh, %d polygons (%fs)", (
int)polygons.size(), time.
ticks());
1473 std::pair<std::map<int, Mesh>::iterator,
bool> inserted =
createdMeshes_.insert(std::make_pair(
id,
Mesh()));
1475 inserted.first->second.cloud = cloud;
1476 inserted.first->second.indices = indices;
1477 inserted.first->second.polygons = polygons;
1478 inserted.first->second.polygonsLowRes = polygonsLowRes;
1479 inserted.first->second.visible =
true;
1480 inserted.first->second.cameraModel = data.
cameraModels()[0];
1481 inserted.first->second.gains[0] = 1.0;
1482 inserted.first->second.gains[1] = 1.0;
1483 inserted.first->second.gains[2] = 1.0;
1489 cv::resize(data.
imageRaw(), inserted.first->second.texture, reducedSize, 0, 0, CV_INTER_LINEAR);
1490 #ifdef DEBUG_RENDERING_PERFORMANCE 1491 LOGW(
"resize image from %dx%d to %dx%d (%fs)", data.
imageRaw().cols, data.
imageRaw().rows, reducedSize.width, reducedSize.height, time.
ticks());
1496 inserted.first->second.texture = data.
imageRaw();
1510 #ifdef DEBUG_RENDERING_PERFORMANCE 1511 LOGW(
"Adding mesh to scene: %fs", time.
ticks());
1521 if(poses.size() > 2)
1525 for(std::multimap<int, rtabmap::Link>::const_iterator iter=links.begin(); iter!=links.end(); ++iter)
1529 int oldId = iter->second.to()>iter->second.from()?iter->second.from():iter->second.to();
1541 for(std::set<int>::const_iterator iter=addedClouds.begin();
1542 iter!=addedClouds.end();
1545 if(*iter > 0 && poses.find(*iter) == poses.end())
1548 std::map<int, Mesh>::iterator meshIter =
createdMeshes_.find(*iter);
1550 meshIter->second.visible =
false;
1566 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
1567 pcl::IndicesPtr indices(
new std::vector<int>);
1569 if(cloud->size() && indices->size())
1571 LOGI(
"Created odom cloud (rgb=%dx%d depth=%dx%d cloud=%dx%d)",
1574 (int)cloud->width, (
int)cloud->height);
1580 UERROR(
"Generated cloud is empty!");
1585 UERROR(
"Odom data images are empty!");
1596 main_scene_.
updateGains(iter->first, iter->second.gains[0], iter->second.gains[1], iter->second.gains[2]);
1599 notifyDataLoaded =
true;
1604 LOGI(
"Bilateral filtering...");
1609 if(iter->second.cloud->size() && iter->second.indices->size())
1617 notifyDataLoaded =
true;
1622 LOGI(
"Polygon filtering...");
1628 if(iter->second.polygons.size())
1635 notifyDataLoaded =
true;
1645 if(rtabmapEvents.size())
1650 rtabmapEvents.pop_back();
1652 for(std::list<rtabmap::RtabmapEvent*>::iterator iter=rtabmapEvents.begin(); iter!=rtabmapEvents.end(); ++iter)
1656 rtabmapEvents.clear();
1662 UERROR(
"TangoPoseEventNotReceived");
1673 cv::Mat image(h, w, CV_8UC4);
1674 glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, image.data);
1675 cv::flip(image, image, 0);
1676 cv::cvtColor(image, image, CV_RGBA2BGRA);
1680 int offset = (w-h)/2;
1685 int offset = (h-w)/2;
1689 LOGI(
"Saving screenshot %dx%d...", roi.cols, roi.rows);
1698 double renderTime = fpsTime.
elapsed();
1699 if(0.2 - renderTime > 0.0)
1701 uSleep((0.2 - renderTime)*1000);
1708 double updateInterval = 1.0;
1718 if(interval >= updateInterval)
1729 return notifyDataLoaded||notifyCameraStarted?1:0;
1733 for(std::list<rtabmap::RtabmapEvent*>::iterator iter=rtabmapEvents.begin(); iter!=rtabmapEvents.end(); ++iter)
1737 rtabmapEvents.clear();
1738 UERROR(
"Exception! msg=\"%s\"", e.what());
1741 catch(
const cv::Exception & e)
1743 for(std::list<rtabmap::RtabmapEvent*>::iterator iter=rtabmapEvents.begin(); iter!=rtabmapEvents.end(); ++iter)
1747 rtabmapEvents.clear();
1748 UERROR(
"Exception! msg=\"%s\"", e.what());
1751 catch(
const std::exception & e)
1753 for(std::list<rtabmap::RtabmapEvent*>::iterator iter=rtabmapEvents.begin(); iter!=rtabmapEvents.end(); ++iter)
1757 rtabmapEvents.clear();
1758 UERROR(
"Exception! msg=\"%s\"", e.what());
1770 float x0,
float y0,
float x1,
float y1) {
1863 std::map<int, rtabmap::Transform> poses;
1864 std::multimap<int, rtabmap::Link> links;
1873 LOGI(
"Send rtabmap event to update graph...");
2011 std::string compatibleKey = key;
2017 if(iter->second.first)
2020 compatibleKey = iter->second.second;
2021 LOGW(
"Parameter name changed: \"%s\" -> \"%s\". Please update the code accordingly. Value \"%s\" is still set to the new parameter name.",
2022 iter->first.c_str(), iter->second.second.c_str(), value.c_str());
2026 if(iter->second.second.empty())
2028 UERROR(
"Parameter \"%s\" doesn't exist anymore!",
2029 iter->first.c_str());
2033 UERROR(
"Parameter \"%s\" doesn't exist anymore! You may look at this similar parameter: \"%s\"",
2034 iter->first.c_str(), iter->second.second.c_str());
2041 LOGI(
uFormat(
"Setting param \"%s\" to \"%s\"", compatibleKey.c_str(), value.c_str()).c_str());
2042 if(compatibleKey.compare(rtabmap::Parameters::kKpDetectorStrategy()) == 0 &&
2043 mappingParameters_.at(rtabmap::Parameters::kKpDetectorStrategy()).compare(value) != 0)
2054 UERROR(
uFormat(
"Key \"%s\" doesn't exist!", compatibleKey.c_str()).c_str());
2086 LOGI(
"Saving database to %s", databasePath.c_str());
2089 LOGI(
"Taking screenshot...");
2093 UERROR(
"Failed to take a screenshot after 2 sec!");
2115 if(appendModeBackup || dataRecorderModeBackup || localizationModeBackup)
2138 UWARN(
"Processing canceled!");
2143 float cloudVoxelSize,
2144 bool regenerateCloud,
2150 float optimizedVoxelSize,
2152 int optimizedMaxPolygons,
2153 float optimizedColorRadius,
2154 bool optimizedCleanWhitePolygons,
2155 int optimizedMinClusterSize,
2156 float optimizedMaxTextureDistance,
2157 int optimizedMinTextureClusterSize,
2158 bool blockRendering)
2167 std::multimap<int, rtabmap::Link> links;
2175 UERROR(
"Empty optimized poses!");
2189 bool success =
false;
2194 totalSteps+=poses.size();
2199 totalSteps += poses.size();
2205 if(optimizedMaxPolygons > 0)
2215 totalSteps+=poses.size()+1;
2220 totalSteps += poses.size()+1;
2230 pcl::PolygonMesh::Ptr polygonMesh(
new pcl::PolygonMesh);
2231 pcl::TextureMesh::Ptr textureMesh(
new pcl::TextureMesh);
2232 std::vector<std::map<int, pcl::PointXY> > vertexToPixels;
2233 cv::Mat globalTextures;
2234 int totalPolygons = 0;
2238 std::map<int, rtabmap::Transform> cameraPoses;
2239 std::map<int, rtabmap::CameraModel> cameraModels;
2240 std::map<int, cv::Mat> cameraDepths;
2243 LOGI(
"Assemble clouds (%d)...", (
int)poses.size());
2247 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2248 for(std::map<int, rtabmap::Transform>::iterator iter=poses.begin();
2252 std::map<int, Mesh>::iterator jter =
createdMeshes_.find(iter->first);
2253 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
2254 pcl::IndicesPtr indices(
new std::vector<int>);
2258 gains[0] = gains[1] = gains[2] = 1.0f;
2261 cloud = jter->second.cloud;
2262 indices = jter->second.indices;
2263 model = jter->second.cameraModel;
2264 gains[0] = jter->second.gains[0];
2265 gains[1] = jter->second.gains[1];
2266 gains[2] = jter->second.gains[2];
2283 pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformedCloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
2284 if(optimizedVoxelSize > 0.0
f)
2293 pcl::copyPointCloud(*cloud, *indices, *transformedCloud);
2297 Eigen::Vector3f viewpoint( iter->second.x(), iter->second.y(), iter->second.z());
2300 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudWithNormals(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2301 pcl::concatenateFields(*transformedCloud, *normals, *cloudWithNormals);
2303 if(textureSize == 0 && (gains[0] != 1.0 || gains[1] != 1.0 || gains[2] != 1.0))
2305 for(
unsigned int i=0; i<cloudWithNormals->size(); ++i)
2307 pcl::PointXYZRGBNormal & pt = cloudWithNormals->at(i);
2315 if(mergedClouds->size() == 0)
2317 *mergedClouds = *cloudWithNormals;
2321 *mergedClouds += *cloudWithNormals;
2324 cameraPoses.insert(std::make_pair(iter->first, iter->second));
2325 cameraModels.insert(std::make_pair(iter->first, model));
2328 cameraDepths.insert(std::make_pair(iter->first, depth));
2331 LOGI(
"Assembled %d points (%d/%d total=%d)", (
int)cloudWithNormals->size(), ++cloudCount, (int)poses.size(), (int)mergedClouds->size());
2335 UERROR(
"Cloud %d not found or empty", iter->first);
2349 LOGI(
"Assembled clouds (%d)... done! %fs (total points=%d)", (
int)cameraPoses.size(), timer.
ticks(), (int)mergedClouds->size());
2351 if(mergedClouds->size()>=3)
2353 if(optimizedDepth == 0)
2357 float mapLength =
uMax3(max[0]-min[0], max[1]-min[1], max[2]-min[2]);
2358 optimizedDepth = 12;
2359 for(
int i=6; i<12; ++i)
2361 if(mapLength/
float(1<<i) < 0.03
f)
2367 LOGI(
"optimizedDepth=%d (map length=%f)", optimizedDepth, mapLength);
2371 LOGI(
"Mesh reconstruction...");
2372 pcl::PolygonMesh::Ptr mesh(
new pcl::PolygonMesh);
2373 pcl::Poisson<pcl::PointXYZRGBNormal> poisson;
2374 poisson.setDepth(optimizedDepth);
2375 poisson.setInputCloud(mergedClouds);
2376 poisson.reconstruct(*mesh);
2377 LOGI(
"Mesh reconstruction... done! %fs (%d polygons)", timer.
ticks(), (int)mesh->polygons.size());
2391 if(mesh->polygons.size())
2393 totalPolygons=(int)mesh->polygons.size();
2395 if(optimizedMaxPolygons > 0 && optimizedMaxPolygons < (
int)mesh->polygons.size())
2398 unsigned int count = mesh->polygons.size();
2399 float factor = 1.0f-float(optimizedMaxPolygons)/float(count);
2400 LOGI(
"Mesh decimation (max polygons %d/%d -> factor=%f)...", optimizedMaxPolygons, (
int)count, factor);
2404 pcl::PolygonMesh::Ptr output(
new pcl::PolygonMesh);
2405 pcl::MeshQuadricDecimationVTK mqd;
2406 mqd.setTargetReductionFactor(factor);
2407 mqd.setInputMesh(mesh);
2408 mqd.process (*output);
2416 LOGI(
"Mesh decimated (factor=%f) from %d to %d polygons (%fs)", factor, count, (
int)mesh->polygons.size(), timer.
ticks());
2417 if(count < mesh->polygons.size())
2419 UWARN(
"Decimated mesh has more polygons than before!");
2422 UWARN(
"RTAB-Map is not built with PCL-VTK module so mesh decimation cannot be used!");
2438 rtabmap::util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>(
2443 optimizedColorRadius,
2445 optimizedCleanWhitePolygons,
2446 optimizedMinClusterSize);
2450 LOGI(
"Texturing... cameraPoses=%d, cameraDepths=%d", (
int)cameraPoses.size(), (int)cameraDepths.size());
2456 optimizedMaxTextureDistance,
2459 optimizedMinTextureClusterSize,
2460 std::vector<float>(),
2463 LOGI(
"Texturing... done! %fs", timer.
ticks());
2476 if(textureMesh->tex_coordinates.size() && optimizedCleanWhitePolygons)
2478 LOGI(
"Cleanup mesh...");
2480 LOGI(
"Cleanup mesh... done! %fs", timer.
ticks());
2484 for(
unsigned int t=0; t<textureMesh->tex_polygons.size(); ++t)
2486 totalPolygons+=textureMesh->tex_polygons[t].size();
2491 totalPolygons = (int)mesh->polygons.size();
2498 UERROR(
"Merged cloud too small (%d points) to create polygons!", (
int)mergedClouds->size());
2503 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2507 textureMesh->tex_materials.resize(poses.size());
2508 textureMesh->tex_polygons.resize(poses.size());
2509 textureMesh->tex_coordinates.resize(poses.size());
2512 int polygonsStep = 0;
2514 for(std::map<int, rtabmap::Transform>::iterator iter=poses.begin();
2518 LOGI(
"Assembling cloud %d (total=%d)...", iter->first, (
int)poses.size());
2520 std::map<int, Mesh>::iterator jter =
createdMeshes_.find(iter->first);
2521 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
2522 std::vector<pcl::Vertices> polygons;
2523 float gains[3] = {1.0f};
2526 cloud = jter->second.cloud;
2527 polygons= jter->second.polygons;
2528 if(cloud->size() && polygons.size() == 0)
2532 gains[0] = jter->second.gains[0];
2533 gains[1] = jter->second.gains[1];
2534 gains[2] = jter->second.gains[2];
2546 if(cloud->size() && polygons.size())
2549 pcl::PointCloud<pcl::PointXYZRGB>::Ptr outputCloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
2550 std::vector<pcl::Vertices> outputPolygons;
2555 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudWithNormals(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2556 pcl::concatenateFields(*outputCloud, *normals, *cloudWithNormals);
2558 UASSERT(outputPolygons.size());
2560 totalPolygons+=outputPolygons.size();
2562 if(textureSize == 0)
2567 if(gains[0] != 1.0
f || gains[1] != 1.0
f || gains[2] != 1.0
f)
2569 for(
unsigned int i=0; i<cloudWithNormals->size(); ++i)
2571 pcl::PointXYZRGBNormal & pt = cloudWithNormals->at(i);
2578 if(mergedClouds->size() == 0)
2580 *mergedClouds = *cloudWithNormals;
2581 polygonMesh->polygons = outputPolygons;
2591 unsigned int polygonSize = outputPolygons.front().vertices.size();
2592 textureMesh->tex_polygons[oi].resize(outputPolygons.size());
2593 textureMesh->tex_coordinates[oi].resize(outputPolygons.size() * polygonSize);
2594 for(
unsigned int j=0; j<outputPolygons.size(); ++j)
2596 pcl::Vertices
vertices = outputPolygons[j];
2597 UASSERT(polygonSize == vertices.vertices.size());
2598 for(
unsigned int k=0; k<vertices.vertices.size(); ++k)
2601 UASSERT(vertices.vertices[k] < denseToOrganizedIndices.size());
2602 int originalVertex = denseToOrganizedIndices[vertices.vertices[k]];
2603 textureMesh->tex_coordinates[oi][j*vertices.vertices.size()+k] = Eigen::Vector2f(
2604 float(originalVertex % cloud->width) /
float(cloud->width),
2605 float(cloud->height - originalVertex / cloud->width) /
float(cloud->height));
2607 vertices.vertices[k] += polygonsStep;
2609 textureMesh->tex_polygons[oi][j] =
vertices;
2612 polygonsStep += outputCloud->size();
2615 if(mergedClouds->size() == 0)
2617 *mergedClouds = *transformedCloud;
2621 *mergedClouds += *transformedCloud;
2624 textureMesh->tex_materials[oi].tex_illum = 1;
2625 textureMesh->tex_materials[oi].tex_name =
uFormat(
"material_%d", iter->first);
2626 textureMesh->tex_materials[oi].tex_file =
uNumber2Str(iter->first);
2632 UERROR(
"Mesh not found for mesh %d", iter->first);
2646 if(textureSize == 0)
2648 if(mergedClouds->size())
2650 pcl::toPCLPointCloud2(*mergedClouds, polygonMesh->cloud);
2654 polygonMesh->polygons.clear();
2659 textureMesh->tex_materials.resize(oi);
2660 textureMesh->tex_polygons.resize(oi);
2662 if(mergedClouds->size())
2664 pcl::toPCLPointCloud2(*mergedClouds, textureMesh->cloud);
2671 if(textureSize>0 && totalPolygons && textureMesh->tex_materials.size())
2673 LOGI(
"Merging %d textures...", (
int)textureMesh->tex_materials.size());
2676 std::map<int, cv::Mat>(),
2677 std::map<
int, std::vector<rtabmap::CameraModel> >(),
2683 true, 10.0f,
true ,
true, 0, 0, 0,
false,
2700 if(textureSize == 0)
2702 UASSERT((
int)polygonMesh->polygons.size() == totalPolygons);
2703 if(polygonMesh->polygons.size())
2706 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2707 pcl::fromPCLPointCloud2(polygonMesh->cloud, *cloud);
2709 std::vector<std::vector<std::vector<unsigned int> > > polygons(1);
2710 polygons[0].resize(polygonMesh->polygons.size());
2711 for(
unsigned int p=0; p<polygonMesh->polygons.size(); ++p)
2713 polygons[0][p] = polygonMesh->polygons[p].vertices;
2721 else if(textureMesh->tex_materials.size())
2723 pcl::PointCloud<pcl::PointNormal>::Ptr cloud(
new pcl::PointCloud<pcl::PointNormal>);
2724 pcl::fromPCLPointCloud2(textureMesh->cloud, *cloud);
2728 std::vector<std::vector<std::vector<unsigned int> > > polygons(textureMesh->tex_polygons.size());
2729 for(
unsigned int t=0; t<textureMesh->tex_polygons.size(); ++t)
2731 polygons[t].resize(textureMesh->tex_polygons[t].size());
2732 for(
unsigned int p=0; p<textureMesh->tex_polygons[t].size(); ++p)
2734 polygons[t][p] = textureMesh->tex_polygons[t][p].vertices;
2743 UERROR(
"Failed exporting texture mesh! There are no textures!");
2748 UERROR(
"Failed exporting mesh! There are no polygons!");
2753 pcl::PointCloud<pcl::PointXYZRGB>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGB>);
2754 for(std::map<int, rtabmap::Transform>::iterator iter=poses.begin();
2758 std::map<int, Mesh>::iterator jter=
createdMeshes_.find(iter->first);
2759 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
2760 pcl::IndicesPtr indices(
new std::vector<int>);
2762 gains[0] = gains[1] = gains[2] = 1.0f;
2767 gains[0] = jter->second.gains[0];
2768 gains[1] = jter->second.gains[1];
2769 gains[2] = jter->second.gains[2];
2782 cloud = jter->second.cloud;
2783 indices = jter->second.indices;
2784 gains[0] = jter->second.gains[0];
2785 gains[1] = jter->second.gains[1];
2786 gains[2] = jter->second.gains[2];
2797 if(cloud->size() && indices->size())
2800 pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformedCloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
2801 if(cloudVoxelSize > 0.0
f)
2810 pcl::copyPointCloud(*cloud, *indices, *transformedCloud);
2814 if(gains[0] != 1.0
f || gains[1] != 1.0
f || gains[2] != 1.0
f)
2817 for(
unsigned int i=0; i<transformedCloud->size(); ++i)
2819 pcl::PointXYZRGB & pt = transformedCloud->at(i);
2828 if(mergedClouds->size() == 0)
2830 *mergedClouds = *transformedCloud;
2834 *mergedClouds += *transformedCloud;
2850 if(mergedClouds->size())
2852 if(cloudVoxelSize > 0.0
f)
2867 UERROR(
"Merged cloud is empty!");
2878 catch (std::exception &
e)
2880 UERROR(
"Out of memory! %s", e.what());
2897 if(success && poses.size())
2910 LOGI(
"postExportation(visualize=%d)", visualize?1:0);
2911 optMesh_.reset(
new pcl::TextureMesh);
2919 std::vector<std::vector<std::vector<unsigned int> > > polygons;
2920 #if PCL_VERSION_COMPARE(>=, 1, 8, 0) 2921 std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > texCoords;
2923 std::vector<std::vector<Eigen::Vector2f> > texCoords;
2929 if(!cloudMat.empty())
2931 LOGI(
"postExportation: Found optimized mesh! Visualizing it.");
2941 LOGI(
"postExportation: No optimized mesh found.");
2964 LOGI(
"writeExportedMesh: dir=%s name=%s", directory.c_str(), name.c_str());
2967 bool success =
false;
2969 pcl::PolygonMesh::Ptr polygonMesh(
new pcl::PolygonMesh);
2970 pcl::TextureMesh::Ptr textureMesh(
new pcl::TextureMesh);
2972 std::vector<std::vector<std::vector<unsigned int> > > polygons;
2973 #if PCL_VERSION_COMPARE(>=, 1, 8, 0) 2974 std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > texCoords;
2976 std::vector<std::vector<Eigen::Vector2f> > texCoords;
2982 if(!cloudMat.empty())
2984 LOGI(
"writeExportedMesh: Found optimized mesh!");
2985 if(textures.empty())
2996 LOGI(
"writeExportedMesh: No optimized mesh found.");
3000 if(polygonMesh->cloud.data.size())
3004 LOGI(
"Saving ply (%d vertices, %d polygons) to %s.", (
int)polygonMesh->cloud.data.size()/polygonMesh->cloud.point_step, (int)polygonMesh->polygons.size(), filePath.c_str());
3005 success = pcl::io::savePLYFileBinary(filePath, *polygonMesh) == 0;
3008 LOGI(
"Saved ply to %s!", filePath.c_str());
3012 UERROR(
"Failed saving ply to %s!", filePath.c_str());
3015 else if(textureMesh->cloud.data.size())
3018 LOGD(
"Saving texture(s) (%d)", textures.empty()?0:textures.cols/textures.rows);
3019 UASSERT(textures.empty() || textures.cols % textures.rows == 0);
3020 UASSERT((
int)textureMesh->tex_materials.size() == textures.cols/textures.rows);
3021 for(
unsigned int i=0; i<textureMesh->tex_materials.size(); ++i)
3023 std::string baseNameNum = name;
3024 if(textureMesh->tex_materials.size()>1)
3029 textureMesh->tex_materials[i].tex_file = baseNameNum+
".jpg";
3030 LOGI(
"Saving texture to %s.", fullPath.c_str());
3031 success = cv::imwrite(fullPath, textures(
cv::Range::all(), cv::Range(i*textures.rows, (i+1)*textures.rows)));
3034 LOGI(
"Failed saving %s!", fullPath.c_str());
3038 LOGI(
"Saved %s.", fullPath.c_str());
3045 pcl::PointCloud<pcl::PointNormal>::Ptr cloud(
new pcl::PointCloud<pcl::PointNormal>);
3046 pcl::fromPCLPointCloud2(textureMesh->cloud, *cloud);
3047 cloud =
rtabmap::util3d::transformPointCloud(cloud,
rtabmap::Transform(1,0,0,0, 0,0,1,0, 0,-1,0,0));
3048 pcl::toPCLPointCloud2(*cloud, textureMesh->cloud);
3050 int totalPolygons = 0;
3051 for(
unsigned int i=0;i<textureMesh->tex_polygons.size(); ++i)
3053 totalPolygons += textureMesh->tex_polygons[i].size();
3055 LOGI(
"Saving obj (%d vertices, %d polygons) to %s.", (
int)textureMesh->cloud.data.size()/textureMesh->cloud.point_step, totalPolygons, filePath.c_str());
3056 success = pcl::io::saveOBJFile(filePath, *textureMesh) == 0;
3060 LOGI(
"Saved obj to %s!", filePath.c_str());
3064 UERROR(
"Failed saving obj to %s!", filePath.c_str());
3075 LOGI(
"postProcessing(%d)", approach);
3076 int returnedValue = 0;
3079 std::map<int, rtabmap::Transform> poses;
3080 std::multimap<int, rtabmap::Link> links;
3083 if(approach == -1 || approach == 2)
3098 if(returnedValue >=0)
3104 std::map<int, rtabmap::Signature> signatures;
3111 poses = sba->
optimizeBA(poses.rbegin()->first, poses, links, signatures);
3116 UERROR(
"g2o not available!");
3119 else if(approach!=4 && approach!=5 && approach != 7)
3133 LOGI(
"PostProcessing, sending rtabmap event to update graph...");
3138 else if(approach!=4 && approach!=5 && approach != 7)
3143 if(returnedValue >=0)
3147 if(approach == -1 || approach == 4)
3153 if(approach == -1 || approach == 5 || approach == 6)
3167 return returnedValue;
3175 if(event->
getClassName().compare(
"OdometryEvent") == 0)
3177 LOGI(
"Received OdometryEvent!");
3191 LOGI(
"Received RtabmapEvent event!");
3219 if(event->
getClassName().compare(
"CameraTangoEvent") == 0)
3224 bool success =
false;
3228 jint
rs =
jvm->AttachCurrentThread(&env,
NULL);
3229 if(rs == JNI_OK && env)
3234 jmethodID methodID = env->GetMethodID(clazz,
"tangoEventCallback",
"(ILjava/lang/String;Ljava/lang/String;)V" );
3239 env->NewStringUTF(tangoEvent->
key().c_str()),
3240 env->NewStringUTF(tangoEvent->
value().c_str()));
3245 jvm->DetachCurrentThread();
3249 UERROR(
"Failed to call RTABMapActivity::tangoEventCallback");
3253 if(event->
getClassName().compare(
"RtabmapEventInit") == 0)
3255 LOGI(
"Received RtabmapEventInit!");
3260 bool success =
false;
3264 jint
rs =
jvm->AttachCurrentThread(&env,
NULL);
3265 if(rs == JNI_OK && env)
3270 jmethodID methodID = env->GetMethodID(clazz,
"rtabmapInitEventCallback",
"(ILjava/lang/String;)V" );
3275 env->NewStringUTF(
status_.second.c_str()));
3280 jvm->DetachCurrentThread();
3284 UERROR(
"Failed to call RTABMapActivity::rtabmapInitEventsCallback");
3288 if(event->
getClassName().compare(
"PostRenderEvent") == 0)
3290 LOGI(
"Received PostRenderEvent!");
3292 int loopClosureId = 0;
3293 int featuresExtracted = 0;
3300 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kMemoryWorking_memory_size(),
uValue(stats.
data(), rtabmap::Statistics::kMemoryWorking_memory_size(), 0.0f)));
3301 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kMemoryShort_time_memory_size(),
uValue(stats.
data(), rtabmap::Statistics::kMemoryShort_time_memory_size(), 0.0f)));
3302 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kKeypointDictionary_size(),
uValue(stats.
data(), rtabmap::Statistics::kKeypointDictionary_size(), 0.0f)));
3304 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopHighest_hypothesis_id(),
uValue(stats.
data(), rtabmap::Statistics::kLoopHighest_hypothesis_id(), 0.0f)));
3305 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kMemoryDatabase_memory_used(),
uValue(stats.
data(), rtabmap::Statistics::kMemoryDatabase_memory_used(), 0.0f)));
3306 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopVisual_inliers(),
uValue(stats.
data(), rtabmap::Statistics::kLoopVisual_inliers(), 0.0f)));
3307 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopVisual_matches(),
uValue(stats.
data(), rtabmap::Statistics::kLoopVisual_matches(), 0.0f)));
3308 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopRejectedHypothesis(),
uValue(stats.
data(), rtabmap::Statistics::kLoopRejectedHypothesis(), 0.0f)));
3309 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopOptimization_max_error(),
uValue(stats.
data(), rtabmap::Statistics::kLoopOptimization_max_error(), 0.0f)));
3310 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopOptimization_max_error_ratio(),
uValue(stats.
data(), rtabmap::Statistics::kLoopOptimization_max_error_ratio(), 0.0f)));
3311 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kMemoryRehearsal_sim(),
uValue(stats.
data(), rtabmap::Statistics::kMemoryRehearsal_sim(), 0.0f)));
3312 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopHighest_hypothesis_value(),
uValue(stats.
data(), rtabmap::Statistics::kLoopHighest_hypothesis_value(), 0.0f)));
3313 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kMemoryDistance_travelled(),
uValue(stats.
data(), rtabmap::Statistics::kMemoryDistance_travelled(), 0.0f)));
3314 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kMemoryFast_movement(),
uValue(stats.
data(), rtabmap::Statistics::kMemoryFast_movement(), 0.0f)));
3323 int databaseMemoryUsed = (int)
uValue(
bufferedStatsData_, rtabmap::Statistics::kMemoryDatabase_memory_used(), 0.0f);
3328 float optimizationMaxErrorRatio =
uValue(
bufferedStatsData_, rtabmap::Statistics::kLoopOptimization_max_error_ratio(), 0.0
f);
3334 float x=0.0f,y=0.0f,z=0.0f,
roll=0.0f,
pitch=0.0f,
yaw=0.0f;
3335 if(!currentPose.
isNull())
3341 UINFO(
"Send statistics to GUI");
3342 bool success =
false;
3346 jint
rs =
jvm->AttachCurrentThread(&env,
NULL);
3347 if(rs == JNI_OK && env)
3352 jmethodID methodID = env->GetMethodID(clazz,
"updateStatsCallback",
"(IIIIFIIIIIIFIFIFFFFIFFFFFF)V" );
3372 optimizationMaxError,
3373 optimizationMaxErrorRatio,
3386 jvm->DetachCurrentThread();
3390 UERROR(
"Failed to call RTABMapActivity::updateStatsCallback");
void save(const std::string &databasePath)
LaserScan RTABMAP_EXP laserScanFromPointCloud(const pcl::PCLPointCloud2 &cloud, bool filterNaNs=true)
GLM_FUNC_DECL T roll(detail::tquat< T, P > const &x)
std::vector< int > RTABMAP_EXP filterNaNPointsFromMesh(const pcl::PointCloud< pcl::PointXYZRGB > &cloud, const std::vector< pcl::Vertices > &polygons, pcl::PointCloud< pcl::PointXYZRGB > &outputCloud, std::vector< pcl::Vertices > &outputPolygons)
cv::Mat loadOptimizedMesh(std::vector< std::vector< std::vector< unsigned int > > > *polygons=0, std::vector< std::vector< Eigen::Vector2f > > *texCoords=0, cv::Mat *textures=0) const
void OnTouchEvent(int touch_count, tango_gl::GestureCamera::TouchEvent event, float x0, float y0, float x1, float y1)
void onCreate(JNIEnv *env, jobject caller_activity)
static const std::map< std::string, std::pair< bool, std::string > > & getRemovedParameters()
void get3DMap(std::map< int, Signature > &signatures, std::map< int, Transform > &poses, std::multimap< int, Link > &constraints, bool optimized, bool global) const
void setCameraColor(bool enabled)
cv::Mat RTABMAP_EXP mergeTextures(pcl::TextureMesh &mesh, const std::map< int, cv::Mat > &images, const std::map< int, CameraModel > &calibrations, const Memory *memory=0, const DBDriver *dbDriver=0, int textureSize=4096, int textureCount=1, const std::vector< std::map< int, pcl::PointXY > > &vertexToPixels=std::vector< std::map< int, pcl::PointXY > >(), bool gainCompensation=true, float gainBeta=10.0f, bool gainRGB=true, bool blending=true, int blendingDecimation=0, int brightnessContrastRatioLow=0, int brightnessContrastRatioHigh=0, bool exposureFusion=false, const ProgressState *state=0)
cv::Mat loadOptimizedMesh(std::vector< std::vector< std::vector< unsigned int > > > *polygons=0, std::vector< std::vector< Eigen::Vector2f > > *texCoords=0, cv::Mat *textures=0) const
int getViewPortWidth() const
void setMaxGainRadius(float value)
int openDatabase(const std::string &databasePath, bool databaseInMemory, bool optimize, const std::string &databaseSource=std::string())
void setWireframe(bool enabled)
void setAppendMode(bool enabled)
void setGridVisible(bool visible)
void setScreenRotation(TangoSupportRotation colorCameraToDisplayRotation)
bool isMeshTexturing() const
void updateCloudPolygons(int id, const std::vector< pcl::Vertices > &polygons)
void OnTouchEvent(int touch_count, tango_gl::GestureCamera::TouchEvent event, float x0, float y0, float x1, float y1)
static void post(UEvent *event, bool async=true, const UEventsSender *sender=0)
GLM_FUNC_DECL genType min(genType const &x, genType const &y)
cv::Point3f RTABMAP_EXP transformPoint(const cv::Point3f &pt, const Transform &transform)
int setMappingParameter(const std::string &key, const std::string &value)
void SetViewPort(int width, int height)
void setScreenRotation(TangoSupportRotation colorCameraToDisplayRotation)
void SetupViewPort(int w, int h)
double lastPoseEventTime_
void setSmoothing(bool enabled)
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP transformPointCloud(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const Transform &transform)
void setCloudPose(int id, const rtabmap::Transform &pose)
pcl::TextureMesh::Ptr RTABMAP_EXP createTextureMesh(const pcl::PolygonMesh::Ptr &mesh, const std::map< int, Transform > &poses, const std::map< int, CameraModel > &cameraModels, const std::map< int, cv::Mat > &cameraDepths, float maxDistance=0.0f, float maxDepthError=0.0f, float maxAngle=0.0f, int minClusterSize=50, const std::vector< float > &roiRatios=std::vector< float >(), const ProgressState *state=0, std::vector< std::map< int, pcl::PointXY > > *vertexToPixels=0)
void RTABMAP_EXP getMinMax3D(const cv::Mat &laserScan, cv::Point3f &min, cv::Point3f &max)
int lastDrawnCloudsCount_
std::vector< pcl::Vertices > filterOrganizedPolygons(const std::vector< pcl::Vertices > &polygons, int cloudSize) const
virtual bool init(const std::string &calibrationFolder=".", const std::string &cameraName="")
const std::map< int, Signature > & getSignatures() const
void setGraphOptimization(bool enabled)
std::map< int, Mesh > createdMeshes_
int getViewPortHeight() const
bool onTangoServiceConnected(JNIEnv *env, jobject iBinder)
static const rtabmap::Transform rtabmap_world_T_tango_world(0.0f, 1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f)
void setGridColor(float r, float g, float b)
int proximityDetectionId() const
void setWireframe(bool enabled)
std::pair< std::string, std::string > ParametersPair
void setGraphVisible(bool visible)
static std::string separator()
rtabmap::ParametersMap getRtabmapParameters()
bool isMapRendering() const
SensorData getNodeData(int nodeId, bool uncompressedData=false) const
bool hasMesh(int id) const
static int erase(const std::string &filePath)
void setBackfaceCulling(bool enabled)
GLM_FUNC_DECL genType e()
float UTILITE_EXP uStr2Float(const std::string &str)
GLM_FUNC_DECL bool all(vecType< bool, P > const &v)
static const float vertices[]
cv::Mat getImageCompressed(int signatureId) const
boost::mutex visLocalizationMutex_
std::map< std::string, std::string > ParametersMap
std::string UTILITE_EXP uBool2Str(bool boolean)
cv::Mat RTABMAP_EXP fastBilateralFiltering(const cv::Mat &depth, float sigmaS=15.0f, float sigmaR=0.05f, bool earlyDivision=false)
pcl::PointCloud< pcl::Normal >::Ptr normals
void setRawScanPublished(bool enabled)
std::vector< pcl::Vertices > filterPolygons(const std::vector< pcl::Vertices > &polygons, int cloudSize) const
std::vector< pcl::Vertices > polygons
GLM_FUNC_DECL T angle(detail::tquat< T, P > const &x)
std::map< std::string, float > bufferedStatsData_
void setConstraints(const std::multimap< int, Link > &constraints)
Some conversion functions.
pcl::PointCloud< pcl::PointXYZRGB >::Ptr cloud
bool acquire(int n=1, int ms=0)
std::list< rtabmap::RtabmapEvent * > rtabmapEvents_
GLM_FUNC_DECL T pitch(detail::tquat< T, P > const &x)
void setCloudDensityLevel(int value)
bool hasCloud(int id) const
const cv::Mat & imageRaw() const
bool smoothMesh(int id, Mesh &mesh)
void InitializeGLContent()
double getGain(int id, double *r=0, double *g=0, double *b=0) const
int postProcessing(int approach)
void getGraph(std::map< int, Transform > &poses, std::multimap< int, Link > &constraints, bool optimized, bool global, std::map< int, Signature > *signatures=0)
static bool isAvailable(Optimizer::Type type)
pcl::TextureMesh::Ptr optMesh_
void setRenderingTextureDecimation(int value)
void setGPS(const GPS &gps)
const std::map< int, Transform > & getLocalOptimizedPoses() const
void post(UEvent *event, bool async=true) const
void setMeshRendering(bool enabled, bool withTexture)
void setSmoothing(bool enabled)
void setClusterRatio(float value)
void setOrthoCropFactor(float value)
void setLighting(bool enabled)
void savePreviewImage(const cv::Mat &image) const
void setOrthoCropFactor(float value)
bool openConnection(const std::string &url, bool overwritten=false)
#define UASSERT(condition)
void setGPS(const rtabmap::GPS &gps)
Wrappers of STL for convenient functions.
const std::map< std::string, float > & data() const
void updateGains(int id, float gainR, float gainG, float gainB)
TangoSupportRotation GetAndroidRotationFromColorCameraToDisplay(int display_rotation, int color_camera_rotation)
const Transform & pose() const
const std::string & key() const
std::list< std::list< int > > RTABMAP_EXP clusterPolygons(const std::vector< std::set< int > > &neighborPolygons, int minClusterSize=0)
T uMax3(const T &a, const T &b, const T &c)
void setPointSize(float value)
bool filterPolygonsOnNextRender_
void close(bool databaseSaved=true, const std::string &ouputDatabasePath="")
const CameraModel & getCameraModel() const
bool takeScreenshotOnNextRender_
void RTABMAP_EXP appendMesh(pcl::PointCloud< pcl::PointXYZRGBNormal > &cloudA, std::vector< pcl::Vertices > &polygonsA, const pcl::PointCloud< pcl::PointXYZRGBNormal > &cloudB, const std::vector< pcl::Vertices > &polygonsB)
void setPoses(const std::map< int, Transform > &poses)
const rtabmap::RtabmapEvent * getRtabmapEvent() const
boost::mutex rtabmapMutex_
virtual std::string getClassName() const =0
void SetCameraPose(const rtabmap::Transform &pose)
bool clearSceneOnNextRender_
void setOptimizedPoses(const std::map< int, Transform > &poses)
void setMapRendering(bool enabled)
const Statistics & getStatistics() const
void setBlending(bool enabled)
pcl::PointCloud< pcl::PointXYZRGB >::Ptr RTABMAP_EXP cloudRGBFromSensorData(const SensorData &sensorData, int decimation=1, float maxDepth=0.0f, float minDepth=0.0f, std::vector< int > *validIndices=0, const ParametersMap &stereoParameters=ParametersMap(), const std::vector< float > &roiRatios=std::vector< float >())
void addCloud(int id, const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloud, const pcl::IndicesPtr &indices, const rtabmap::Transform &pose)
void setBackgroundColor(float r, float g, float b)
void setTrajectoryMode(bool enabled)
static const rtabmap::Transform opengl_world_T_rtabmap_world(0.0f,-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,-1.0f, 0.0f, 0.0f, 0.0f)
virtual bool handleEvent(UEvent *event)
cv::Mat RTABMAP_EXP computeNormals(const cv::Mat &laserScan, int searchK, float searchRadius)
void setCloudVisible(int id, bool visible)
pcl::TextureMesh::Ptr RTABMAP_EXP assembleTextureMesh(const cv::Mat &cloudMat, const std::vector< std::vector< std::vector< unsigned int > > > &polygons, const std::vector< std::vector< Eigen::Vector2f > > &texCoords, cv::Mat &textures, bool mergeTextures=false)
static void copy(const std::string &from, const std::string &to)
std::map< int, rtabmap::Transform > rawPoses_
void setMaxCloudDepth(float value)
void setGridRotation(float value)
int renderingTextureDecimation_
void updateGraph(const std::map< int, rtabmap::Transform > &poses, const std::multimap< int, rtabmap::Link > &links)
bool isMeshRendering() const
void setBackfaceCulling(bool enabled)
void setPointSize(float size)
void setRawScanSaved(bool enabled)
void SetCameraType(tango_gl::GestureCamera::CameraType camera_type)
std::set< int > getAddedClouds() const
void TangoResetMotionTracking()
cv::Mat RTABMAP_EXP compressData2(const cv::Mat &data)
bool hasTexture(int id) const
void updateMesh(int id, const Mesh &mesh)
int loopClosureId() const
std::vector< pcl::Vertices > RTABMAP_EXP organizedFastMesh(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, double angleTolerance, bool quad, int trianglePixelSize, const Eigen::Vector3f &viewpoint=Eigen::Vector3f(0, 0, 0))
void init(const ParametersMap ¶meters, const std::string &databasePath="")
int gainCompensationOnNextRender_
bool uContains(const std::list< V > &list, const V &value)
bool postExportation(bool visualize)
void setBackgroundColor(float gray)
static DBDriver * create(const ParametersMap ¶meters=ParametersMap())
GLM_FUNC_DECL detail::tquat< T, P > rotation(detail::tvec3< T, P > const &orig, detail::tvec3< T, P > const &dest)
void parseParameters(const ParametersMap ¶meters)
void setMeshRendering(bool enabled, bool withTexture)
const VWDictionary * getVWDictionary() const
static const rtabmap::Transform opengl_world_T_tango_world(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f)
void setNodesFiltering(bool enabled)
boost::mutex meshesMutex_
double lastPostRenderEventTime_
void registerToEventsManager()
void setMapCloudShown(bool shown)
void uSleep(unsigned int ms)
const std::map< int, Transform > & poses() const
bool isValidForProjection() const
static const ParametersMap & getDefaultParameters()
rtabmap::RtabmapThread * rtabmapThread_
const std::vector< CameraModel > & cameraModels() const
const Transform & getPose() const
void setDetectorRate(float rate)
virtual std::map< int, Transform > optimizeBA(int rootId, const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, const std::map< int, CameraModel > &models, std::map< int, cv::Point3f > &points3DMap, const std::map< int, std::map< int, cv::Point3f > > &wordReferences, std::set< int > *outliers=0)
void setColorCamera(bool enabled)
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
SensorData & sensorData()
void RTABMAP_EXP cleanTextureMesh(pcl::TextureMesh &textureMesh, int minClusterSize)
void setJavaObjects(JavaVM *jvm, jobject rtabmap)
const Signature * getLastWorkingSignature() const
void setMinCloudDepth(float value)
void setTraceVisible(bool visible)
void SetCameraType(tango_gl::GestureCamera::CameraType camera_type)
rtabmap::Transform GetCameraPose() const
void setDecimation(int value)
void RTABMAP_EXP createPolygonIndexes(const std::vector< pcl::Vertices > &polygons, int cloudSize, std::vector< std::set< int > > &neighborPolygons, std::vector< std::set< int > > &vertexPolygons)
Given a set of polygons, create two indexes: polygons to neighbor polygons and vertices to polygons...
rtabmap::Transform mapToOdom_
std::pair< rtabmap::RtabmapEventInit::Status, std::string > status_
int detectMoreLoopClosures(float clusterRadius=0.5f, float clusterAngle=M_PI/6.0f, int iterations=1, const ProgressState *state=0)
const Memory * getMemory() const
rtabmap::RtabmapEvent * rtabmapEvent_
void setOnlineBlending(bool enabled)
void feed(const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloudA, const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloudB, const Transform &transformB)
bool exportedMeshUpdated_
void close(bool databaseSaved, const std::string &databasePath="")
void gainCompensation(bool full=false)
void setDataRecorderMode(bool enabled)
GLM_FUNC_DECL T yaw(detail::tquat< T, P > const &x)
void setGraphVisible(bool visible)
bool writeExportedMesh(const std::string &directory, const std::string &name)
bool cameraJustInitialized_
boost::mutex renderingMutex_
static jobject RTABMapActivity
void setMeshTriangleSize(int value)
void addMesh(int id, const Mesh &mesh, const rtabmap::Transform &pose, bool createWireframe=false)
void unregisterFromEventsManager()
void setGridVisible(bool visible)
float getDetectorRate() const
void saveOptimizedMesh(const cv::Mat &cloud, const std::vector< std::vector< std::vector< unsigned int > > > &polygons=std::vector< std::vector< std::vector< unsigned int > > >(), const std::vector< std::vector< Eigen::Vector2f > > &texCoords=std::vector< std::vector< Eigen::Vector2f > >(), const cv::Mat &textures=cv::Mat()) const
void join(bool killFirst=false)
bool exportMesh(float cloudVoxelSize, bool regenerateCloud, bool meshing, int textureSize, int textureCount, int normalK, bool optimized, float optimizedVoxelSize, int optimizedDepth, int optimizedMaxPolygons, float optimizedColorRadius, bool optimizedCleanWhitePolygons, int optimizedMinClusterSize, float optimizedMaxTextureDistance, int optimizedMinTextureClusterSize, bool blockRendering)
float meshAngleToleranceDeg_
std::list< rtabmap::Transform > poseEvents_
void setGridRotation(float angleDeg)
USemaphore screenshotReady_
void setFullResolution(bool enabled)
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP voxelize(const pcl::PointCloud< pcl::PointXYZ >::Ptr &cloud, const pcl::IndicesPtr &indices, float voxelSize)
void setMeshAngleTolerance(float value)
const Transform & mapCorrection() const
std::list< rtabmap::OdometryEvent > odomEvents_
void setScreenRotation(int displayRotation, int cameraRotation)
std::string UTILITE_EXP uFormat(const char *fmt,...)
rtabmap::Rtabmap * rtabmap_
std::string UTILITE_EXP uNumber2Str(unsigned int number)
bool bilateralFilteringOnNextRender_
rtabmap::ParametersMap mappingParameters_
rtabmap::ProgressionStatus progressionStatus_
void setLighting(bool enabled)
std::vector< Eigen::Vector2f > texCoords
rtabmap::Transform * optRefPose_
static Optimizer * create(const ParametersMap ¶meters)
V uValue(const std::map< K, V > &m, const K &key, const V &defaultValue=V())
rtabmap::CameraTango * camera_
PostRenderEvent(rtabmap::RtabmapEvent *event=0)
rtabmap::CameraModel cameraModel
const std::map< int, VisualWord * > & getVisualWords() const
void setPausedMapping(bool paused)
const std::string & value() const
int getDatabaseMemoryUsed() const
cv::Mat RTABMAP_EXP uncompressImage(const cv::Mat &bytes)
void addStatistic(const std::string &name, float value)
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)
void setOdomCloudShown(bool shown)
void setLocalizationMode(bool enabled)
std::list< rtabmap::RtabmapEvent * > visLocalizationEvents_
void increment(int count=1) const
const Transform & localTransform() const
virtual std::string getClassName() const
pcl::PolygonMesh::Ptr RTABMAP_EXP assemblePolygonMesh(const cv::Mat &cloudMat, const std::vector< std::vector< unsigned int > > &polygons)
void setCanceled(bool canceled)