32 #include "CameraAvailability.h" 39 #include <media/NdkImage.h> 41 #ifdef RTABMAP_ARENGINE 56 #include <opencv2/opencv_modules.hpp> 68 #include <pcl/common/common.h> 69 #include <pcl/filters/extract_indices.h> 70 #include <pcl/io/ply_io.h> 71 #include <pcl/io/obj_io.h> 72 #include <pcl/surface/poisson.h> 73 #include <pcl/surface/vtk_smoothing/vtk_mesh_quadric_decimation.h> 83 static jobject RTABMapActivity = 0;
91 static void *thread_func(
void*)
95 while((rdsz = read(pfd[0], buf,
sizeof buf - 1)) > 0) {
96 if(buf[rdsz - 1] ==
'\n') --rdsz;
98 __android_log_write(ANDROID_LOG_DEBUG,
LOG_TAG, buf);
106 setvbuf(stdout, 0, _IOLBF, 0);
107 setvbuf(stderr, 0, _IONBF, 0);
115 if(pthread_create(&thr, 0, thread_func, 0) == -1)
134 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapPublishLikelihood(), std::string(
"false")));
142 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kMemCompressionParallelized(), std::string(
"false")));
144 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kRGBDOptimizeFromGraphEnd(), std::string(
"true")));
146 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kRGBDProximityPathMaxNeighbors(), std::string(
"0")));
147 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kRGBDProximityBySpace(), std::string(
"false")));
153 if(parameters.find(rtabmap::Parameters::kOptimizerStrategy()) != parameters.end())
155 if(parameters.at(rtabmap::Parameters::kOptimizerStrategy()).compare(
"2") == 0)
161 else if(parameters.at(rtabmap::Parameters::kOptimizerStrategy()).compare(
"1") == 0)
181 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kIcpCorrespondenceRatio(), std::string(
"0.49")));
182 parameters.insert(
rtabmap::ParametersPair(rtabmap::Parameters::kIcpMaxCorrespondenceDistance(), std::string(
"0.05")));
257 env->GetJavaVM(&jvm);
258 RTABMapActivity = env->NewGlobalRef(caller_activity);
261 LOGI(
"RTABMapApp::RTABMapApp()");
283 LOGI(
"RTABMapApp::RTABMapApp() end");
292 #ifndef __ANDROID__ // __APPLE__ 294 void(*progressCallback)(
void *,
int,
int),
295 void(*initCallback)(
void *,
int,
const char*),
296 void(*statsUpdatedCallback)(
void *,
299 int,
int,
int,
int,
int ,
int,
304 float,
float,
float,
float,
306 float,
float,
float,
float,
float,
float))
316 LOGI(
"~RTABMapApp() begin");
336 LOGI(
"~RTABMapApp() end");
354 LOGW(
"Opening database %s (inMemory=%d, optimize=%d, clearDatabase=%d)", databasePath.c_str(), databaseInMemory?1:0, optimize?1:0, clearDatabase?1:0);
367 bool restartThread =
false;
391 optMesh_.reset(
new pcl::TextureMesh);
400 std::vector<std::vector<std::vector<RTABMAP_PCL_INDEX> > > polygons;
401 #if PCL_VERSION_COMPARE(>=, 1, 8, 0) 402 std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > texCoords;
404 std::vector<std::vector<Eigen::Vector2f> > texCoords;
407 if(!databasePath.empty() &&
UFile::exists(databasePath) && !clearDatabase)
414 if(!cloudMat.empty())
416 LOGI(
"Open: Found optimized mesh! Visualizing it.");
424 else if(
optMesh_->tex_polygons.size())
426 LOGI(
"Open: Polygon mesh");
429 else if(!
optMesh_->cloud.data.empty())
431 LOGI(
"Open: Point cloud");
437 LOGI(
"Open: No optimized mesh found.");
465 LOGI(
"Erasing database \"%s\"...", databasePath.c_str());
475 LOGI(
"Initializing database...");
478 if(parameters.find(rtabmap::Parameters::kRtabmapDetectionRate()) != parameters.end())
484 std::map<int, rtabmap::Signature> signatures;
485 std::map<int, rtabmap::Transform> poses;
486 std::multimap<int, rtabmap::Link> links;
487 LOGI(
"Loading full map from database...");
500 if(signatures.size() && poses.empty())
502 LOGE(
"Failed to optimize the graph!");
507 LOGI(
"Creating the meshes (%d)....", (
int)poses.size());
513 for(std::map<int, rtabmap::Transform>::iterator iter=poses.begin(); iter!=poses.end() && status>=0; ++iter)
517 int id = iter->first;
518 if(!iter->second.isNull())
524 rawPoses_.insert(std::make_pair(
id, signatures.at(
id).getPose()));
538 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
539 pcl::IndicesPtr indices(
new std::vector<int>);
550 indices->resize(cloud->size());
551 for(
unsigned int i=0; i<cloud->size(); ++i)
557 if(cloud->size() && indices->size())
559 std::vector<pcl::Vertices> polygons;
560 std::vector<pcl::Vertices> polygonsLowRes;
561 #if PCL_VERSION_COMPARE(>=, 1, 8, 0) 562 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > texCoords;
564 std::vector<Eigen::Vector2f> texCoords;
572 pcl::PolygonMesh::Ptr tmpMesh(
new pcl::PolygonMesh);
573 pcl::toPCLPointCloud2(*cloud, tmpMesh->cloud);
574 tmpMesh->polygons = polygons;
575 rtabmap::util3d::denseMeshPostProcessing<pcl::PointXYZRGB>(tmpMesh,
meshDecimationFactor_, 0, cloud, 0);
576 if(!tmpMesh->polygons.empty())
580 std::map<int, rtabmap::Transform> cameraPoses;
581 std::map<int, rtabmap::CameraModel> cameraModels;
583 cameraModels.insert(std::make_pair(0, data.
cameraModels()[0]));
588 std::map<int, cv::Mat>());
589 pcl::fromPCLPointCloud2(textureMesh->cloud, *cloud);
590 polygons = textureMesh->tex_polygons[0];
591 texCoords = textureMesh->tex_coordinates[0];
595 pcl::fromPCLPointCloud2(tmpMesh->cloud, *cloud);
596 polygons = tmpMesh->polygons;
599 indices->resize(cloud->size());
600 for(
unsigned int i=0; i<cloud->size(); ++i)
607 LOGE(
"Mesh decimation factor is too high (%f), returning full mesh (id=%d).", meshDecimationFactor_, data.
id());
610 #ifdef DEBUG_RENDERING_PERFORMANCE 611 LOGW(
"Mesh simplication, %d polygons, %d points (%fs)", (
int)polygons.size(), (int)cloud->size(), timer.
ticks());
623 inserted.first->second.cloud = cloud;
624 inserted.first->second.indices = indices;
625 inserted.first->second.polygons = polygons;
626 inserted.first->second.polygonsLowRes = polygonsLowRes;
627 inserted.first->second.visible =
true;
628 inserted.first->second.cameraModel = data.
cameraModels()[0];
629 inserted.first->second.gains[0] = 1.0;
630 inserted.first->second.gains[1] = 1.0;
631 inserted.first->second.gains[2] = 1.0;
634 inserted.first->second.texCoords = texCoords;
638 cv::resize(data.
imageRaw(), inserted.first->second.texture, reducedSize, 0, 0, cv::INTER_LINEAR);
642 inserted.first->second.texture = data.
imageRaw();
645 LOGI(
"Created cloud %d (%fs, %d points)",
id, timer.
ticks(), (int)cloud->size());
649 UWARN(
"Cloud %d is empty",
id);
654 UERROR(
"Failed to uncompress data!");
660 UWARN(
"Data for node %d not found",
id);
665 UWARN(
"Pose %d is null !?",
id);
676 UERROR(
"Exception! msg=\"%s\"", e.what());
679 catch (
const cv::Exception & e)
681 UERROR(
"Exception! msg=\"%s\"", e.what());
684 catch (
const std::exception & e)
686 UERROR(
"Exception! msg=\"%s\"", e.what());
703 if(optimize && status>=0)
708 LOGI(
"Polygon filtering...");
713 if(iter->second.polygons.size())
722 LOGI(
"Open: add rtabmap event to update the scene");
760 if(poses.empty() || status>0)
775 if((height >= 480 || width >= 480) && width % 20 == 0 && height % 20 == 0)
779 else if(width % 15 == 0 && height % 15 == 0)
783 else if(width % 10 == 0 && height % 10 == 0)
787 else if(width % 8 == 0 && height % 8 == 0)
793 UERROR(
"Could not set decimation to high (size=%dx%d)", width, height);
798 if((height >= 480 || width >= 480) && width % 10 == 0 && height % 10 == 0)
802 else if(width % 5 == 0 && height % 5 == 0)
806 else if(width % 4 == 0 && height % 4 == 0)
812 UERROR(
"Could not set decimation to medium (size=%dx%d)", width, height);
817 if((height >= 480 || width >= 480) && width % 5 == 0 && height % 5 == 0)
821 else if(width % 3 == 0 && width % 3 == 0)
825 else if(width % 2 == 0 && width % 2 == 0)
831 UERROR(
"Could not set decimation to low (size=%dx%d)", width, height);
835 LOGI(
"Set decimation to %d (image=%dx%d, density level=%d)", meshDecimation, width, height,
cloudDensityLevel_);
841 if(cameraDriver == 0)
850 if(cameraDriver == 1)
852 #ifdef RTABMAP_ARCORE 859 if(cameraDriver == 2)
861 #ifdef RTABMAP_ARENGINE 894 if (TangoService_setBinder(env, iBinder) != TANGO_SUCCESS) {
895 UERROR(
"TangoHandler::ConnectTango, TangoService_setBinder error");
901 UERROR(
"RTAB-Map is not built with Tango support!");
906 #ifdef RTABMAP_ARCORE 909 UERROR(
"RTAB-Map is not built with ARCore support!");
914 #ifdef RTABMAP_ARENGINE 917 UERROR(
"RTAB-Map is not built with AREngine support!");
938 LOGI(
"Start camera thread");
942 UERROR(
"Failed camera initialization!");
948 LOGI(
"stopCamera()");
968 const std::vector<pcl::Vertices> & polygons,
971 std::vector<int> vertexToCluster(cloudSize, 0);
972 std::map<int, std::list<int> > clusters;
973 int lastClusterID = 0;
975 for(
unsigned int i=0; i<polygons.size(); ++i)
978 for(
unsigned int j=0;j<polygons[i].vertices.size(); ++j)
980 if(vertexToCluster[polygons[i].
vertices[j]]>0)
982 clusterID = vertexToCluster[polygons[i].vertices[j]];
988 clusters.at(clusterID).push_back(i);
992 clusterID = ++lastClusterID;
993 std::list<int> polygons;
994 polygons.push_back(i);
995 clusters.insert(std::make_pair(clusterID, polygons));
997 for(
unsigned int j=0;j<polygons[i].vertices.size(); ++j)
999 vertexToCluster[polygons[i].vertices[j]] = clusterID;
1003 unsigned int biggestClusterSize = 0;
1004 for(std::map<
int, std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
1008 if(iter->second.size() > biggestClusterSize)
1010 biggestClusterSize = iter->second.size();
1013 unsigned int minClusterSize = (
unsigned int)(
float(biggestClusterSize)*
clusterRatio_);
1017 std::vector<pcl::Vertices> filteredPolygons(polygons.size());
1019 for(std::map<
int, std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
1021 if(iter->second.size() >= minClusterSize)
1023 for(std::list<int>::iterator jter=iter->second.begin(); jter!=iter->second.end(); ++jter)
1025 filteredPolygons[oi++] = polygons[*jter];
1029 filteredPolygons.resize(oi);
1030 return filteredPolygons;
1035 const std::vector<pcl::Vertices> & polygons,
1036 int cloudSize)
const 1039 std::vector<std::set<int> > neighbors;
1040 std::vector<std::set<int> > vertexToPolygons;
1048 unsigned int biggestClusterSize = 0;
1049 for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
1051 if(iter->size() > biggestClusterSize)
1053 biggestClusterSize = iter->size();
1056 unsigned int minClusterSize = (
unsigned int)(
float(biggestClusterSize)*
clusterRatio_);
1057 LOGI(
"Biggest cluster = %d -> minClusterSize(ratio=%f)=%d",
1060 std::vector<pcl::Vertices> filteredPolygons(polygons.size());
1062 for(std::list<std::list<int> >::iterator jter=clusters.begin(); jter!=clusters.end(); ++jter)
1064 if(jter->size() >= minClusterSize)
1066 for(std::list<int>::iterator kter=jter->begin(); kter!=jter->end(); ++kter)
1068 filteredPolygons[oi++] = polygons.at(*kter);
1072 filteredPolygons.resize(oi);
1073 return filteredPolygons;
1101 rtabmapEvent_(event)
1106 if(rtabmapEvent_!=0)
1108 delete rtabmapEvent_;
1123 cv::Mat depth = cv::Mat::zeros(mesh.
cloud->height, mesh.
cloud->width, CV_32FC1);
1125 for(
unsigned int i=0; i<mesh.
indices->size(); ++i)
1127 int index = mesh.
indices->at(i);
1129 if(mesh.
cloud->at(index).x > 0)
1132 depth.at<
float>(index) = pt.z;
1137 LOGI(
"smoothMesh() Bilateral filtering of %d, time=%fs",
id, t.
ticks());
1139 if(!depth.empty() && mesh.
indices->size())
1141 pcl::IndicesPtr newIndices(
new std::vector<int>(mesh.
indices->size()));
1143 for(
unsigned int i=0; i<mesh.
indices->size(); ++i)
1145 int index = mesh.
indices->at(i);
1147 pcl::PointXYZRGB & pt = mesh.
cloud->at(index);
1149 if(depth.at<
float>(index) > 0)
1151 newPt.z = depth.at<
float>(index);
1153 newIndices->at(oi++) = index;
1157 newPt.x = newPt.y = newPt.z = std::numeric_limits<float>::quiet_NaN();
1163 newIndices->resize(oi);
1167 std::vector<pcl::Vertices> polygons;
1172 LOGI(
"smoothMesh() Reconstructing the mesh of %d, time=%fs",
id, t.
ticks());
1177 UERROR(
"smoothMesh() Failed to smooth surface %d",
id);
1185 UTimer tGainCompensation;
1186 LOGI(
"Gain compensation...");
1189 std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr > clouds;
1190 std::map<int, pcl::IndicesPtr> indices;
1193 clouds.insert(std::make_pair(iter->first, iter->second.cloud));
1194 indices.insert(std::make_pair(iter->first, iter->second.indices));
1196 std::map<int, rtabmap::Transform> poses;
1197 std::multimap<int, rtabmap::Link> links;
1203 for(std::map<
int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr>::const_iterator iter=clouds.begin(); iter!=clouds.end(); ++iter)
1205 int from = iter->first;
1206 std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr>::const_iterator jter = iter;
1208 for(;jter!=clouds.end(); ++jter)
1210 int to = jter->first;
1218 if(clouds.size() > 1 && links.size())
1220 compensator.
feed(clouds, indices, links);
1221 LOGI(
"Gain compensation... compute gain: links=%d, time=%fs", (
int)links.size(), tGainCompensation.
ticks());
1226 if(!iter->second.cloud->empty())
1228 if(clouds.size() > 1 && links.size())
1230 compensator.
getGain(iter->first, &iter->second.gains[0], &iter->second.gains[1], &iter->second.gains[2]);
1231 LOGI(
"%d mesh has gain %f,%f,%f", iter->first, iter->second.gains[0], iter->second.gains[1], iter->second.gains[2]);
1235 LOGI(
"Gain compensation... applying gain: meshes=%d, time=%fs", (
int)
createdMeshes_.size(), tGainCompensation.
ticks());
1241 std::list<rtabmap::RtabmapEvent*> rtabmapEvents;
1250 #ifdef DEBUG_RENDERING_PERFORMANCE 1255 bool notifyDataLoaded =
false;
1256 bool notifyCameraStarted =
false;
1264 const float* uvsTransformed = 0;
1277 #ifdef DEBUG_RENDERING_PERFORMANCE 1278 LOGW(
"Camera spinOnce %fs", time.
ticks());
1305 pcl::IndicesPtr indices(
new std::vector<int>);
1309 occlusionMesh.
cloud.reset(
new pcl::PointCloud<pcl::PointXYZRGB>());
1310 pcl::copyPointCloud(*cloud, *occlusionMesh.
cloud);
1311 occlusionMesh.
indices = indices;
1314 else if(!occlusionImage.empty())
1316 UERROR(
"invalid occlusionModel: %f %f %f %f %dx%d", occlusionModel.
fx(), occlusionModel.
fy(), occlusionModel.
cx(), occlusionModel.
cy(), occlusionModel.
imageWidth(), occlusionModel.
imageHeight());
1320 #ifdef DEBUG_RENDERING_PERFORMANCE 1321 LOGW(
"Update background and occlusion mesh %fs", time.
ticks());
1342 LOGI(
"Process odom events");
1347 notifyCameraStarted =
true;
1366 notifyCameraStarted =
true;
1381 LOGI(
"Adding optimized mesh to opengl (%d points, %d polygons, %d tex_coords, materials=%d texture=%dx%d)...",
1384 optMesh_->tex_coordinates.size()!=1?0:(int)
optMesh_->tex_coordinates[0].size(),
1385 (int)
optMesh_->tex_materials.size(),
1391 mesh.
cloud.reset(
new pcl::PointCloud<pcl::PointXYZRGB>);
1392 mesh.
normals.reset(
new pcl::PointCloud<pcl::Normal>);
1397 if(
optMesh_->tex_coordinates.size())
1406 pcl::IndicesPtr indices(
new std::vector<int>);
1407 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
1408 pcl::fromPCLPointCloud2(
optMesh_->cloud, *cloud);
1420 if(rtabmapEvents.size())
1428 std::map<int, rtabmap::Transform>::const_iterator iter = stats.
poses().find(
optRefId_);
1434 int fastMovement = (int)
uValue(stats.
data(), rtabmap::Statistics::kMemoryFast_movement(), 0.0f);
1435 int loopClosure = (int)
uValue(stats.
data(), rtabmap::Statistics::kLoopAccepted_hypothesis_id(), 0.0f);
1436 int proximityClosureId = int(
uValue(stats.
data(), rtabmap::Statistics::kProximitySpace_last_detection_id(), 0.0f));
1437 int rejected = (int)
uValue(stats.
data(), rtabmap::Statistics::kLoopRejectedHypothesis(), 0.0f);
1438 int landmark = (int)
uValue(stats.
data(), rtabmap::Statistics::kLoopLandmark_detected(), 0.0f);
1472 for(std::map<int, rtabmap::Transform>::const_iterator iter=stats.
poses().begin();
1473 iter!=stats.
poses().end() && iter->first<0;
1476 int id = iter->first;
1507 if(rtabmapEvents.size())
1510 if(rtabmapEvents.back()->getStats().refImageId()>0 ||
1511 !rtabmapEvents.back()->getStats().data().empty())
1514 rtabmapEvents.pop_back();
1517 for(std::list<rtabmap::RtabmapEvent*>::iterator iter=rtabmapEvents.begin(); iter!=rtabmapEvents.end(); ++iter)
1521 rtabmapEvents.clear();
1530 optMesh_.reset(
new pcl::TextureMesh);
1547 if(rtabmapEvents.front()->getStats().refImageId()>0 && rtabmapEvents.front()->getStats().refImageId() <
createdMeshes_.rbegin()->first)
1549 LOGI(
"Detected new database! new=%d old=%d", rtabmapEvents.front()->getStats().refImageId(),
createdMeshes_.rbegin()->first);
1554 #ifdef DEBUG_RENDERING_PERFORMANCE 1555 if(rtabmapEvents.size())
1557 LOGW(
"begin and getting rtabmap events %fs", time.
ticks());
1564 LOGI(
"Clearing all rendering data...");
1578 LOGI(
"Clearing meshes...");
1584 notifyDataLoaded =
true;
1602 if(added.size() != meshes)
1604 LOGI(
"added (%d) != meshes (%d)", (
int)added.size(), meshes);
1611 LOGI(
"Re-add mesh %d to OpenGL context", iter->first);
1622 if(!textureRaw.empty())
1627 LOGD(
"resize image from %dx%d to %dx%d", textureRaw.cols, textureRaw.rows, reducedSize.width, reducedSize.height);
1628 cv::resize(textureRaw, iter->second.texture, reducedSize, 0, 0, cv::INTER_LINEAR);
1632 iter->second.texture = textureRaw;
1639 iter->second.texture = cv::Mat();
1644 else if(notifyDataLoaded)
1653 if(rtabmapEvents.size())
1655 #ifdef DEBUG_RENDERING_PERFORMANCE 1656 LOGW(
"Process rtabmap events %fs", time.
ticks());
1658 LOGI(
"Process rtabmap events");
1662 std::map<int, rtabmap::SensorData> bufferedSensorData;
1665 for(std::list<rtabmap::RtabmapEvent*>::iterator iter=rtabmapEvents.begin(); iter!=rtabmapEvents.end(); ++iter)
1670 int smallMovement = (int)
uValue(stats.
data(), rtabmap::Statistics::kMemorySmall_movement(), 0.0f);
1671 int fastMovement = (int)
uValue(stats.
data(), rtabmap::Statistics::kMemoryFast_movement(), 0.0f);
1672 int rehearsalMerged = (int)
uValue(stats.
data(), rtabmap::Statistics::kMemoryRehearsal_merged(), 0.0f);
1674 smallMovement == 0 && rehearsalMerged == 0 && fastMovement == 0)
1689 int loopClosure = (int)
uValue(stats.
data(), rtabmap::Statistics::kLoopAccepted_hypothesis_id(), 0.0f);
1690 int proximityClosureId = int(
uValue(stats.
data(), rtabmap::Statistics::kProximitySpace_last_detection_id(), 0.0f));
1691 int rejected = (int)
uValue(stats.
data(), rtabmap::Statistics::kLoopRejectedHypothesis(), 0.0f);
1692 int landmark = (int)
uValue(stats.
data(), rtabmap::Statistics::kLoopLandmark_detected(), 0.0f);
1724 #ifdef DEBUG_RENDERING_PERFORMANCE 1725 LOGW(
"Looking for data to load (%d) %fs", (
int)bufferedSensorData.size(), time.
ticks());
1728 std::map<int, rtabmap::Transform> posesWithMarkers = rtabmapEvents.back()->getStats().poses();
1729 if(!rtabmapEvents.back()->getStats().mapCorrection().isNull())
1731 mapToOdom_ = rtabmapEvents.back()->getStats().mapCorrection();
1735 for(std::map<int, rtabmap::Transform>::iterator iter=posesWithMarkers.begin(); iter!=posesWithMarkers.end(); ++iter)
1739 std::map<int, rtabmap::Transform>::iterator jter =
rawPoses_.find(iter->first);
1751 std::map<int, rtabmap::Transform> poses(posesWithMarkers.lower_bound(0), posesWithMarkers.end());
1752 const std::multimap<int, rtabmap::Link> & links = rtabmapEvents.back()->getStats().constraints();
1758 #ifdef DEBUG_RENDERING_PERFORMANCE 1759 LOGW(
"Update graph: %fs", time.
ticks());
1764 std::set<std::string> strIds;
1765 for(std::map<int, rtabmap::Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
1767 int id = iter->first;
1768 if(!iter->second.isNull())
1775 std::map<int, rtabmap::Mesh>::iterator meshIter =
createdMeshes_.find(
id);
1778 meshIter->second.visible =
true;
1783 bufferedSensorData.find(
id) != bufferedSensorData.end())
1787 cv::Mat tmpA, depth;
1794 #ifdef DEBUG_RENDERING_PERFORMANCE 1795 LOGW(
"Decompressing data: %fs", time.
ticks());
1801 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
1802 pcl::IndicesPtr indices(
new std::vector<int>);
1812 indices->resize(cloud->size());
1813 for(
unsigned int i=0; i<cloud->size(); ++i)
1818 #ifdef DEBUG_RENDERING_PERFORMANCE 1821 if(cloud->size() && indices->size())
1823 std::vector<pcl::Vertices> polygons;
1824 std::vector<pcl::Vertices> polygonsLowRes;
1825 #if PCL_VERSION_COMPARE(>=, 1, 8, 0) 1826 std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > texCoords;
1828 std::vector<Eigen::Vector2f> texCoords;
1830 pcl::PointCloud<pcl::Normal>::Ptr normals(
new pcl::PointCloud<pcl::Normal>);
1834 #ifdef DEBUG_RENDERING_PERFORMANCE 1835 LOGW(
"Creating mesh, %d polygons (%fs)", (
int)polygons.size(), time.
ticks());
1840 pcl::PolygonMesh::Ptr tmpMesh(
new pcl::PolygonMesh);
1841 pcl::toPCLPointCloud2(*cloud, tmpMesh->cloud);
1842 tmpMesh->polygons = polygons;
1843 rtabmap::util3d::denseMeshPostProcessing<pcl::PointXYZRGB>(tmpMesh,
meshDecimationFactor_, 0, cloud, 0);
1845 if(!tmpMesh->polygons.empty())
1849 std::map<int, rtabmap::Transform> cameraPoses;
1850 std::map<int, rtabmap::CameraModel> cameraModels;
1852 cameraModels.insert(std::make_pair(0, data.
cameraModels()[0]));
1857 std::map<int, cv::Mat>());
1858 pcl::fromPCLPointCloud2(textureMesh->cloud, *cloud);
1859 polygons = textureMesh->tex_polygons[0];
1860 texCoords = textureMesh->tex_coordinates[0];
1864 pcl::fromPCLPointCloud2(tmpMesh->cloud, *cloud);
1865 polygons = tmpMesh->polygons;
1868 indices->resize(cloud->size());
1869 for(
unsigned int i=0; i<cloud->size(); ++i)
1876 LOGE(
"Mesh decimation factor is too high (%f), returning full mesh (id=%d).", meshDecimationFactor_, data.
id());
1878 #ifdef DEBUG_RENDERING_PERFORMANCE 1879 LOGW(
"Creating mesh, %d polygons (%fs)", (
int)polygons.size(), time.
ticks());
1882 #ifdef DEBUG_RENDERING_PERFORMANCE 1883 LOGW(
"Mesh simplication, %d polygons, %d points (%fs)", (
int)polygons.size(), (int)cloud->size(), time.
ticks());
1890 #ifdef DEBUG_RENDERING_PERFORMANCE 1891 LOGW(
"Creating mesh, %d polygons (%fs)", (
int)polygons.size(), time.
ticks());
1898 inserted.first->second.cloud = cloud;
1899 inserted.first->second.indices = indices;
1900 inserted.first->second.polygons = polygons;
1901 inserted.first->second.polygonsLowRes = polygonsLowRes;
1902 inserted.first->second.visible =
true;
1903 inserted.first->second.cameraModel = data.
cameraModels()[0];
1904 inserted.first->second.gains[0] = 1.0;
1905 inserted.first->second.gains[1] = 1.0;
1906 inserted.first->second.gains[2] = 1.0;
1909 inserted.first->second.texCoords = texCoords;
1913 cv::resize(data.
imageRaw(), inserted.first->second.texture, reducedSize, 0, 0, cv::INTER_LINEAR);
1914 #ifdef DEBUG_RENDERING_PERFORMANCE 1915 LOGW(
"resize image from %dx%d to %dx%d (%fs)", data.
imageRaw().cols, data.
imageRaw().rows, reducedSize.width, reducedSize.height, time.
ticks());
1920 inserted.first->second.texture = data.
imageRaw();
1933 #ifdef DEBUG_RENDERING_PERFORMANCE 1934 LOGW(
"Adding mesh to scene: %fs", time.
ticks());
1944 if(poses.size() > 2)
1948 for(std::multimap<int, rtabmap::Link>::const_iterator iter=links.begin(); iter!=links.end(); ++iter)
1952 int oldId = iter->second.to()>iter->second.from()?iter->second.from():iter->second.to();
1964 for(std::set<int>::const_iterator iter=addedClouds.begin();
1965 iter!=addedClouds.end();
1968 if(*iter > 0 && poses.find(*iter) == poses.end())
1971 std::map<int, rtabmap::Mesh>::iterator meshIter =
createdMeshes_.find(*iter);
1973 meshIter->second.visible =
false;
1980 for(std::set<int>::const_iterator iter=addedMarkers.begin();
1981 iter!=addedMarkers.end();
1984 if(posesWithMarkers.find(*iter) == posesWithMarkers.end())
1989 for(std::map<int, rtabmap::Transform>::const_iterator iter=posesWithMarkers.begin();
1990 iter!=posesWithMarkers.end() && iter->first<0;
1993 int id = iter->first;
2016 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
2017 pcl::IndicesPtr indices(
new std::vector<int>);
2027 indices->resize(cloud->size());
2028 for(
unsigned int i=0; i<cloud->size(); ++i)
2034 if(cloud->size() && indices->size())
2036 LOGI(
"Created odom cloud (rgb=%dx%d depth=%dx%d cloud=%dx%d)",
2039 (int)cloud->width, (
int)cloud->height);
2045 UERROR(
"Generated cloud is empty!");
2050 UWARN(
"Odom data images/scans are empty!");
2061 main_scene_.
updateGains(iter->first, iter->second.gains[0], iter->second.gains[1], iter->second.gains[2]);
2064 notifyDataLoaded =
true;
2069 LOGI(
"Bilateral filtering...");
2074 if(iter->second.cloud->size() && iter->second.indices->size())
2082 notifyDataLoaded =
true;
2087 LOGI(
"Polygon filtering...");
2093 if(iter->second.polygons.size())
2100 notifyDataLoaded =
true;
2111 if(rtabmapEvents.size())
2115 if(rtabmapEvents.back()->getStats().refImageId()>0 ||
2116 !rtabmapEvents.back()->getStats().data().empty())
2119 rtabmapEvents.pop_back();
2122 for(std::list<rtabmap::RtabmapEvent*>::iterator iter=rtabmapEvents.begin(); iter!=rtabmapEvents.end(); ++iter)
2126 rtabmapEvents.clear();
2132 UERROR(
"TangoPoseEventNotReceived");
2143 cv::Mat image(h, w, CV_8UC4);
2144 glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, image.data);
2145 cv::flip(image, image, 0);
2146 cv::cvtColor(image, image, cv::COLOR_RGBA2BGRA);
2150 int offset = (w-h)/2;
2155 int offset = (h-w)/2;
2159 LOGI(
"Saving screenshot %dx%d...", roi.cols, roi.rows);
2168 double updateInterval = 1.0;
2178 if(interval >= updateInterval)
2189 return notifyDataLoaded||notifyCameraStarted?1:0;
2193 for(std::list<rtabmap::RtabmapEvent*>::iterator iter=rtabmapEvents.begin(); iter!=rtabmapEvents.end(); ++iter)
2197 rtabmapEvents.clear();
2198 UERROR(
"Exception! msg=\"%s\"", e.what());
2201 catch(
const cv::Exception & e)
2203 for(std::list<rtabmap::RtabmapEvent*>::iterator iter=rtabmapEvents.begin(); iter!=rtabmapEvents.end(); ++iter)
2207 rtabmapEvents.clear();
2208 UERROR(
"Exception! msg=\"%s\"", e.what());
2211 catch(
const std::exception & e)
2213 for(std::list<rtabmap::RtabmapEvent*>::iterator iter=rtabmapEvents.begin(); iter!=rtabmapEvents.end(); ++iter)
2217 rtabmapEvents.clear();
2218 UERROR(
"Exception! msg=\"%s\"", e.what());
2230 float x0,
float y0,
float x1,
float y1) {
2324 std::map<int, rtabmap::Transform> poses;
2325 std::multimap<int, rtabmap::Link> links;
2334 LOGI(
"Send rtabmap event to update graph...");
2485 std::string compatibleKey = key;
2491 if(iter->second.first)
2494 compatibleKey = iter->second.second;
2495 LOGW(
"Parameter name changed: \"%s\" -> \"%s\". Please update the code accordingly. Value \"%s\" is still set to the new parameter name.",
2496 iter->first.c_str(), iter->second.second.c_str(), value.c_str());
2500 if(iter->second.second.empty())
2502 UERROR(
"Parameter \"%s\" doesn't exist anymore!",
2503 iter->first.c_str());
2507 UERROR(
"Parameter \"%s\" doesn't exist anymore! You may look at this similar parameter: \"%s\"",
2508 iter->first.c_str(), iter->second.second.c_str());
2515 LOGI(
"%s",
uFormat(
"Setting param \"%s\" to \"%s\"", compatibleKey.c_str(), value.c_str()).c_str());
2522 UERROR(
uFormat(
"Key \"%s\" doesn't exist!", compatibleKey.c_str()).c_str());
2547 LOGI(
"Saving database to %s", databasePath.c_str());
2551 LOGI(
"Taking screenshot...");
2555 UERROR(
"Failed to take a screenshot after 2 sec!");
2577 if(appendModeBackup || dataRecorderModeBackup || localizationModeBackup)
2599 std::string errorMsg;
2602 LOGE(
"Recovery Error: %s", errorMsg.c_str());
2607 LOGI(
"Renaming %s to %s", from.c_str(), to.c_str());
2610 LOGE(
"Failed renaming %s to %s", from.c_str(), to.c_str());
2619 UWARN(
"Processing canceled!");
2624 float cloudVoxelSize,
2625 bool regenerateCloud,
2631 float optimizedVoxelSize,
2633 int optimizedMaxPolygons,
2634 float optimizedColorRadius,
2635 bool optimizedCleanWhitePolygons,
2636 int optimizedMinClusterSize,
2637 float optimizedMaxTextureDistance,
2638 int optimizedMinTextureClusterSize,
2639 bool blockRendering)
2648 std::multimap<int, rtabmap::Link> links;
2656 UERROR(
"Empty optimized poses!");
2670 bool success =
false;
2675 totalSteps+=poses.size();
2680 totalSteps += poses.size();
2686 if(optimizedMaxPolygons > 0)
2696 totalSteps+=poses.size()+1;
2701 totalSteps += poses.size()+1;
2711 pcl::PolygonMesh::Ptr polygonMesh(
new pcl::PolygonMesh);
2712 pcl::TextureMesh::Ptr textureMesh(
new pcl::TextureMesh);
2713 std::vector<std::map<int, pcl::PointXY> > vertexToPixels;
2714 cv::Mat globalTextures;
2715 int totalPolygons = 0;
2719 std::map<int, rtabmap::Transform> cameraPoses;
2720 std::map<int, rtabmap::CameraModel> cameraModels;
2721 std::map<int, cv::Mat> cameraDepths;
2724 LOGI(
"Assemble clouds (%d)...", (
int)poses.size());
2728 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2729 for(std::map<int, rtabmap::Transform>::iterator iter=poses.begin();
2733 std::map<int, rtabmap::Mesh>::iterator jter =
createdMeshes_.find(iter->first);
2734 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
2735 pcl::IndicesPtr indices(
new std::vector<int>);
2739 gains[0] = gains[1] = gains[2] = 1.0f;
2742 cloud = jter->second.cloud;
2743 indices = jter->second.indices;
2744 model = jter->second.cameraModel;
2745 gains[0] = jter->second.gains[0];
2746 gains[1] = jter->second.gains[1];
2747 gains[2] = jter->second.gains[2];
2766 pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformedCloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
2767 if(optimizedVoxelSize > 0.0
f)
2776 pcl::copyPointCloud(*cloud, *indices, *transformedCloud);
2780 Eigen::Vector3f viewpoint( iter->second.x(), iter->second.y(), iter->second.z());
2783 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudWithNormals(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2784 pcl::concatenateFields(*transformedCloud, *normals, *cloudWithNormals);
2786 if(textureSize == 0 && (gains[0] != 1.0 || gains[1] != 1.0 || gains[2] != 1.0))
2788 for(
unsigned int i=0; i<cloudWithNormals->size(); ++i)
2790 pcl::PointXYZRGBNormal & pt = cloudWithNormals->at(i);
2798 if(mergedClouds->size() == 0)
2800 *mergedClouds = *cloudWithNormals;
2804 *mergedClouds += *cloudWithNormals;
2807 cameraPoses.insert(std::make_pair(iter->first, iter->second));
2808 cameraModels.insert(std::make_pair(iter->first, model));
2811 cameraDepths.insert(std::make_pair(iter->first, depth));
2814 LOGI(
"Assembled %d points (%d/%d total=%d)", (
int)cloudWithNormals->size(), ++cloudCount, (int)poses.size(), (int)mergedClouds->size());
2818 UERROR(
"Cloud %d not found or empty", iter->first);
2832 LOGI(
"Assembled clouds (%d)... done! %fs (total points=%d)", (
int)cameraPoses.size(), timer.
ticks(), (int)mergedClouds->size());
2834 if(mergedClouds->size()>=3)
2836 if(optimizedDepth == 0)
2840 float mapLength =
uMax3(max[0]-min[0], max[1]-min[1], max[2]-min[2]);
2841 optimizedDepth = 12;
2842 for(
int i=6; i<12; ++i)
2844 if(mapLength/
float(1<<i) < 0.03
f)
2850 LOGI(
"optimizedDepth=%d (map length=%f)", optimizedDepth, mapLength);
2854 LOGI(
"Mesh reconstruction...");
2855 pcl::PolygonMesh::Ptr mesh(
new pcl::PolygonMesh);
2856 pcl::Poisson<pcl::PointXYZRGBNormal> poisson;
2857 poisson.setDepth(optimizedDepth);
2858 poisson.setInputCloud(mergedClouds);
2859 poisson.reconstruct(*mesh);
2860 LOGI(
"Mesh reconstruction... done! %fs (%d polygons)", timer.
ticks(), (int)mesh->polygons.size());
2874 if(mesh->polygons.size())
2876 totalPolygons=(int)mesh->polygons.size();
2878 if(optimizedMaxPolygons > 0 && optimizedMaxPolygons < (
int)mesh->polygons.size())
2881 unsigned int count = mesh->polygons.size();
2882 float factor = 1.0f-float(optimizedMaxPolygons)/float(count);
2883 LOGI(
"Mesh decimation (max polygons %d/%d -> factor=%f)...", optimizedMaxPolygons, (
int)count, factor);
2887 pcl::PolygonMesh::Ptr output(
new pcl::PolygonMesh);
2888 pcl::MeshQuadricDecimationVTK mqd;
2889 mqd.setTargetReductionFactor(factor);
2890 mqd.setInputMesh(mesh);
2891 mqd.process (*output);
2899 LOGI(
"Mesh decimated (factor=%f) from %d to %d polygons (%fs)", factor, count, (
int)mesh->polygons.size(), timer.
ticks());
2900 if(count < mesh->polygons.size())
2902 UWARN(
"Decimated mesh has more polygons than before!");
2905 UWARN(
"RTAB-Map is not built with PCL-VTK module so mesh decimation cannot be used!");
2921 rtabmap::util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>(
2926 optimizedColorRadius,
2928 optimizedCleanWhitePolygons,
2929 optimizedMinClusterSize);
2933 LOGI(
"Texturing... cameraPoses=%d, cameraDepths=%d", (
int)cameraPoses.size(), (int)cameraDepths.size());
2939 optimizedMaxTextureDistance,
2942 optimizedMinTextureClusterSize,
2943 std::vector<float>(),
2946 LOGI(
"Texturing... done! %fs", timer.
ticks());
2959 if(textureMesh->tex_coordinates.size() && optimizedCleanWhitePolygons)
2961 LOGI(
"Cleanup mesh...");
2963 LOGI(
"Cleanup mesh... done! %fs", timer.
ticks());
2967 for(
unsigned int t=0; t<textureMesh->tex_polygons.size(); ++t)
2969 totalPolygons+=textureMesh->tex_polygons[t].size();
2974 totalPolygons = (int)mesh->polygons.size();
2981 UERROR(
"Merged cloud too small (%d points) to create polygons!", (
int)mergedClouds->size());
2986 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
2990 textureMesh->tex_materials.resize(poses.size());
2991 textureMesh->tex_polygons.resize(poses.size());
2992 textureMesh->tex_coordinates.resize(poses.size());
2995 int polygonsStep = 0;
2997 for(std::map<int, rtabmap::Transform>::iterator iter=poses.begin();
3001 LOGI(
"Assembling cloud %d (total=%d)...", iter->first, (
int)poses.size());
3003 std::map<int, rtabmap::Mesh>::iterator jter =
createdMeshes_.find(iter->first);
3004 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
3005 std::vector<pcl::Vertices> polygons;
3006 float gains[3] = {1.0f};
3009 cloud = jter->second.cloud;
3010 polygons= jter->second.polygons;
3011 if(cloud->size() && polygons.size() == 0)
3015 gains[0] = jter->second.gains[0];
3016 gains[1] = jter->second.gains[1];
3017 gains[2] = jter->second.gains[2];
3031 if(cloud->size() && polygons.size())
3034 pcl::PointCloud<pcl::PointXYZRGB>::Ptr outputCloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
3035 std::vector<pcl::Vertices> outputPolygons;
3040 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudWithNormals(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3041 pcl::concatenateFields(*outputCloud, *normals, *cloudWithNormals);
3043 UASSERT(outputPolygons.size());
3045 totalPolygons+=outputPolygons.size();
3047 if(textureSize == 0)
3052 if(gains[0] != 1.0
f || gains[1] != 1.0
f || gains[2] != 1.0
f)
3054 for(
unsigned int i=0; i<cloudWithNormals->size(); ++i)
3056 pcl::PointXYZRGBNormal & pt = cloudWithNormals->at(i);
3063 if(mergedClouds->size() == 0)
3065 *mergedClouds = *cloudWithNormals;
3066 polygonMesh->polygons = outputPolygons;
3076 size_t polygonSize = outputPolygons.front().vertices.size();
3077 textureMesh->tex_polygons[oi].resize(outputPolygons.size());
3078 textureMesh->tex_coordinates[oi].resize(outputPolygons.size() * polygonSize);
3079 for(
unsigned int j=0; j<outputPolygons.size(); ++j)
3081 pcl::Vertices
vertices = outputPolygons[j];
3082 UASSERT(polygonSize == vertices.vertices.size());
3083 for(
unsigned int k=0; k<vertices.vertices.size(); ++k)
3086 UASSERT(vertices.vertices[k] < denseToOrganizedIndices.size());
3087 int originalVertex = denseToOrganizedIndices[vertices.vertices[k]];
3088 textureMesh->tex_coordinates[oi][j*vertices.vertices.size()+k] = Eigen::Vector2f(
3089 float(originalVertex % cloud->width) /
float(cloud->width),
3090 float(cloud->height - originalVertex / cloud->width) /
float(cloud->height));
3092 vertices.vertices[k] += polygonsStep;
3094 textureMesh->tex_polygons[oi][j] =
vertices;
3097 polygonsStep += outputCloud->size();
3100 if(mergedClouds->size() == 0)
3102 *mergedClouds = *transformedCloud;
3106 *mergedClouds += *transformedCloud;
3109 textureMesh->tex_materials[oi].tex_illum = 1;
3110 textureMesh->tex_materials[oi].tex_name =
uFormat(
"material_%d", iter->first);
3111 textureMesh->tex_materials[oi].tex_file =
uNumber2Str(iter->first);
3117 UERROR(
"Mesh not found for mesh %d", iter->first);
3131 if(textureSize == 0)
3133 if(mergedClouds->size())
3135 pcl::toPCLPointCloud2(*mergedClouds, polygonMesh->cloud);
3139 polygonMesh->polygons.clear();
3144 textureMesh->tex_materials.resize(oi);
3145 textureMesh->tex_polygons.resize(oi);
3147 if(mergedClouds->size())
3149 pcl::toPCLPointCloud2(*mergedClouds, textureMesh->cloud);
3156 if(textureSize>0 && totalPolygons && textureMesh->tex_materials.size())
3158 LOGI(
"Merging %d textures...", (
int)textureMesh->tex_materials.size());
3161 std::map<int, cv::Mat>(),
3162 std::map<
int, std::vector<rtabmap::CameraModel> >(),
3168 true, 10.0f,
true ,
true, 0, 0, 0,
false,
3170 LOGI(
"Merging %d textures... globalTextures=%dx%d", (
int)textureMesh->tex_materials.size(),
3171 globalTextures.cols, globalTextures.rows);
3187 if(textureSize == 0)
3189 UASSERT((
int)polygonMesh->polygons.size() == totalPolygons);
3190 if(polygonMesh->polygons.size())
3193 pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGBNormal>);
3194 pcl::fromPCLPointCloud2(polygonMesh->cloud, *cloud);
3196 std::vector<std::vector<std::vector<RTABMAP_PCL_INDEX> > > polygons(1);
3197 polygons[0].resize(polygonMesh->polygons.size());
3198 for(
unsigned int p=0; p<polygonMesh->polygons.size(); ++p)
3200 polygons[0][p] = polygonMesh->polygons[p].vertices;
3208 else if(textureMesh->tex_materials.size())
3210 pcl::PointCloud<pcl::PointNormal>::Ptr cloud(
new pcl::PointCloud<pcl::PointNormal>);
3211 pcl::fromPCLPointCloud2(textureMesh->cloud, *cloud);
3215 std::vector<std::vector<std::vector<RTABMAP_PCL_INDEX> > > polygons(textureMesh->tex_polygons.size());
3216 for(
unsigned int t=0; t<textureMesh->tex_polygons.size(); ++t)
3218 polygons[t].resize(textureMesh->tex_polygons[t].size());
3219 for(
unsigned int p=0; p<textureMesh->tex_polygons[t].size(); ++p)
3221 polygons[t][p] = textureMesh->tex_polygons[t][p].vertices;
3230 UERROR(
"Failed exporting texture mesh! There are no textures!");
3235 UERROR(
"Failed exporting mesh! There are no polygons!");
3240 pcl::PointCloud<pcl::PointXYZRGB>::Ptr mergedClouds(
new pcl::PointCloud<pcl::PointXYZRGB>);
3241 for(std::map<int, rtabmap::Transform>::iterator iter=poses.begin();
3245 std::map<int, rtabmap::Mesh>::iterator jter=
createdMeshes_.find(iter->first);
3246 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
3247 pcl::IndicesPtr indices(
new std::vector<int>);
3249 gains[0] = gains[1] = gains[2] = 1.0f;
3254 gains[0] = jter->second.gains[0];
3255 gains[1] = jter->second.gains[1];
3256 gains[2] = jter->second.gains[2];
3269 indices->resize(cloud->size());
3270 for(
unsigned int i=0; i<cloud->size(); ++i)
3280 cloud = jter->second.cloud;
3281 indices = jter->second.indices;
3282 gains[0] = jter->second.gains[0];
3283 gains[1] = jter->second.gains[1];
3284 gains[2] = jter->second.gains[2];
3299 indices->resize(cloud->size());
3300 for(
unsigned int i=0; i<cloud->size(); ++i)
3307 if(cloud->size() && indices->size())
3310 pcl::PointCloud<pcl::PointXYZRGB>::Ptr transformedCloud(
new pcl::PointCloud<pcl::PointXYZRGB>);
3311 if(cloudVoxelSize > 0.0
f)
3320 pcl::copyPointCloud(*cloud, *indices, *transformedCloud);
3324 if(gains[0] != 1.0
f || gains[1] != 1.0
f || gains[2] != 1.0
f)
3327 for(
unsigned int i=0; i<transformedCloud->size(); ++i)
3329 pcl::PointXYZRGB & pt = transformedCloud->at(i);
3338 if(mergedClouds->size() == 0)
3340 *mergedClouds = *transformedCloud;
3344 *mergedClouds += *transformedCloud;
3360 if(mergedClouds->size())
3362 if(cloudVoxelSize > 0.0
f)
3377 UERROR(
"Merged cloud is empty!");
3388 catch (std::exception &
e)
3390 UERROR(
"Out of memory! %s", e.what());
3407 if(success && poses.size())
3420 LOGI(
"postExportation(visualize=%d)", visualize?1:0);
3421 optMesh_.reset(
new pcl::TextureMesh);
3429 std::vector<std::vector<std::vector<RTABMAP_PCL_INDEX> > > polygons;
3430 #if PCL_VERSION_COMPARE(>=, 1, 8, 0) 3431 std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > texCoords;
3433 std::vector<std::vector<Eigen::Vector2f> > texCoords;
3439 if(!cloudMat.empty())
3441 LOGI(
"postExportation: Found optimized mesh! Visualizing it.");
3451 LOGI(
"postExportation: No optimized mesh found.");
3496 LOGI(
"writeExportedMesh: dir=%s name=%s", directory.c_str(), name.c_str());
3499 bool success =
false;
3501 pcl::PolygonMesh::Ptr polygonMesh(
new pcl::PolygonMesh);
3502 pcl::TextureMesh::Ptr textureMesh(
new pcl::TextureMesh);
3504 std::vector<std::vector<std::vector<RTABMAP_PCL_INDEX> > > polygons;
3505 #if PCL_VERSION_COMPARE(>=, 1, 8, 0) 3506 std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > texCoords;
3508 std::vector<std::vector<Eigen::Vector2f> > texCoords;
3514 if(!cloudMat.empty())
3516 LOGI(
"writeExportedMesh: Found optimized mesh!");
3517 if(textures.empty())
3528 LOGI(
"writeExportedMesh: No optimized mesh found.");
3532 if(polygonMesh->cloud.data.size())
3536 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());
3537 success = pcl::io::savePLYFileBinary(filePath, *polygonMesh) == 0;
3540 LOGI(
"Saved ply to %s!", filePath.c_str());
3544 UERROR(
"Failed saving ply to %s!", filePath.c_str());
3547 else if(textureMesh->cloud.data.size())
3550 LOGD(
"Saving texture(s) (%d)", textures.empty()?0:textures.cols/textures.rows);
3551 UASSERT(textures.empty() || textures.cols % textures.rows == 0);
3552 UASSERT((
int)textureMesh->tex_materials.size() == textures.cols/textures.rows);
3553 for(
unsigned int i=0; i<textureMesh->tex_materials.size(); ++i)
3555 std::string baseNameNum = name;
3556 if(textureMesh->tex_materials.size()>1)
3561 textureMesh->tex_materials[i].tex_file = baseNameNum+
".jpg";
3562 LOGI(
"Saving texture to %s.", fullPath.c_str());
3563 success = cv::imwrite(fullPath, textures(
cv::Range::all(), cv::Range(i*textures.rows, (i+1)*textures.rows)));
3566 LOGI(
"Failed saving %s!", fullPath.c_str());
3570 LOGI(
"Saved %s.", fullPath.c_str());
3582 int totalPolygons = 0;
3583 for(
unsigned int i=0;i<textureMesh->tex_polygons.size(); ++i)
3585 totalPolygons += textureMesh->tex_polygons[i].size();
3587 LOGI(
"Saving obj (%d vertices, %d polygons) to %s.", (
int)textureMesh->cloud.data.size()/textureMesh->cloud.point_step, totalPolygons, filePath.c_str());
3588 success = pcl::io::saveOBJFile(filePath, *textureMesh) == 0;
3592 LOGI(
"Saved obj to %s!", filePath.c_str());
3596 UERROR(
"Failed saving obj to %s!", filePath.c_str());
3607 LOGI(
"postProcessing begin(%d)", approach);
3608 int returnedValue = 0;
3611 std::map<int, rtabmap::Transform> poses;
3612 std::multimap<int, rtabmap::Link> links;
3615 if(approach == -1 || approach == 2)
3630 if(returnedValue >=0)
3636 std::map<int, rtabmap::Signature> signatures;
3643 poses = sba->
optimizeBA(poses.rbegin()->first, poses, links, signatures);
3648 UERROR(
"g2o not available!");
3651 else if(approach!=4 && approach!=5 && approach != 7)
3665 LOGI(
"PostProcessing, sending rtabmap event to update graph...");
3670 else if(approach!=4 && approach!=5 && approach != 7)
3675 if(returnedValue >=0)
3679 if(approach == -1 || approach == 4)
3685 if(approach == -1 || approach == 5 || approach == 6)
3699 LOGI(
"postProcessing end(%d) -> %d", approach, returnedValue);
3700 return returnedValue;
3704 float x,
float y,
float z,
float qx,
float qy,
float qz,
float qw,
double stamp)
3709 if(qx==0 && qy==0 && qz==0 && qw==0)
3730 float rgb_fx,
float rgb_fy,
float rgb_cx,
float rgb_cy,
3731 float depth_fx,
float depth_fy,
float depth_cx,
float depth_cy,
3736 const void * yPlane,
const void * uPlane,
const void * vPlane,
int yPlaneLen,
int rgbWidth,
int rgbHeight,
int rgbFormat,
3737 const void * depth,
int depthLen,
int depthWidth,
int depthHeight,
int depthFormat,
3738 const void * conf,
int confLen,
int confWidth,
int confHeight,
int confFormat,
3739 const float * points,
int pointsLen,
int pointsChannels,
3741 float p00,
float p11,
float p02,
float p12,
float p22,
float p32,
float p23,
3742 float t0,
float t1,
float t2,
float t3,
float t4,
float t5,
float t6,
float t7)
3744 #if defined(RTABMAP_ARCORE) || defined(__APPLE__) 3748 if(rgb_fx > 0.0
f && rgb_fy > 0.0
f && rgb_cx > 0.0
f && rgb_cy > 0.0
f && stamp > 0.0
f && yPlane && vPlane && yPlaneLen == rgbWidth*rgbHeight)
3753 #if defined(RTABMAP_ARCORE) 3754 if(rgbFormat == AR_IMAGE_FORMAT_YUV_420_888 &&
3755 (depth==0 || depthFormat == AIMAGE_FORMAT_DEPTH16))
3757 if(rgbFormat == 875704422 &&
3758 (depth==0 ||Â depthFormat == 1717855600))
3765 if((
long)vPlane-(
long)yPlane != yPlaneLen)
3768 cv::Mat yuv(rgbHeight+rgbHeight/2, rgbWidth, CV_8UC1);
3769 memcpy(yuv.data, yPlane, yPlaneLen);
3770 memcpy(yuv.data+yPlaneLen, vPlane, rgbHeight/2*rgbWidth);
3771 cv::cvtColor(yuv, outputRGB, cv::COLOR_YUV2BGR_NV21);
3776 cv::cvtColor(cv::Mat(rgbHeight+rgbHeight/2, rgbWidth, CV_8UC1, (
void*)yPlane), outputRGB, cv::COLOR_YUV2BGR_NV21);
3778 cv::cvtColor(cv::Mat(rgbHeight+rgbHeight/2, rgbWidth, CV_8UC1, (
void*)yPlane), outputRGB, cv::COLOR_YUV2RGB_NV21);
3783 cv::Mat outputDepth;
3784 if(depth && depthHeight>0 && depthWidth>0)
3789 if(depthLen == 4*depthWidth*depthHeight)
3792 outputDepth = cv::Mat(depthHeight, depthWidth, CV_32FC1, (
void*)depth).clone();
3793 if(conf && confWidth == depthWidth && confHeight == depthHeight && confFormat == 1278226488 &&
depthConfidence_>0)
3795 const unsigned char * confPtr = (
const unsigned char *)conf;
3796 float * depthPtr = outputDepth.ptr<
float>();
3798 for (
int y = 0; y < outputDepth.rows; ++y)
3800 for (
int x = 0;
x < outputDepth.cols; ++
x)
3808 depthPtr[y*outputDepth.cols +
x] = 0.0f;
3815 else if(depthLen == 2*depthWidth*depthHeight)
3818 outputDepth = cv::Mat(depthHeight, depthWidth, CV_16UC1);
3820 for (
int y = 0; y < outputDepth.rows; ++y)
3822 for (
int x = 0;
x < outputDepth.cols; ++
x)
3824 uint16_t depthSample = dataShort[y*outputDepth.cols +
x];
3825 uint16_t depthRange = (depthSample & 0x1FFF);
3826 outputDepth.at<
uint16_t>(y,
x) = depthRange;
3832 if(!outputRGB.empty())
3837 if(!outputDepth.empty() && !depthFrame.
isNull() && depth_fx!=0 && (rgbFrame != depthFrame || depthStamp!=stamp))
3848 UWARN(
"Could not find poses to interpolate at time %f (last is %f)...", depthStamp,
poseBuffer_.rbegin()->first);
3852 std::map<double, rtabmap::Transform >::const_iterator iterB =
poseBuffer_.lower_bound(depthStamp);
3853 std::map<double, rtabmap::Transform >::const_iterator iterA = iterB;
3863 if(iterA == iterB && depthStamp == iterA->first)
3865 poseDepth = iterA->second;
3867 else if(depthStamp >= iterA->first && depthStamp <= iterB->first)
3869 poseDepth = iterA->second.
interpolate((depthStamp-iterA->first) / (iterB->first-iterA->first), iterB->second);
3871 else if(depthStamp < iterA->first)
3873 UERROR(
"Could not find poses to interpolate at image time %f (earliest is %f). Are sensors synchronized?", depthStamp, iterA->first);
3877 UERROR(
"Could not find poses to interpolate at image time %f (between %f and %f), Are sensors synchronized?", depthStamp, iterA->first, iterB->first);
3885 motion = pose.
inverse()*poseDepth;
3888 UDEBUG(
"motion=%s", motion.prettyPrint().c_str());
3892 UDEBUG(
"motion=%s", motion.prettyPrint().c_str());
3899 float scale = (float)outputDepth.cols/(
float)outputRGB.cols;
3900 cv::Mat colorK = (cv::Mat_<double>(3,3) <<
3901 rgb_fx*scale, 0, rgb_cx*scale,
3902 0, rgb_fy*scale, rgb_cy*scale,
3904 cv::Mat depthK = (cv::Mat_<double>(3,3) <<
3905 depth_fx, 0, depth_cx,
3906 0, depth_fy, depth_cy,
3921 model = model.scaled(1.0/
double(2));
3924 std::vector<cv::KeyPoint> kpts;
3925 std::vector<cv::Point3f> kpts3;
3927 if(points && pointsLen>0)
3929 cv::Mat pointsMat(1, pointsLen, CV_32FC(pointsChannels), (
void*)points);
3930 if(outputDepth.empty())
3942 if(!outputDepth.empty())
3957 projectionMatrix[0][0] = p00;
3958 projectionMatrix[1][1] = p11;
3959 projectionMatrix[2][0] = p02;
3960 projectionMatrix[2][1] = p12;
3961 projectionMatrix[2][2] = p22;
3962 projectionMatrix[2][3] = p32;
3963 projectionMatrix[3][2] = p23;
3981 UERROR(
"Missing image information! fx=%f fy=%f cx=%f cy=%f stamp=%f yPlane=%d vPlane=%d yPlaneLen=%d rgbWidth=%d rgbHeight=%d",
3982 rgb_fx, rgb_fy, rgb_cx, rgb_cy, stamp, yPlane?1:0, vPlane?1:0, yPlaneLen, rgbWidth, rgbHeight);
3986 UERROR(
"Not built with ARCore or iOS!");
3995 if(event->
getClassName().compare(
"OdometryEvent") == 0)
3997 LOGI(
"Received OdometryEvent!");
4007 LOGI(
"Received RtabmapEvent event! status=%d",
status_.first);
4016 LOGW(
"Received RtabmapEvent event but ignoring it while we are initializing...status=%d",
status_.first);
4031 if(event->
getClassName().compare(
"CameraInfoEvent") == 0)
4036 bool success =
false;
4038 if(jvm && RTABMapActivity)
4041 jint
rs = jvm->AttachCurrentThread(&env,
NULL);
4042 if(rs == JNI_OK && env)
4044 jclass clazz = env->GetObjectClass(RTABMapActivity);
4047 jmethodID methodID = env->GetMethodID(clazz,
"cameraEventCallback",
"(ILjava/lang/String;Ljava/lang/String;)V" );
4050 env->CallVoidMethod(RTABMapActivity, methodID,
4052 env->NewStringUTF(tangoEvent->
key().c_str()),
4053 env->NewStringUTF(tangoEvent->
value().c_str()));
4058 jvm->DetachCurrentThread();
4063 UERROR(
"Failed to call RTABMapActivity::tangoEventCallback");
4067 if(event->
getClassName().compare(
"RtabmapEventInit") == 0)
4071 LOGI(
"Received RtabmapEventInit! Status=%d info=%s", (
int)
status_.first,
status_.second.c_str());
4074 bool success =
false;
4076 if(jvm && RTABMapActivity)
4079 jint
rs = jvm->AttachCurrentThread(&env,
NULL);
4080 if(rs == JNI_OK && env)
4082 jclass clazz = env->GetObjectClass(RTABMapActivity);
4085 jmethodID methodID = env->GetMethodID(clazz,
"rtabmapInitEventCallback",
"(ILjava/lang/String;)V" );
4088 env->CallVoidMethod(RTABMapActivity, methodID,
4090 env->NewStringUTF(
status_.second.c_str()));
4095 jvm->DetachCurrentThread();
4100 std::function<void()> actualCallback = [&](){
4109 UERROR(
"Failed to call RTABMapActivity::rtabmapInitEventsCallback");
4113 if(event->
getClassName().compare(
"PostRenderEvent") == 0)
4115 LOGI(
"Received PostRenderEvent!");
4117 int loopClosureId = 0;
4118 int featuresExtracted = 0;
4121 LOGI(
"Received PostRenderEvent! has getRtabmapEvent");
4127 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kMemoryWorking_memory_size(),
uValue(stats.
data(), rtabmap::Statistics::kMemoryWorking_memory_size(), 0.0f)));
4128 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)));
4129 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kKeypointDictionary_size(),
uValue(stats.
data(), rtabmap::Statistics::kKeypointDictionary_size(), 0.0f)));
4131 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopHighest_hypothesis_id(),
uValue(stats.
data(), rtabmap::Statistics::kLoopHighest_hypothesis_id(), 0.0f)));
4132 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kMemoryDatabase_memory_used(),
uValue(stats.
data(), rtabmap::Statistics::kMemoryDatabase_memory_used(), 0.0f)));
4133 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopVisual_inliers(),
uValue(stats.
data(), rtabmap::Statistics::kLoopVisual_inliers(), 0.0f)));
4134 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopVisual_matches(),
uValue(stats.
data(), rtabmap::Statistics::kLoopVisual_matches(), 0.0f)));
4135 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopRejectedHypothesis(),
uValue(stats.
data(), rtabmap::Statistics::kLoopRejectedHypothesis(), 0.0f)));
4136 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopOptimization_max_error(),
uValue(stats.
data(), rtabmap::Statistics::kLoopOptimization_max_error(), 0.0f)));
4137 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)));
4138 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kMemoryRehearsal_sim(),
uValue(stats.
data(), rtabmap::Statistics::kMemoryRehearsal_sim(), 0.0f)));
4139 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopHighest_hypothesis_value(),
uValue(stats.
data(), rtabmap::Statistics::kLoopHighest_hypothesis_value(), 0.0f)));
4140 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kMemoryDistance_travelled(),
uValue(stats.
data(), rtabmap::Statistics::kMemoryDistance_travelled(), 0.0f)));
4141 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kMemoryFast_movement(),
uValue(stats.
data(), rtabmap::Statistics::kMemoryFast_movement(), 0.0f)));
4142 uInsert(
bufferedStatsData_, std::make_pair<std::string, float>(rtabmap::Statistics::kLoopLandmark_detected(),
uValue(stats.
data(), rtabmap::Statistics::kLoopLandmark_detected(), 0.0f)));
4151 int databaseMemoryUsed = (int)
uValue(
bufferedStatsData_, rtabmap::Statistics::kMemoryDatabase_memory_used(), 0.0f);
4156 float optimizationMaxErrorRatio =
uValue(
bufferedStatsData_, rtabmap::Statistics::kLoopOptimization_max_error_ratio(), 0.0
f);
4164 if(!currentPose.
isNull())
4170 UINFO(
"Send statistics to GUI");
4171 bool success =
false;
4173 if(jvm && RTABMapActivity)
4176 jint
rs = jvm->AttachCurrentThread(&env,
NULL);
4177 if(rs == JNI_OK && env)
4179 jclass clazz = env->GetObjectClass(RTABMapActivity);
4182 jmethodID methodID = env->GetMethodID(clazz,
"updateStatsCallback",
"(IIIIFIIIIIIFIFIFFFFIIFFFFFF)V" );
4185 env->CallVoidMethod(RTABMapActivity, methodID,
4202 optimizationMaxError,
4203 optimizationMaxErrorRatio,
4217 jvm->DetachCurrentThread();
4222 std::function<void()> actualCallback = [&](){
4240 optimizationMaxError,
4241 optimizationMaxErrorRatio,
4258 UERROR(
"Failed to call RTABMapActivity::updateStatsCallback");
void save(const std::string &databasePath)
void setLocalTransform(const Transform &transform)
void(* swiftInitCallback)(void *, int, const char *)
glm::mat4 glmFromTransform(const rtabmap::Transform &transform)
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)
void OnTouchEvent(int touch_count, tango_gl::GestureCamera::TouchEvent event, float x0, float y0, float x1, float y1)
static const std::map< std::string, std::pair< bool, std::string > > & getRemovedParameters()
void setCameraColor(bool enabled)
void saveOptimizedMesh(const cv::Mat &cloud, const std::vector< std::vector< std::vector< RTABMAP_PCL_INDEX > > > &polygons=std::vector< std::vector< std::vector< RTABMAP_PCL_INDEX > > >(), const std::vector< std::vector< Eigen::Vector2f > > &texCoords=std::vector< std::vector< Eigen::Vector2f > >(), const cv::Mat &textures=cv::Mat()) const
void setMaxGainRadius(float value)
void setWireframe(bool enabled)
void addMesh(int id, const rtabmap::Mesh &mesh, const rtabmap::Transform &pose, bool createWireframe=false)
rtabmap::CameraModel cameraModel
std::vector< Eigen::Vector2f > texCoords
void setAppendMode(bool enabled)
void setGridVisible(bool visible)
const Transform & getOriginOffset() const
bool isBuiltWith(int cameraDriver) 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)
rtabmap::LogHandler * logHandler_
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)
CameraModel scaled(double scale) const
int setMappingParameter(const std::string &key, const std::string &value)
void SetViewPort(int width, int height)
void addEnvSensor(int type, float value)
void SetupViewPort(int w, int h)
double lastPoseEventTime_
void setSmoothing(bool enabled)
bool hasMarker(int id) const
std::set< int > getAddedMarkers() const
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)
void RTABMAP_EXP getMinMax3D(const cv::Mat &laserScan, cv::Point3f &min, cv::Point3f &max)
int lastDrawnCloudsCount_
pcl::PointCloud< pcl::PointXYZRGB >::Ptr cloud
const LaserScan & laserScanCompressed() const
void setGraphOptimization(bool enabled)
const Signature * getLastWorkingSignature() const
const Statistics & getStatistics() const
int getViewPortWidth() const
bool hasTexture(int id) const
static LaserScan scanFromPointCloudData(const cv::Mat &pointCloudData, int points, const Transform &pose, const CameraModel &model, const cv::Mat &rgb, std::vector< cv::KeyPoint > *kpts=0, std::vector< cv::Point3f > *kpts3D=0, int kptsSize=3)
void setGridColor(float r, float g, float b)
ScreenRotation GetAndroidRotationFromColorCameraToDisplay(ScreenRotation display_rotation, int color_camera_rotation)
void setWireframe(bool enabled)
std::pair< std::string, std::string > ParametersPair
bool uvsInitialized() const
void setGraphVisible(bool visible)
int Render(const float *uvsTransformed=0, glm::mat4 arViewMatrix=glm::mat4(0), glm::mat4 arProjectionMatrix=glm::mat4(0), const rtabmap::Mesh &occlusionMesh=rtabmap::Mesh(), bool mapping=false)
static std::string separator()
rtabmap::ParametersMap getRtabmapParameters()
std::set< int > getAddedClouds() const
void setDepthFromMotion(bool enabled)
static int erase(const std::string &filePath)
void setBackfaceCulling(bool enabled)
GLM_FUNC_DECL genType e()
bool isMeshRendering() const
float UTILITE_EXP uStr2Float(const std::string &str)
GLM_FUNC_DECL bool all(vecType< bool, P > const &v)
static const float vertices[]
static const rtabmap::Transform rtabmap_world_T_opengl_world(0.0f, 0.0f,-1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f)
const cv::Mat & data() const
void postOdometryEvent(rtabmap::Transform pose, float rgb_fx, float rgb_fy, float rgb_cx, float rgb_cy, float depth_fx, float depth_fy, float depth_cx, float depth_cy, const rtabmap::Transform &rgbFrame, const rtabmap::Transform &depthFrame, double stamp, double depthStamp, const void *yPlane, const void *uPlane, const void *vPlane, int yPlaneLen, int rgbWidth, int rgbHeight, int rgbFormat, const void *depth, int depthLen, int depthWidth, int depthHeight, int depthFormat, const void *conf, int confLen, int confWidth, int confHeight, int confFormat, const float *points, int pointsLen, int pointsChannels, const rtabmap::Transform &viewMatrix, float p00, float p11, float p02, float p12, float p22, float p32, float p23, float t0, float t1, float t2, float t3, float t4, float t5, float t6, float t7)
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)
void setScreenRotation(rtabmap::ScreenRotation colorCameraToDisplayRotation)
bool isMapRendering() const
void init(const ParametersMap ¶meters, const std::string &databasePath="", bool loadDatabaseParameters=false)
GLM_FUNC_DECL T angle(detail::tquat< T, P > const &x)
const std::map< int, VisualWord * > & getVisualWords() const
std::map< std::string, float > bufferedStatsData_
int getViewPortHeight() const
void setConstraints(const std::multimap< int, Link > &constraints)
BackgroundRenderer * background_renderer_
Some conversion functions.
pcl::TextureMesh::Ptr RTABMAP_EXP assembleTextureMesh(const cv::Mat &cloudMat, const std::vector< std::vector< std::vector< RTABMAP_PCL_INDEX > > > &polygons, const std::vector< std::vector< Eigen::Vector2f > > &texCoords, cv::Mat &textures, bool mergeTextures=false)
cv::Mat RTABMAP_EXP registerDepth(const cv::Mat &depth, const cv::Mat &depthK, const cv::Size &colorSize, const cv::Mat &colorK, const rtabmap::Transform &transform)
bool acquire(int n=1, int ms=0)
std::map< double, rtabmap::Transform > poseBuffer_
std::list< rtabmap::RtabmapEvent * > rtabmapEvents_
GLM_FUNC_DECL T pitch(detail::tquat< T, P > const &x)
void setCloudDensityLevel(int value)
void poseReceived(const Transform &pose)
virtual std::map< int, Transform > optimizeBA(int rootId, const std::map< int, Transform > &poses, const std::multimap< int, Link > &links, const std::map< int, std::vector< CameraModel > > &models, std::map< int, cv::Point3f > &points3DMap, const std::map< int, std::map< int, FeatureBA > > &wordReferences, std::set< int > *outliers=0)
void post(UEvent *event, bool async=true) const
void InitializeGLContent()
int postProcessing(int approach)
static Transform opticalRotation()
std::vector< pcl::Vertices > polygons
static bool isAvailable(Optimizer::Type type)
pcl::TextureMesh::Ptr optMesh_
void setRenderingTextureDecimation(int value)
void setMeshRendering(bool enabled, bool withTexture)
void removeMarker(int id)
const std::map< int, Transform > & poses() const
void setClusterRatio(float value)
void setOrthoCropFactor(float value)
pcl::PointCloud< pcl::PointXYZ >::Ptr RTABMAP_EXP cloudFromDepth(const cv::Mat &imageDepth, const CameraModel &model, int decimation=1, float maxDepth=0.0f, float minDepth=0.0f, std::vector< int > *validIndices=0)
const std::map< std::string, float > & data() const
void setLighting(bool enabled)
int loopClosureId() const
void setOrthoCropFactor(float value)
bool openConnection(const std::string &url, bool overwritten=false)
int openDatabase(const std::string &databasePath, bool databaseInMemory, bool optimize, bool clearDatabase)
#define UASSERT(condition)
void setGPS(const rtabmap::GPS &gps)
Wrappers of STL for convenient functions.
void updateGains(int id, float gainR, float gainG, float gainB)
pcl::PointCloud< pcl::PointXYZRGB >::Ptr RTABMAP_EXP laserScanToPointCloudRGB(const LaserScan &laserScan, const Transform &transform=Transform(), unsigned char r=100, unsigned char g=100, unsigned char b=100)
rtabmap::Transform GetCameraPose() const
const std::vector< CameraModel > & cameraModels() const
std::list< std::list< int > > RTABMAP_EXP clusterPolygons(const std::vector< std::set< int > > &neighborPolygons, int minClusterSize=0)
LaserScan RTABMAP_EXP commonFiltering(const LaserScan &scan, int downsamplingStep, float rangeMin=0.0f, float rangeMax=0.0f, float voxelSize=0.0f, int normalK=0, float normalRadius=0.0f, float groundNormalsUp=0.0f)
pcl::PolygonMesh::Ptr RTABMAP_EXP meshDecimation(const pcl::PolygonMesh::Ptr &mesh, float factor)
static const rtabmap::Transform optical_T_opengl(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f)
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="")
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)
int detectMoreLoopClosures(float clusterRadiusMax=0.5f, float clusterAngle=M_PI/6.0f, int iterations=1, bool intraSession=true, bool interSession=true, const ProgressState *state=0, float clusterRadiusMin=0.0f)
boost::mutex rtabmapMutex_
virtual std::string getClassName() const =0
void SetCameraPose(const rtabmap::Transform &pose)
const cv::Mat & imageRaw() const
cv::Mat RTABMAP_EXP decimate(const cv::Mat &image, int d)
bool clearSceneOnNextRender_
const Memory * getMemory() const
pcl::PointCloud< pcl::Normal >::Ptr normals
void setMapRendering(bool enabled)
const Transform & mapCorrection() 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)
const Transform & localTransform() const
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)
LaserScan laserScanFromPointCloud(const PointCloud2T &cloud, bool filterNaNs, bool is2D, const Transform &transform)
void InitializeGlContent(GLuint textureId, bool oes)
void setBackfaceCulling(bool enabled)
void setPointSize(float size)
void setRawScanSaved(bool enabled)
void SetCameraType(tango_gl::GestureCamera::CameraType camera_type)
const std::multimap< int, Link > & getLocalConstraints() const
cv::Mat RTABMAP_EXP compressData2(const cv::Mat &data)
virtual void setScreenRotationAndSize(ScreenRotation colorCameraToDisplayRotation, int width, int height)
const std::map< int, Transform > & getLocalOptimizedPoses() 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))
float meshDecimationFactor_
virtual bool init(const std::string &calibrationFolder=".", const std::string &cameraName="")
bool hasCloud(int id) const
int gainCompensationOnNextRender_
void setupSwiftCallbacks(void *classPtr, void(*progressCallback)(void *, int, int), void(*initCallback)(void *, int, const char *), void(*statsUpdatedCallback)(void *, int, int, int, int, float, int, int, int, int, int, int, float, int, float, int, float, float, float, float, int, int, float, float, float, float, float, float))
bool uContains(const std::list< V > &list, const V &value)
bool postExportation(bool visualize)
SensorData getNodeData(int locationId, bool images, bool scan, bool userData, bool occupancyGrid) const
int getDatabaseMemoryUsed() const
void addMarker(int id, const rtabmap::Transform &pose)
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)
void setNodesFiltering(bool enabled)
boost::mutex meshesMutex_
const Transform & getDeviceTColorCamera() const
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, unsigned char blankValue=255, std::map< int, std::map< int, cv::Vec4d > > *gains=0, std::map< int, std::map< int, cv::Mat > > *blendingGains=0, std::pair< float, float > *contrastValues=0)
double lastPostRenderEventTime_
void registerToEventsManager()
void setMapCloudShown(bool shown)
void setSwiftCallback(void *classPtr, void(*callback)(void *, int, int))
void setFrustumVisible(bool visible)
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, bool distanceToCamPolicy=false)
static const ParametersMap & getDefaultParameters()
bool recover(const std::string &from, const std::string &to)
rtabmap::RtabmapThread * rtabmapThread_
boost::mutex cameraMutex_
void setDetectorRate(float rate)
void setMeshDecimationFactor(float value)
const LaserScan & laserScanRaw() const
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
SensorData & sensorData()
void RTABMAP_EXP cleanTextureMesh(pcl::TextureMesh &textureMesh, int minClusterSize)
int updateMeshDecimation(int width, int height)
void setMinCloudDepth(float value)
bool RTABMAP_EXP databaseRecovery(const std::string &corruptedDatabase, bool keepCorruptedDatabase=true, std::string *errorMsg=0, ProgressState *progressState=0)
void setTraceVisible(bool visible)
void SetCameraType(tango_gl::GestureCamera::CameraType camera_type)
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_
float getDetectorRate() const
const Transform & getPose() 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)
const Signature & getLastSignatureData() const
bool exportedMeshUpdated_
void close(bool databaseSaved, const std::string &databasePath="")
void getGraph(std::map< int, Transform > &poses, std::multimap< int, Link > &constraints, bool optimized, bool global, std::map< int, Signature > *signatures=0, bool withImages=false, bool withScan=false, bool withUserData=false, bool withGrid=false, bool withWords=true, bool withGlobalDescriptors=true) const
std::map< int, rtabmap::Mesh > createdMeshes_
cv::Mat loadOptimizedMesh(std::vector< std::vector< std::vector< RTABMAP_PCL_INDEX > > > *polygons=0, std::vector< std::vector< Eigen::Vector2f > > *texCoords=0, cv::Mat *textures=0) const
void gainCompensation(bool full=false)
void updateMesh(int id, const rtabmap::Mesh &mesh)
void setDataRecorderMode(bool enabled)
GLM_FUNC_DECL T yaw(detail::tquat< T, P > const &x)
std::vector< pcl::Vertices > filterPolygons(const std::vector< pcl::Vertices > &polygons, int cloudSize) const
void setOcclusionImage(const cv::Mat &image, const CameraModel &model)
void setGraphVisible(bool visible)
bool writeExportedMesh(const std::string &directory, const std::string &name)
bool cameraJustInitialized_
boost::mutex renderingMutex_
bool hasMesh(int id) const
const rtabmap::RtabmapEvent * getRtabmapEvent() const
static int rename(const std::string &oldFilePath, const std::string &newFilePath)
void savePreviewImage(const cv::Mat &image) const
void setDepthConfidence(int value)
void setMarkerPose(int id, const rtabmap::Transform &pose)
void setMeshTriangleSize(int value)
cv::Mat loadOptimizedMesh(std::vector< std::vector< std::vector< RTABMAP_PCL_INDEX > > > *polygons=0, std::vector< std::vector< Eigen::Vector2f > > *texCoords=0, cv::Mat *textures=0) const
void unregisterFromEventsManager()
void setGridVisible(bool visible)
bool isMeshTexturing() const
int proximityDetectionId() 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)
tango_gl::GestureCamera::CameraType GetCameraType() const
void postCameraPoseEvent(float x, float y, float z, float qx, float qy, float qz, float qw, double stamp)
float meshAngleToleranceDeg_
std::list< rtabmap::Transform > poseEvents_
bool smoothMesh(int id, rtabmap::Mesh &mesh)
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)
rtabmap::ScreenRotation getScreenRotation() const
std::list< rtabmap::OdometryEvent > odomEvents_
void addEnvSensor(int type, float value)
const VWDictionary * getVWDictionary() const
void(* swiftStatsUpdatedCallback)(void *, int, int, int, int, float, int, int, int, int, int, int, float, int, float, int, float, float, float, float, int, int, float, float, float, float, float, float)
void increment(int count=1) const
void setScreenRotation(int displayRotation, int cameraRotation)
const Transform & pose() const
std::string UTILITE_EXP uFormat(const char *fmt,...)
std::vector< pcl::Vertices > filterOrganizedPolygons(const std::vector< pcl::Vertices > &polygons, int cloudSize) const
rtabmap::Rtabmap * rtabmap_
std::string UTILITE_EXP uNumber2Str(unsigned int number)
const std::string & value() const
bool bilateralFilteringOnNextRender_
rtabmap::ParametersMap mappingParameters_
rtabmap::ProgressionStatus progressionStatus_
bool isValidForProjection() const
void setLighting(bool enabled)
rtabmap::CameraMobile * camera_
Transform localTransform() const
rtabmap::Transform * optRefPose_
static Optimizer * create(const ParametersMap ¶meters)
V uValue(const std::map< K, V > &m, const K &key, const V &defaultValue=V())
void setOptimizedPoses(const std::map< int, Transform > &poses, const std::multimap< int, Link > &constraints)
void setFeatures(const std::vector< cv::KeyPoint > &keypoints, const std::vector< cv::Point3f > &keypoints3D, const cv::Mat &descriptors)
void setData(const SensorData &data, const Transform &pose, const glm::mat4 &viewMatrix, const glm::mat4 &projectionMatrix, const float *texCoord)
void setGPS(const GPS &gps)
pcl::PolygonMesh::Ptr RTABMAP_EXP assemblePolygonMesh(const cv::Mat &cloudMat, const std::vector< std::vector< RTABMAP_PCL_INDEX > > &polygons)
cv::Mat getImageCompressed(int signatureId) const
PostRenderEvent(rtabmap::RtabmapEvent *event=0)
double getGain(int id, double *r=0, double *g=0, double *b=0) const
void setPausedMapping(bool paused)
cv::Mat RTABMAP_EXP uncompressImage(const cv::Mat &bytes)
const std::string & key() const
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)
virtual std::string getClassName() const
void setLocalizationMode(bool enabled)
const std::multimap< int, int > & getWords() const
GLM_FUNC_DECL matType< T, P > inverse(matType< T, P > const &m)
void setCanceled(bool canceled)