mirror of
https://github.com/introlab/rtabmap_ros.git
synced 2026-10-03 16:27:46 +08:00
MainWindow: added timing stats on global map creation. Updated util3d::occupancy2DFromLaserScan() and util3d::create2DMap() interfaces (hit/noHit scans in opencv matrix format). Parameter default: Grid/ProjRayTracing=true, Grid/NormalK=true
This commit is contained in:
@@ -490,7 +490,7 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(Grid, MinGroundHeight, float, 0.0, "Minimum ground height (0=disabled).");
|
RTABMAP_PARAM(Grid, MinGroundHeight, float, 0.0, "Minimum ground height (0=disabled).");
|
||||||
RTABMAP_PARAM(Grid, MaxGroundHeight, float, 0.0, uFormat("Maximum ground height (0=disabled). Should be set if \"%s\" is true.", kGridNormalsSegmentation().c_str()));
|
RTABMAP_PARAM(Grid, MaxGroundHeight, float, 0.0, uFormat("Maximum ground height (0=disabled). Should be set if \"%s\" is true.", kGridNormalsSegmentation().c_str()));
|
||||||
RTABMAP_PARAM(Grid, MaxGroundAngle, float, 45, uFormat("[%s=true] Maximum angle (degrees) between point's normal to ground's normal to label it as ground. Points with higher angle difference are considered as obstacles.", kGridNormalsSegmentation().c_str()));
|
RTABMAP_PARAM(Grid, MaxGroundAngle, float, 45, uFormat("[%s=true] Maximum angle (degrees) between point's normal to ground's normal to label it as ground. Points with higher angle difference are considered as obstacles.", kGridNormalsSegmentation().c_str()));
|
||||||
RTABMAP_PARAM(Grid, NormalK, int, 10, uFormat("[%s=true] K neighbors to compute normals.", kGridNormalsSegmentation().c_str()));
|
RTABMAP_PARAM(Grid, NormalK, int, 20, uFormat("[%s=true] K neighbors to compute normals.", kGridNormalsSegmentation().c_str()));
|
||||||
RTABMAP_PARAM(Grid, ClusterRadius, float, 0.1, uFormat("[%s=true] Cluster maximum radius.", kGridNormalsSegmentation().c_str()));
|
RTABMAP_PARAM(Grid, ClusterRadius, float, 0.1, uFormat("[%s=true] Cluster maximum radius.", kGridNormalsSegmentation().c_str()));
|
||||||
RTABMAP_PARAM(Grid, MinClusterSize, int, 10, uFormat("[%s=true] Minimum cluster size to project the points.", kGridNormalsSegmentation().c_str()));
|
RTABMAP_PARAM(Grid, MinClusterSize, int, 10, uFormat("[%s=true] Minimum cluster size to project the points.", kGridNormalsSegmentation().c_str()));
|
||||||
RTABMAP_PARAM(Grid, FlatObstacleDetected, bool, true, uFormat("[%s=true] Flat obstacles detected.", kGridNormalsSegmentation().c_str()));
|
RTABMAP_PARAM(Grid, FlatObstacleDetected, bool, true, uFormat("[%s=true] Flat obstacles detected.", kGridNormalsSegmentation().c_str()));
|
||||||
@@ -504,7 +504,7 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(Grid, NoiseFilteringMinNeighbors, int, 5, "Noise filtering minimum neighbors.");
|
RTABMAP_PARAM(Grid, NoiseFilteringMinNeighbors, int, 5, "Noise filtering minimum neighbors.");
|
||||||
RTABMAP_PARAM(Grid, Scan2dUnknownSpaceFilled, bool, false, "Unknown space filled. Only used with 2D laser scans.");
|
RTABMAP_PARAM(Grid, Scan2dUnknownSpaceFilled, bool, false, "Unknown space filled. Only used with 2D laser scans.");
|
||||||
RTABMAP_PARAM(Grid, Scan2dMaxFilledRange, float, 4.0, "Unknown space filled maximum range. If 0, the laser scan maximum range is used.");
|
RTABMAP_PARAM(Grid, Scan2dMaxFilledRange, float, 4.0, "Unknown space filled maximum range. If 0, the laser scan maximum range is used.");
|
||||||
RTABMAP_PARAM(Grid, ProjRayTracing, bool, false, uFormat("[%s=false] 2D ray tracing is done for each projected obstacle, filling unknown space between the sensor and obstacles.", kGrid3D().c_str()));
|
RTABMAP_PARAM(Grid, ProjRayTracing, bool, true, uFormat("[%s=false] 2D ray tracing is done for each projected obstacle, filling unknown space between the sensor and obstacles.", kGrid3D().c_str()));
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~Parameters();
|
virtual ~Parameters();
|
||||||
|
|||||||
@@ -213,6 +213,8 @@ pcl::PointNormal RTABMAP_EXP laserScanToPointNormal(const cv::Mat & laserScan, i
|
|||||||
// For laserScan of type CV_32FC2, CV_32FC3 and CV_32FC6, rgb is set to default r,g,b parameters.
|
// For laserScan of type CV_32FC2, CV_32FC3 and CV_32FC6, rgb is set to default r,g,b parameters.
|
||||||
pcl::PointXYZRGB RTABMAP_EXP laserScanToPointRGB(const cv::Mat & laserScan, int index, unsigned char r = 255, unsigned char g = 255, unsigned char b = 255);
|
pcl::PointXYZRGB RTABMAP_EXP laserScanToPointRGB(const cv::Mat & laserScan, int index, unsigned char r = 255, unsigned char g = 255, unsigned char b = 255);
|
||||||
|
|
||||||
|
void RTABMAP_EXP getMinMax3D(const cv::Mat & laserScan, cv::Point3f & min, cv::Point3f & max);
|
||||||
|
void RTABMAP_EXP getMinMax3D(const cv::Mat & laserScan, pcl::PointXYZ & min, pcl::PointXYZ & max);
|
||||||
|
|
||||||
cv::Point3f RTABMAP_EXP projectDisparityTo3D(
|
cv::Point3f RTABMAP_EXP projectDisparityTo3D(
|
||||||
const cv::Point2f & pt,
|
const cv::Point2f & pt,
|
||||||
|
|||||||
@@ -51,13 +51,23 @@ RTABMAP_DEPRECATED(void RTABMAP_EXP occupancy2DFromLaserScan(
|
|||||||
bool unknownSpaceFilled = false,
|
bool unknownSpaceFilled = false,
|
||||||
float scanMaxRange = 0.0f), "Use interface with \"viewpoint\" parameter to make sure the ray tracing origin is from the sensor and not the base.");
|
float scanMaxRange = 0.0f), "Use interface with \"viewpoint\" parameter to make sure the ray tracing origin is from the sensor and not the base.");
|
||||||
|
|
||||||
void RTABMAP_EXP occupancy2DFromLaserScan(
|
RTABMAP_DEPRECATED(void RTABMAP_EXP occupancy2DFromLaserScan(
|
||||||
const cv::Mat & scan, // in /base_link frame
|
const cv::Mat & scan, // in /base_link frame
|
||||||
const cv::Point3f & viewpoint, // /base_link -> /base_scan
|
const cv::Point3f & viewpoint, // /base_link -> /base_scan
|
||||||
cv::Mat & ground,
|
cv::Mat & ground,
|
||||||
cv::Mat & obstacles,
|
cv::Mat & obstacles,
|
||||||
float cellSize,
|
float cellSize,
|
||||||
bool unknownSpaceFilled = false,
|
bool unknownSpaceFilled = false,
|
||||||
|
float scanMaxRange = 0.0f), "Use interface with scanHit/scanNoHit parameters: scanNoHit set to null matrix has the same functionality than this method.");
|
||||||
|
|
||||||
|
void RTABMAP_EXP occupancy2DFromLaserScan(
|
||||||
|
const cv::Mat & scanHit, // in /base_link frame
|
||||||
|
const cv::Mat & scanNoHit, // in /base_link frame
|
||||||
|
const cv::Point3f & viewpoint, // /base_link -> /base_scan
|
||||||
|
cv::Mat & ground,
|
||||||
|
cv::Mat & obstacles,
|
||||||
|
float cellSize,
|
||||||
|
bool unknownSpaceFilled = false,
|
||||||
float scanMaxRange = 0.0f); // would be set if unknownSpaceFilled=true
|
float scanMaxRange = 0.0f); // would be set if unknownSpaceFilled=true
|
||||||
|
|
||||||
cv::Mat RTABMAP_EXP create2DMapFromOccupancyLocalMaps(
|
cv::Mat RTABMAP_EXP create2DMapFromOccupancyLocalMaps(
|
||||||
@@ -79,7 +89,7 @@ RTABMAP_DEPRECATED(cv::Mat RTABMAP_EXP create2DMap(const std::map<int, Transform
|
|||||||
float minMapSize = 0.0f,
|
float minMapSize = 0.0f,
|
||||||
float scanMaxRange = 0.0f), "Use interface with \"viewpoints\" parameter to make sure the ray tracing origin is from the sensor and not the base.");
|
float scanMaxRange = 0.0f), "Use interface with \"viewpoints\" parameter to make sure the ray tracing origin is from the sensor and not the base.");
|
||||||
|
|
||||||
cv::Mat RTABMAP_EXP create2DMap(const std::map<int, Transform> & poses,
|
RTABMAP_DEPRECATED(cv::Mat RTABMAP_EXP create2DMap(const std::map<int, Transform> & poses,
|
||||||
const std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans, // in /base_link frame
|
const std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans, // in /base_link frame
|
||||||
const std::map<int, cv::Point3f > & viewpoints, // /base_link -> /base_scan
|
const std::map<int, cv::Point3f > & viewpoints, // /base_link -> /base_scan
|
||||||
float cellSize,
|
float cellSize,
|
||||||
@@ -87,6 +97,16 @@ cv::Mat RTABMAP_EXP create2DMap(const std::map<int, Transform> & poses,
|
|||||||
float & xMin,
|
float & xMin,
|
||||||
float & yMin,
|
float & yMin,
|
||||||
float minMapSize = 0.0f,
|
float minMapSize = 0.0f,
|
||||||
|
float scanMaxRange = 0.0f), "Use interface with cv::Mat scans.");
|
||||||
|
|
||||||
|
cv::Mat RTABMAP_EXP create2DMap(const std::map<int, Transform> & poses,
|
||||||
|
const std::map<int, std::pair<cv::Mat, cv::Mat> > & scans, // <id, <hit, no hit> >, in /base_link frame
|
||||||
|
const std::map<int, cv::Point3f > & viewpoints, // /base_link -> /base_scan
|
||||||
|
float cellSize,
|
||||||
|
bool unknownSpaceFilled,
|
||||||
|
float & xMin,
|
||||||
|
float & yMin,
|
||||||
|
float minMapSize = 0.0f,
|
||||||
float scanMaxRange = 0.0f); // would be set if unknownSpaceFilled=true
|
float scanMaxRange = 0.0f); // would be set if unknownSpaceFilled=true
|
||||||
|
|
||||||
void RTABMAP_EXP rayTrace(const cv::Point2i & start,
|
void RTABMAP_EXP rayTrace(const cv::Point2i & start,
|
||||||
|
|||||||
@@ -208,6 +208,7 @@ void OccupancyGrid::createLocalMap(
|
|||||||
|
|
||||||
util3d::occupancy2DFromLaserScan(
|
util3d::occupancy2DFromLaserScan(
|
||||||
util3d::transformLaserScan(node.sensorData().laserScanRaw(), node.sensorData().laserScanInfo().localTransform()),
|
util3d::transformLaserScan(node.sensorData().laserScanRaw(), node.sensorData().laserScanInfo().localTransform()),
|
||||||
|
cv::Mat(),
|
||||||
viewPoint,
|
viewPoint,
|
||||||
ground,
|
ground,
|
||||||
obstacles,
|
obstacles,
|
||||||
@@ -345,9 +346,12 @@ void OccupancyGrid::createLocalMap(
|
|||||||
if(projRayTracing_)
|
if(projRayTracing_)
|
||||||
{
|
{
|
||||||
cv::Mat laserScan = obstacles;
|
cv::Mat laserScan = obstacles;
|
||||||
|
cv::Mat laserScanNoHit = ground;
|
||||||
obstacles = cv::Mat();
|
obstacles = cv::Mat();
|
||||||
|
ground = cv::Mat();
|
||||||
util3d::occupancy2DFromLaserScan(
|
util3d::occupancy2DFromLaserScan(
|
||||||
laserScan,
|
laserScan,
|
||||||
|
laserScanNoHit,
|
||||||
viewPoint,
|
viewPoint,
|
||||||
ground,
|
ground,
|
||||||
obstacles,
|
obstacles,
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ void OctoMap::update(const std::map<int, Transform> & poses)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UWARN("Updated pose for node %d is not found, some points may not be copied.", jter->first);
|
UWARN("Updated pose for node %d is not found, some points may not be copied. Use negative ids to just update cell values without adding new ones.", jter->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(graphChanged)
|
if(graphChanged)
|
||||||
|
|||||||
@@ -1424,6 +1424,44 @@ pcl::PointXYZRGB laserScanToPointRGB(const cv::Mat & laserScan, int index, unsig
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void getMinMax3D(const cv::Mat & laserScan, cv::Point3f & min, cv::Point3f & max)
|
||||||
|
{
|
||||||
|
UASSERT(!laserScan.empty());
|
||||||
|
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6));
|
||||||
|
|
||||||
|
const float * ptr = laserScan.ptr<float>(0, 0);
|
||||||
|
min.x = max.x = ptr[0];
|
||||||
|
min.y = max.y = ptr[1];
|
||||||
|
min.z = max.z = laserScan.channels() >= 3?ptr[2]:0.0f;
|
||||||
|
for(int i=1; i<laserScan.cols; ++i)
|
||||||
|
{
|
||||||
|
ptr = laserScan.ptr<float>(0, i);
|
||||||
|
|
||||||
|
if(ptr[0] < min.x) min.x = ptr[0];
|
||||||
|
else if(ptr[0] > max.x) max.x = ptr[0];
|
||||||
|
|
||||||
|
if(ptr[1] < min.y) min.y = ptr[1];
|
||||||
|
else if(ptr[1] > max.y) max.y = ptr[1];
|
||||||
|
|
||||||
|
if(laserScan.channels() >= 3)
|
||||||
|
{
|
||||||
|
if(ptr[2] < min.z) min.z = ptr[2];
|
||||||
|
else if(ptr[2] > max.z) max.z = ptr[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void getMinMax3D(const cv::Mat & laserScan, pcl::PointXYZ & min, pcl::PointXYZ & max)
|
||||||
|
{
|
||||||
|
cv::Point3f minCV, maxCV;
|
||||||
|
getMinMax3D(laserScan, minCV, maxCV);
|
||||||
|
min.x = minCV.x;
|
||||||
|
min.y = minCV.y;
|
||||||
|
min.z = minCV.z;
|
||||||
|
max.x = maxCV.x;
|
||||||
|
max.y = maxCV.y;
|
||||||
|
max.z = maxCV.z;
|
||||||
|
}
|
||||||
|
|
||||||
// inspired from ROS image_geometry/src/stereo_camera_model.cpp
|
// inspired from ROS image_geometry/src/stereo_camera_model.cpp
|
||||||
cv::Point3f projectDisparityTo3D(
|
cv::Point3f projectDisparityTo3D(
|
||||||
const cv::Point2f & pt,
|
const cv::Point2f & pt,
|
||||||
|
|||||||
+111
-63
@@ -74,7 +74,20 @@ void occupancy2DFromLaserScan(
|
|||||||
bool unknownSpaceFilled,
|
bool unknownSpaceFilled,
|
||||||
float scanMaxRange)
|
float scanMaxRange)
|
||||||
{
|
{
|
||||||
if(scan.empty())
|
occupancy2DFromLaserScan(scan, cv::Mat(), viewpoint, ground, obstacles, cellSize, unknownSpaceFilled, scanMaxRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
void occupancy2DFromLaserScan(
|
||||||
|
const cv::Mat & scanHit,
|
||||||
|
const cv::Mat & scanNoHit,
|
||||||
|
const cv::Point3f & viewpoint,
|
||||||
|
cv::Mat & ground,
|
||||||
|
cv::Mat & obstacles,
|
||||||
|
float cellSize,
|
||||||
|
bool unknownSpaceFilled,
|
||||||
|
float scanMaxRange)
|
||||||
|
{
|
||||||
|
if(scanHit.empty() && scanNoHit.empty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -82,11 +95,8 @@ void occupancy2DFromLaserScan(
|
|||||||
std::map<int, Transform> poses;
|
std::map<int, Transform> poses;
|
||||||
poses.insert(std::make_pair(1, Transform::getIdentity()));
|
poses.insert(std::make_pair(1, Transform::getIdentity()));
|
||||||
|
|
||||||
pcl::PointCloud<pcl::PointXYZ>::Ptr obstaclesCloud = util3d::laserScanToPointCloud(scan);
|
std::map<int, std::pair<cv::Mat, cv::Mat> > scans;
|
||||||
//obstaclesCloud = util3d::voxelize<pcl::PointXYZ>(obstaclesCloud, cellSize);
|
scans.insert(std::make_pair(1, std::make_pair(scanHit, scanNoHit)));
|
||||||
|
|
||||||
std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr> scans;
|
|
||||||
scans.insert(std::make_pair(1, obstaclesCloud));
|
|
||||||
|
|
||||||
std::map<int, cv::Point3f> viewpoints;
|
std::map<int, cv::Point3f> viewpoints;
|
||||||
viewpoints.insert(std::make_pair(1, viewpoint));
|
viewpoints.insert(std::make_pair(1, viewpoint));
|
||||||
@@ -94,23 +104,6 @@ void occupancy2DFromLaserScan(
|
|||||||
float xMin, yMin;
|
float xMin, yMin;
|
||||||
cv::Mat map8S = create2DMap(poses, scans, viewpoints, cellSize, unknownSpaceFilled, xMin, yMin, 0.0f, scanMaxRange);
|
cv::Mat map8S = create2DMap(poses, scans, viewpoints, cellSize, unknownSpaceFilled, xMin, yMin, 0.0f, scanMaxRange);
|
||||||
|
|
||||||
// If input ground has already values, add them to map
|
|
||||||
if(ground.rows == 1 && ground.cols>0 && ground.type() == CV_32FC2)
|
|
||||||
{
|
|
||||||
for(int i=0; i<ground.cols; ++i)
|
|
||||||
{
|
|
||||||
cv::Vec2f * ptr = ground.ptr<cv::Vec2f>();
|
|
||||||
|
|
||||||
// cell
|
|
||||||
cv::Point2i cell((ptr[i][0]-xMin)/cellSize, (ptr[i][1]-yMin)/cellSize);
|
|
||||||
|
|
||||||
if(cell.x>=0 && cell.x<map8S.cols && cell.y >= 0 && cell.y < map8S.rows && map8S.at<char>(cell.y, cell.x) == -1)
|
|
||||||
{
|
|
||||||
map8S.at<char>(cell.y, cell.x) = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find ground cells
|
// find ground cells
|
||||||
std::list<int> groundIndices;
|
std::list<int> groundIndices;
|
||||||
for(unsigned int i=0; i< map8S.total(); ++i)
|
for(unsigned int i=0; i< map8S.total(); ++i)
|
||||||
@@ -139,17 +132,7 @@ void occupancy2DFromLaserScan(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// copy directly obstacles precise positions
|
// copy directly obstacles precise positions
|
||||||
obstacles = cv::Mat();
|
obstacles = scanHit.clone();
|
||||||
if(obstaclesCloud->size())
|
|
||||||
{
|
|
||||||
obstacles = cv::Mat(1, (int)obstaclesCloud->size(), CV_32FC2);
|
|
||||||
for(unsigned int i=0;i<obstaclesCloud->size(); ++i)
|
|
||||||
{
|
|
||||||
cv::Vec2f * ptr = obstacles.ptr<cv::Vec2f>();
|
|
||||||
ptr[i][0] = obstaclesCloud->at(i).x;
|
|
||||||
ptr[i][1] = obstaclesCloud->at(i).y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -510,8 +493,39 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
|
|||||||
float scanMaxRange)
|
float scanMaxRange)
|
||||||
{
|
{
|
||||||
std::map<int, cv::Point3f > viewpoints;
|
std::map<int, cv::Point3f > viewpoints;
|
||||||
|
std::map<int, std::pair<cv::Mat, cv::Mat> > scansCv;
|
||||||
|
for(std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr >::const_iterator iter = scans.begin(); iter!=scans.end(); ++iter)
|
||||||
|
{
|
||||||
|
scansCv.insert(std::make_pair(iter->first, std::make_pair(util3d::laserScanFromPointCloud(*iter->second), cv::Mat())));
|
||||||
|
}
|
||||||
return create2DMap(poses,
|
return create2DMap(poses,
|
||||||
scans,
|
scansCv,
|
||||||
|
viewpoints,
|
||||||
|
cellSize,
|
||||||
|
unknownSpaceFilled,
|
||||||
|
xMin,
|
||||||
|
yMin,
|
||||||
|
minMapSize,
|
||||||
|
scanMaxRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat create2DMap(const std::map<int, Transform> & poses,
|
||||||
|
const std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans,
|
||||||
|
const std::map<int, cv::Point3f > & viewpoints,
|
||||||
|
float cellSize,
|
||||||
|
bool unknownSpaceFilled,
|
||||||
|
float & xMin,
|
||||||
|
float & yMin,
|
||||||
|
float minMapSize,
|
||||||
|
float scanMaxRange)
|
||||||
|
{
|
||||||
|
std::map<int, std::pair<cv::Mat, cv::Mat> > scansCv;
|
||||||
|
for(std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr >::const_iterator iter = scans.begin(); iter!=scans.end(); ++iter)
|
||||||
|
{
|
||||||
|
scansCv.insert(std::make_pair(iter->first, std::make_pair(util3d::laserScanFromPointCloud(*iter->second), cv::Mat())));
|
||||||
|
}
|
||||||
|
return create2DMap(poses,
|
||||||
|
scansCv,
|
||||||
viewpoints,
|
viewpoints,
|
||||||
cellSize,
|
cellSize,
|
||||||
unknownSpaceFilled,
|
unknownSpaceFilled,
|
||||||
@@ -537,7 +551,7 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
|
|||||||
* @param scanMaxRange laser scan maximum range, would be set if unknownSpaceFilled=true
|
* @param scanMaxRange laser scan maximum range, would be set if unknownSpaceFilled=true
|
||||||
*/
|
*/
|
||||||
cv::Mat create2DMap(const std::map<int, Transform> & poses,
|
cv::Mat create2DMap(const std::map<int, Transform> & poses,
|
||||||
const std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans,
|
const std::map<int, std::pair<cv::Mat, cv::Mat> > & scans, // <id, <hit, no hit> >
|
||||||
const std::map<int, cv::Point3f > & viewpoints,
|
const std::map<int, cv::Point3f > & viewpoints,
|
||||||
float cellSize,
|
float cellSize,
|
||||||
bool unknownSpaceFilled,
|
bool unknownSpaceFilled,
|
||||||
@@ -547,7 +561,7 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
|
|||||||
float scanMaxRange)
|
float scanMaxRange)
|
||||||
{
|
{
|
||||||
UDEBUG("poses=%d, scans = %d scanMaxRange=%f", poses.size(), scans.size(), scanMaxRange);
|
UDEBUG("poses=%d, scans = %d scanMaxRange=%f", poses.size(), scans.size(), scanMaxRange);
|
||||||
std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > localScans;
|
std::map<int, std::pair<cv::Mat, cv::Mat> > localScans;
|
||||||
|
|
||||||
pcl::PointCloud<pcl::PointXYZ> minMax;
|
pcl::PointCloud<pcl::PointXYZ> minMax;
|
||||||
if(minMapSize > 0.0f)
|
if(minMapSize > 0.0f)
|
||||||
@@ -557,15 +571,25 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
|
|||||||
}
|
}
|
||||||
for(std::map<int, Transform>::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
|
for(std::map<int, Transform>::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
|
||||||
{
|
{
|
||||||
std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr >::const_iterator jter=scans.find(iter->first);
|
std::map<int, std::pair<cv::Mat, cv::Mat> >::const_iterator jter=scans.find(iter->first);
|
||||||
if(jter!=scans.end() && jter->second->size())
|
if(jter!=scans.end() && (jter->second.first.cols || jter->second.second.cols))
|
||||||
{
|
{
|
||||||
UASSERT(!iter->second.isNull());
|
UASSERT(!iter->second.isNull());
|
||||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = util3d::transformPointCloud(jter->second, iter->second);
|
cv::Mat hit = util3d::transformLaserScan(jter->second.first, iter->second);
|
||||||
|
cv::Mat noHit = util3d::transformLaserScan(jter->second.second, iter->second);
|
||||||
pcl::PointXYZ min, max;
|
pcl::PointXYZ min, max;
|
||||||
pcl::getMinMax3D(*cloud, min, max);
|
if(!hit.empty())
|
||||||
minMax.push_back(min);
|
{
|
||||||
minMax.push_back(max);
|
util3d::getMinMax3D(hit, min, max);
|
||||||
|
minMax.push_back(min);
|
||||||
|
minMax.push_back(max);
|
||||||
|
}
|
||||||
|
if(!noHit.empty())
|
||||||
|
{
|
||||||
|
util3d::getMinMax3D(noHit, min, max);
|
||||||
|
minMax.push_back(min);
|
||||||
|
minMax.push_back(max);
|
||||||
|
}
|
||||||
minMax.push_back(pcl::PointXYZ(iter->second.x(), iter->second.y(), iter->second.z()));
|
minMax.push_back(pcl::PointXYZ(iter->second.x(), iter->second.y(), iter->second.z()));
|
||||||
|
|
||||||
std::map<int, cv::Point3f>::const_iterator kter=viewpoints.find(iter->first);
|
std::map<int, cv::Point3f>::const_iterator kter=viewpoints.find(iter->first);
|
||||||
@@ -574,7 +598,7 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
|
|||||||
minMax.push_back(pcl::PointXYZ(iter->second.x()+kter->second.x, iter->second.y()+kter->second.y, iter->second.z()+kter->second.z));
|
minMax.push_back(pcl::PointXYZ(iter->second.x()+kter->second.x, iter->second.y()+kter->second.y, iter->second.z()+kter->second.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
localScans.insert(std::make_pair(iter->first, cloud));
|
localScans.insert(std::make_pair(iter->first, std::make_pair(hit, noHit)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,7 +623,7 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
|
|||||||
|
|
||||||
map = cv::Mat::ones((yMax - yMin) / cellSize, (xMax - xMin) / cellSize, CV_8S)*-1;
|
map = cv::Mat::ones((yMax - yMin) / cellSize, (xMax - xMin) / cellSize, CV_8S)*-1;
|
||||||
int j=0;
|
int j=0;
|
||||||
for(std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr >::iterator iter = localScans.begin(); iter!=localScans.end(); ++iter)
|
for(std::map<int, std::pair<cv::Mat, cv::Mat> >::iterator iter = localScans.begin(); iter!=localScans.end(); ++iter)
|
||||||
{
|
{
|
||||||
const Transform & pose = poses.at(iter->first);
|
const Transform & pose = poses.at(iter->first);
|
||||||
cv::Point3f viewpoint(0,0,0);
|
cv::Point3f viewpoint(0,0,0);
|
||||||
@@ -609,15 +633,48 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
|
|||||||
viewpoint = kter->second;
|
viewpoint = kter->second;
|
||||||
}
|
}
|
||||||
cv::Point2i start(((pose.x()+viewpoint.x)-xMin)/cellSize, ((pose.y()+viewpoint.y)-yMin)/cellSize);
|
cv::Point2i start(((pose.x()+viewpoint.x)-xMin)/cellSize, ((pose.y()+viewpoint.y)-yMin)/cellSize);
|
||||||
for(unsigned int i=0; i<iter->second->size(); ++i)
|
|
||||||
|
// Set obstacles first
|
||||||
|
for(unsigned int i=0; i<iter->second.first.cols; ++i)
|
||||||
{
|
{
|
||||||
cv::Point2i end((iter->second->points[i].x-xMin)/cellSize, (iter->second->points[i].y-yMin)/cellSize);
|
const float * ptr = iter->second.first.ptr<float>(0, i);
|
||||||
|
cv::Point2i end((ptr[0]-xMin)/cellSize, (ptr[1]-yMin)/cellSize);
|
||||||
if(end!=start)
|
if(end!=start)
|
||||||
{
|
{
|
||||||
rayTrace(start, end, map, true); // trace free space
|
|
||||||
map.at<char>(end.y, end.x) = 100; // obstacle
|
map.at<char>(end.y, end.x) = 100; // obstacle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ray tracing for hits
|
||||||
|
for(unsigned int i=0; i<iter->second.first.cols; ++i)
|
||||||
|
{
|
||||||
|
const float * ptr = iter->second.first.ptr<float>(0, i);
|
||||||
|
cv::Point2i end((ptr[0]-xMin)/cellSize, (ptr[1]-yMin)/cellSize);
|
||||||
|
if(end!=start)
|
||||||
|
{
|
||||||
|
if(localScans.size() > 1 || map.at<char>(end.y, end.x) != 0)
|
||||||
|
{
|
||||||
|
rayTrace(start, end, map, true); // trace free space
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ray tracing for no hits
|
||||||
|
for(unsigned int i=0; i<iter->second.second.cols; ++i)
|
||||||
|
{
|
||||||
|
const float * ptr = iter->second.second.ptr<float>(0, i);
|
||||||
|
cv::Point2i end((ptr[0]-xMin)/cellSize, (ptr[1]-yMin)/cellSize);
|
||||||
|
if(end!=start)
|
||||||
|
{
|
||||||
|
if(localScans.size() > 1 || map.at<char>(end.y, end.x) != 0)
|
||||||
|
{
|
||||||
|
rayTrace(start, end, map, true); // trace free space
|
||||||
|
if(map.at<char>(end.y, end.x) == -1)
|
||||||
|
{
|
||||||
|
map.at<char>(end.y, end.x) = 0; // empty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
UDEBUG("Ray trace known space=%fs", timer.ticks());
|
UDEBUG("Ray trace known space=%fs", timer.ticks());
|
||||||
@@ -627,9 +684,9 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
|
|||||||
{
|
{
|
||||||
j=0;
|
j=0;
|
||||||
float a = CV_PI/256.0f; // angle increment
|
float a = CV_PI/256.0f; // angle increment
|
||||||
for(std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr >::iterator iter = localScans.begin(); iter!=localScans.end(); ++iter)
|
for(std::map<int, std::pair<cv::Mat, cv::Mat> >::iterator iter = localScans.begin(); iter!=localScans.end(); ++iter)
|
||||||
{
|
{
|
||||||
if(iter->second->size() > 1)
|
if(iter->second.first.cols > 1)
|
||||||
{
|
{
|
||||||
if(scanMaxRange > cellSize)
|
if(scanMaxRange > cellSize)
|
||||||
{
|
{
|
||||||
@@ -650,19 +707,10 @@ cv::Mat create2DMap(const std::map<int, Transform> & poses,
|
|||||||
cv::Mat origin(2,1,CV_32F), endFirst(2,1,CV_32F), endLast(2,1,CV_32F);
|
cv::Mat origin(2,1,CV_32F), endFirst(2,1,CV_32F), endLast(2,1,CV_32F);
|
||||||
origin.at<float>(0) = pose.x()+viewpoint.x;
|
origin.at<float>(0) = pose.x()+viewpoint.x;
|
||||||
origin.at<float>(1) = pose.y()+viewpoint.y;
|
origin.at<float>(1) = pose.y()+viewpoint.y;
|
||||||
pcl::PointXYZ ptFirst = iter->second->points[0];
|
endFirst.at<float>(0) = iter->second.first.ptr<float>(0,0)[0];
|
||||||
pcl::PointXYZ ptLast = iter->second->points[iter->second->points.size()-1];
|
endFirst.at<float>(1) = iter->second.first.ptr<float>(0,0)[1];
|
||||||
//if(ptFirst.y > ptLast.y)
|
endLast.at<float>(0) = iter->second.first.ptr<float>(0,iter->second.first.cols-1)[0];
|
||||||
//{
|
endLast.at<float>(1) = iter->second.first.ptr<float>(0,iter->second.first.cols-1)[1];
|
||||||
// swap to iterate counterclockwise
|
|
||||||
// pcl::PointXYZ tmp = ptLast;
|
|
||||||
// ptLast = ptFirst;
|
|
||||||
// ptFirst = tmp;
|
|
||||||
//}
|
|
||||||
endFirst.at<float>(0) = ptFirst.x;
|
|
||||||
endFirst.at<float>(1) = ptFirst.y;
|
|
||||||
endLast.at<float>(0) = ptLast.x;
|
|
||||||
endLast.at<float>(1) = ptLast.y;
|
|
||||||
//UWARN("origin = %f %f", origin.at<float>(0), origin.at<float>(1));
|
//UWARN("origin = %f %f", origin.at<float>(0), origin.at<float>(1));
|
||||||
//UWARN("endFirst = %f %f", endFirst.at<float>(0), endFirst.at<float>(1));
|
//UWARN("endFirst = %f %f", endFirst.at<float>(0), endFirst.at<float>(1));
|
||||||
//UWARN("endLast = %f %f", endLast.at<float>(0), endLast.at<float>(1));
|
//UWARN("endLast = %f %f", endLast.at<float>(0), endLast.at<float>(1));
|
||||||
|
|||||||
@@ -241,7 +241,8 @@ private:
|
|||||||
const std::map<int, int> & mapIds,
|
const std::map<int, int> & mapIds,
|
||||||
const std::map<int, std::string> & labels,
|
const std::map<int, std::string> & labels,
|
||||||
const std::map<int, Transform> & groundTruths,
|
const std::map<int, Transform> & groundTruths,
|
||||||
bool verboseProgress = false);
|
bool verboseProgress = false,
|
||||||
|
std::map<std::string, float> * stats = 0);
|
||||||
std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> createAndAddCloudToMap(int nodeId, const Transform & pose, int mapId);
|
std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> createAndAddCloudToMap(int nodeId, const Transform & pose, int mapId);
|
||||||
void createAndAddScanToMap(int nodeId, const Transform & pose, int mapId);
|
void createAndAddScanToMap(int nodeId, const Transform & pose, int mapId);
|
||||||
void createAndAddFeaturesToMap(int nodeId, const Transform & pose, int mapId);
|
void createAndAddFeaturesToMap(int nodeId, const Transform & pose, int mapId);
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ public:
|
|||||||
int getOctomapTreeDepth() const;
|
int getOctomapTreeDepth() const;
|
||||||
bool isOctomapGroundAnObstacle() const;
|
bool isOctomapGroundAnObstacle() const;
|
||||||
double getOctomapOccupancyThr() const;
|
double getOctomapOccupancyThr() const;
|
||||||
|
int getOctomapPointSize() const;
|
||||||
int getCloudDecimation(int index) const; // 0=map, 1=odom
|
int getCloudDecimation(int index) const; // 0=map, 1=odom
|
||||||
double getCloudMaxDepth(int index) const; // 0=map, 1=odom
|
double getCloudMaxDepth(int index) const; // 0=map, 1=odom
|
||||||
double getCloudMinDepth(int index) const; // 0=map, 1=odom
|
double getCloudMinDepth(int index) const; // 0=map, 1=odom
|
||||||
|
|||||||
@@ -1721,6 +1721,7 @@ void DatabaseViewer::regenerateLocalMaps()
|
|||||||
rtabmap::ProgressDialog progressDialog(this);
|
rtabmap::ProgressDialog progressDialog(this);
|
||||||
progressDialog.setMaximumSteps(ids_.size());
|
progressDialog.setMaximumSteps(ids_.size());
|
||||||
progressDialog.show();
|
progressDialog.show();
|
||||||
|
progressDialog.setCancelButtonVisible(true);
|
||||||
|
|
||||||
UPlot * plot = new UPlot(this);
|
UPlot * plot = new UPlot(this);
|
||||||
plot->setWindowFlags(Qt::Window);
|
plot->setWindowFlags(Qt::Window);
|
||||||
@@ -1730,10 +1731,19 @@ void DatabaseViewer::regenerateLocalMaps()
|
|||||||
UPlotCurve * gridCreationCurve = plot->addCurve("Grid Creation");
|
UPlotCurve * gridCreationCurve = plot->addCurve("Grid Creation");
|
||||||
plot->show();
|
plot->show();
|
||||||
|
|
||||||
|
UPlot * plotCells = new UPlot(this);
|
||||||
|
plotCells->setWindowFlags(Qt::Window);
|
||||||
|
plotCells->setWindowTitle("Occupancy Cells");
|
||||||
|
plotCells->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
UPlotCurve * totalCurve = plotCells->addCurve("Total");
|
||||||
|
UPlotCurve * groundCurve = plotCells->addCurve("Empty");
|
||||||
|
UPlotCurve * obstaclesCurve = plotCells->addCurve("Occupied");
|
||||||
|
plotCells->show();
|
||||||
|
|
||||||
double decompressionTime = 0;
|
double decompressionTime = 0;
|
||||||
double gridCreationTime = 0;
|
double gridCreationTime = 0;
|
||||||
|
|
||||||
for(int i =0; i<ids_.size(); ++i)
|
for(int i =0; i<ids_.size() && !progressDialog.isCanceled(); ++i)
|
||||||
{
|
{
|
||||||
UTimer timer;
|
UTimer timer;
|
||||||
SensorData data;
|
SensorData data;
|
||||||
@@ -1758,6 +1768,10 @@ void DatabaseViewer::regenerateLocalMaps()
|
|||||||
uInsert(generatedLocalMaps_, std::make_pair(data.id(), std::make_pair(ground, obstacles)));
|
uInsert(generatedLocalMaps_, std::make_pair(data.id(), std::make_pair(ground, obstacles)));
|
||||||
uInsert(generatedLocalMapsInfo_, std::make_pair(data.id(), std::make_pair(grid.getCellSize(), viewpoint)));
|
uInsert(generatedLocalMapsInfo_, std::make_pair(data.id(), std::make_pair(grid.getCellSize(), viewpoint)));
|
||||||
msg = QString("Generated local occupancy grid map %1/%2").arg(i+1).arg((int)ids_.size());
|
msg = QString("Generated local occupancy grid map %1/%2").arg(i+1).arg((int)ids_.size());
|
||||||
|
|
||||||
|
totalCurve->addValue(ids_.at(i), obstacles.cols+ground.cols);
|
||||||
|
groundCurve->addValue(ids_.at(i), ground.cols);
|
||||||
|
obstaclesCurve->addValue(ids_.at(i), obstacles.cols);
|
||||||
}
|
}
|
||||||
|
|
||||||
progressDialog.appendText(msg);
|
progressDialog.appendText(msg);
|
||||||
@@ -1772,7 +1786,16 @@ void DatabaseViewer::regenerateLocalMaps()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
progressDialog.setValue(progressDialog.maximumSteps());
|
progressDialog.setValue(progressDialog.maximumSteps());
|
||||||
updateGrid();
|
|
||||||
|
if(graphes_.size())
|
||||||
|
{
|
||||||
|
update3dView();
|
||||||
|
sliderIterationsValueChanged((int)graphes_.size()-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
updateGrid();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseViewer::regenerateCurrentLocalMaps()
|
void DatabaseViewer::regenerateCurrentLocalMaps()
|
||||||
@@ -1826,7 +1849,16 @@ void DatabaseViewer::regenerateCurrentLocalMaps()
|
|||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
}
|
}
|
||||||
progressDialog.setValue(progressDialog.maximumSteps());
|
progressDialog.setValue(progressDialog.maximumSteps());
|
||||||
updateGrid();
|
|
||||||
|
if(graphes_.size())
|
||||||
|
{
|
||||||
|
update3dView();
|
||||||
|
sliderIterationsValueChanged((int)graphes_.size()-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
updateGrid();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseViewer::view3DMap()
|
void DatabaseViewer::view3DMap()
|
||||||
@@ -3967,6 +3999,7 @@ void DatabaseViewer::sliderIterationsValueChanged(int value)
|
|||||||
Qt::red);
|
Qt::red);
|
||||||
occupancyGridViewer_->setCloudPointSize("obstaclesXYZ", 5);
|
occupancyGridViewer_->setCloudPointSize("obstaclesXYZ", 5);
|
||||||
}
|
}
|
||||||
|
occupancyGridViewer_->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+97
-13
@@ -586,6 +586,13 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
|||||||
|
|
||||||
_ui->statsToolBox->updateStat("GUI/Refresh odom/ms", false);
|
_ui->statsToolBox->updateStat("GUI/Refresh odom/ms", false);
|
||||||
_ui->statsToolBox->updateStat("GUI/RGB-D cloud/ms", false);
|
_ui->statsToolBox->updateStat("GUI/RGB-D cloud/ms", false);
|
||||||
|
_ui->statsToolBox->updateStat("GUI/Graph Update/ms", false);
|
||||||
|
#ifdef RTABMAP_OCTOMAP
|
||||||
|
_ui->statsToolBox->updateStat("GUI/Octomap Update/ms", false);
|
||||||
|
_ui->statsToolBox->updateStat("GUI/Octomap Rendering/ms", false);
|
||||||
|
#endif
|
||||||
|
_ui->statsToolBox->updateStat("GUI/Grid Update/ms", false);
|
||||||
|
_ui->statsToolBox->updateStat("GUI/Grid Rendering/ms", false);
|
||||||
_ui->statsToolBox->updateStat("GUI/Refresh stats/ms", false);
|
_ui->statsToolBox->updateStat("GUI/Refresh stats/ms", false);
|
||||||
_ui->statsToolBox->updateStat("GUI/Cache Data Size/MB", false);
|
_ui->statsToolBox->updateStat("GUI/Cache Data Size/MB", false);
|
||||||
_ui->statsToolBox->updateStat("GUI/Cache Clouds Size/MB", false);
|
_ui->statsToolBox->updateStat("GUI/Cache Clouds Size/MB", false);
|
||||||
@@ -1429,12 +1436,18 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
signature = stat.getSignatures().at(stat.refImageId());
|
signature = stat.getSignatures().at(stat.refImageId());
|
||||||
signature.sensorData().uncompressData(); // make sure data are uncompressed
|
signature.sensorData().uncompressData(); // make sure data are uncompressed
|
||||||
|
|
||||||
if(!smallMovement &&
|
if( uStr2Bool(_preferencesDialog->getParameter(Parameters::kMemIncrementalMemory())) &&
|
||||||
uStr2Bool(_preferencesDialog->getParameter(Parameters::kMemIncrementalMemory())) &&
|
|
||||||
signature.getWeight()>=0) // ignore intermediate nodes for the cache
|
signature.getWeight()>=0) // ignore intermediate nodes for the cache
|
||||||
{
|
{
|
||||||
_cachedSignatures.insert(signature.id(), signature);
|
if(smallMovement)
|
||||||
_cachedMemoryUsage += signature.sensorData().getMemoryUsed();
|
{
|
||||||
|
_cachedSignatures.insert(-1, signature); // negative means temporary
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_cachedSignatures.insert(signature.id(), signature);
|
||||||
|
_cachedMemoryUsage += signature.sensorData().getMemoryUsed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1675,8 +1688,6 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
//======================
|
//======================
|
||||||
// RGB-D Mapping stuff
|
// RGB-D Mapping stuff
|
||||||
//======================
|
//======================
|
||||||
UTimer timerVis;
|
|
||||||
|
|
||||||
// update clouds
|
// update clouds
|
||||||
if(stat.poses().size())
|
if(stat.poses().size())
|
||||||
{
|
{
|
||||||
@@ -1725,19 +1736,40 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(_cachedSignatures.contains(-1))
|
||||||
|
{
|
||||||
|
if(poses.find(stat.refImageId())!=poses.end())
|
||||||
|
{
|
||||||
|
poses.insert(std::make_pair(-1, poses.at(stat.refImageId())));
|
||||||
|
poses.erase(stat.refImageId());
|
||||||
|
}
|
||||||
|
if(groundTruth.find(stat.refImageId())!=groundTruth.end())
|
||||||
|
{
|
||||||
|
groundTruth.insert(std::make_pair(-1, groundTruth.at(stat.refImageId())));
|
||||||
|
groundTruth.erase(stat.refImageId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, float> updateCloudSats;
|
||||||
updateMapCloud(
|
updateMapCloud(
|
||||||
poses,
|
poses,
|
||||||
stat.constraints(),
|
stat.constraints(),
|
||||||
mapIds,
|
mapIds,
|
||||||
labels,
|
labels,
|
||||||
groundTruth);
|
groundTruth,
|
||||||
|
false,
|
||||||
|
&updateCloudSats);
|
||||||
|
|
||||||
_odometryReceived = false;
|
_odometryReceived = false;
|
||||||
|
|
||||||
_odometryCorrection = groundTruthOffset * stat.mapCorrection();
|
_odometryCorrection = groundTruthOffset * stat.mapCorrection();
|
||||||
|
|
||||||
UDEBUG("time= %d ms", time.restart());
|
UDEBUG("time= %d ms", time.restart());
|
||||||
_ui->statsToolBox->updateStat("GUI/RGB-D cloud/ms", _preferencesDialog->isTimeUsedInFigures()?stat.stamp()-_firstStamp:stat.refImageId(), int(timerVis.elapsed()*1000.0f), _preferencesDialog->isCacheSavedInFigures());
|
|
||||||
|
for(std::map<std::string, float>::iterator iter=updateCloudSats.begin(); iter!=updateCloudSats.end(); ++iter)
|
||||||
|
{
|
||||||
|
_ui->statsToolBox->updateStat(iter->first.c_str(), _preferencesDialog->isTimeUsedInFigures()?stat.stamp()-_firstStamp:stat.refImageId(), int(iter->second), _preferencesDialog->isCacheSavedInFigures());
|
||||||
|
}
|
||||||
|
|
||||||
// loop closure view
|
// loop closure view
|
||||||
if((stat.loopClosureId() > 0 || stat.proximityDetectionId() > 0) &&
|
if((stat.loopClosureId() > 0 || stat.proximityDetectionId() > 0) &&
|
||||||
@@ -1783,6 +1815,8 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
}
|
}
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
|
|
||||||
|
_cachedSignatures.remove(-1); // remove tmp negative ids
|
||||||
|
|
||||||
// keep only compressed data in cache
|
// keep only compressed data in cache
|
||||||
if(_cachedSignatures.contains(stat.refImageId()))
|
if(_cachedSignatures.contains(stat.refImageId()))
|
||||||
{
|
{
|
||||||
@@ -1796,7 +1830,6 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
_cachedMemoryUsage += s.sensorData().getMemoryUsed();
|
_cachedMemoryUsage += s.sensorData().getMemoryUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
}
|
}
|
||||||
else if(!stat.extended() && stat.loopClosureId()>0)
|
else if(!stat.extended() && stat.loopClosureId()>0)
|
||||||
@@ -1843,17 +1876,21 @@ void MainWindow::updateMapCloud(
|
|||||||
const std::map<int, int> & mapIdsIn,
|
const std::map<int, int> & mapIdsIn,
|
||||||
const std::map<int, std::string> & labels,
|
const std::map<int, std::string> & labels,
|
||||||
const std::map<int, Transform> & groundTruths, // ground truth should contain only valid transforms
|
const std::map<int, Transform> & groundTruths, // ground truth should contain only valid transforms
|
||||||
bool verboseProgress)
|
bool verboseProgress,
|
||||||
|
std::map<std::string, float> * stats)
|
||||||
{
|
{
|
||||||
|
UTimer timer;
|
||||||
UDEBUG("posesIn=%d constraints=%d mapIdsIn=%d labelsIn=%d",
|
UDEBUG("posesIn=%d constraints=%d mapIdsIn=%d labelsIn=%d",
|
||||||
(int)posesIn.size(), (int)constraints.size(), (int)mapIdsIn.size(), (int)labels.size());
|
(int)posesIn.size(), (int)constraints.size(), (int)mapIdsIn.size(), (int)labels.size());
|
||||||
if(posesIn.size())
|
if(posesIn.size())
|
||||||
{
|
{
|
||||||
_currentPosesMap = posesIn;
|
_currentPosesMap = posesIn;
|
||||||
|
_currentPosesMap.erase(-1); // don't keep -1 if it is there
|
||||||
_currentLinksMap = constraints;
|
_currentLinksMap = constraints;
|
||||||
_currentMapIds = mapIdsIn;
|
_currentMapIds = mapIdsIn;
|
||||||
_currentLabels = labels;
|
_currentLabels = labels;
|
||||||
_currentGTPosesMap = groundTruths;
|
_currentGTPosesMap = groundTruths;
|
||||||
|
_currentGTPosesMap.erase(-1);
|
||||||
if(_state != kMonitoring && _state != kDetecting)
|
if(_state != kMonitoring && _state != kDetecting)
|
||||||
{
|
{
|
||||||
_ui->actionPost_processing->setEnabled(_cachedSignatures.size() >= 2 && _currentPosesMap.size() >= 2 && _currentLinksMap.size() >= 1);
|
_ui->actionPost_processing->setEnabled(_cachedSignatures.size() >= 2 && _currentPosesMap.size() >= 2 && _currentLinksMap.size() >= 1);
|
||||||
@@ -1902,12 +1939,12 @@ void MainWindow::updateMapCloud(
|
|||||||
}
|
}
|
||||||
_ui->widget_mapVisibility->setMap(posesIn, posesMask);
|
_ui->widget_mapVisibility->setMap(posesIn, posesMask);
|
||||||
|
|
||||||
if(_currentGTPosesMap.size() && _ui->actionAnchor_clouds_to_ground_truth->isChecked())
|
if(groundTruths.size() && _ui->actionAnchor_clouds_to_ground_truth->isChecked())
|
||||||
{
|
{
|
||||||
for(std::map<int, Transform>::iterator iter = poses.begin(); iter!=poses.end(); ++iter)
|
for(std::map<int, Transform>::iterator iter = poses.begin(); iter!=poses.end(); ++iter)
|
||||||
{
|
{
|
||||||
std::map<int, Transform>::iterator gtIter = _currentGTPosesMap.find(iter->first);
|
std::map<int, Transform>::const_iterator gtIter = groundTruths.find(iter->first);
|
||||||
if(gtIter!=_currentGTPosesMap.end())
|
if(gtIter!=groundTruths.end())
|
||||||
{
|
{
|
||||||
iter->second = gtIter->second;
|
iter->second = gtIter->second;
|
||||||
}
|
}
|
||||||
@@ -1932,6 +1969,12 @@ void MainWindow::updateMapCloud(
|
|||||||
{
|
{
|
||||||
std::string cloudName = uFormat("cloud%d", iter->first);
|
std::string cloudName = uFormat("cloud%d", iter->first);
|
||||||
|
|
||||||
|
if(iter->first < 0)
|
||||||
|
{
|
||||||
|
viewerClouds.remove(cloudName);
|
||||||
|
_cloudViewer->removeCloud(cloudName);
|
||||||
|
}
|
||||||
|
|
||||||
// 3d point cloud
|
// 3d point cloud
|
||||||
bool update3dCloud = _cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0);
|
bool update3dCloud = _cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0);
|
||||||
if(update3dCloud)
|
if(update3dCloud)
|
||||||
@@ -1971,6 +2014,11 @@ void MainWindow::updateMapCloud(
|
|||||||
|
|
||||||
// 2d point cloud
|
// 2d point cloud
|
||||||
std::string scanName = uFormat("scan%d", iter->first);
|
std::string scanName = uFormat("scan%d", iter->first);
|
||||||
|
if(iter->first < 0)
|
||||||
|
{
|
||||||
|
viewerClouds.remove(scanName);
|
||||||
|
_cloudViewer->removeCloud(scanName);
|
||||||
|
}
|
||||||
if(_cloudViewer->isVisible() && _preferencesDialog->isScansShown(0))
|
if(_cloudViewer->isVisible() && _preferencesDialog->isScansShown(0))
|
||||||
{
|
{
|
||||||
if(viewerClouds.contains(scanName))
|
if(viewerClouds.contains(scanName))
|
||||||
@@ -2004,6 +2052,12 @@ void MainWindow::updateMapCloud(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// occupancy grids
|
// occupancy grids
|
||||||
|
if(iter->first < 0)
|
||||||
|
{
|
||||||
|
_gridLocalMaps.erase(iter->first);
|
||||||
|
_gridViewPoints.erase(iter->first);
|
||||||
|
}
|
||||||
|
|
||||||
bool updateGridMap =
|
bool updateGridMap =
|
||||||
((_ui->graphicsView_graphView->isVisible() && _ui->graphicsView_graphView->isGridMapVisible()) ||
|
((_ui->graphicsView_graphView->isVisible() && _ui->graphicsView_graphView->isGridMapVisible()) ||
|
||||||
(_cloudViewer->isVisible() && _preferencesDialog->getGridMapShown())) &&
|
(_cloudViewer->isVisible() && _preferencesDialog->getGridMapShown())) &&
|
||||||
@@ -2061,6 +2115,11 @@ void MainWindow::updateMapCloud(
|
|||||||
|
|
||||||
// 3d features
|
// 3d features
|
||||||
std::string featuresName = uFormat("features%d", iter->first);
|
std::string featuresName = uFormat("features%d", iter->first);
|
||||||
|
if(iter->first < 0)
|
||||||
|
{
|
||||||
|
viewerClouds.remove(featuresName);
|
||||||
|
_cloudViewer->removeCloud(featuresName);
|
||||||
|
}
|
||||||
if(_cloudViewer->isVisible() && _preferencesDialog->isFeaturesShown(0))
|
if(_cloudViewer->isVisible() && _preferencesDialog->isFeaturesShown(0))
|
||||||
{
|
{
|
||||||
if(viewerClouds.contains(featuresName))
|
if(viewerClouds.contains(featuresName))
|
||||||
@@ -2129,6 +2188,10 @@ void MainWindow::updateMapCloud(
|
|||||||
}
|
}
|
||||||
|
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
|
if(stats)
|
||||||
|
{
|
||||||
|
stats->insert(std::make_pair("GUI/RGB-D cloud/ms", (float)timer.restart()*1000.0f));
|
||||||
|
}
|
||||||
|
|
||||||
// update 3D graphes (show all poses)
|
// update 3D graphes (show all poses)
|
||||||
_cloudViewer->removeAllGraphs();
|
_cloudViewer->removeAllGraphs();
|
||||||
@@ -2268,6 +2331,10 @@ void MainWindow::updateMapCloud(
|
|||||||
}
|
}
|
||||||
|
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
|
if(stats)
|
||||||
|
{
|
||||||
|
stats->insert(std::make_pair("GUI/Graph Update/ms", (float)timer.restart()*1000.0f));
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef RTABMAP_OCTOMAP
|
#ifdef RTABMAP_OCTOMAP
|
||||||
_cloudViewer->removeOctomap();
|
_cloudViewer->removeOctomap();
|
||||||
@@ -2279,6 +2346,10 @@ void MainWindow::updateMapCloud(
|
|||||||
_octomap->update(poses);
|
_octomap->update(poses);
|
||||||
UINFO("Octomap update time = %fs", time.ticks());
|
UINFO("Octomap update time = %fs", time.ticks());
|
||||||
}
|
}
|
||||||
|
if(stats)
|
||||||
|
{
|
||||||
|
stats->insert(std::make_pair("GUI/Octomap Update/ms", (float)timer.restart()*1000.0f));
|
||||||
|
}
|
||||||
if(_preferencesDialog->isOctomapShown())
|
if(_preferencesDialog->isOctomapShown())
|
||||||
{
|
{
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
@@ -2294,11 +2365,16 @@ void MainWindow::updateMapCloud(
|
|||||||
if(obstacles->size())
|
if(obstacles->size())
|
||||||
{
|
{
|
||||||
_cloudViewer->addCloud("octomap_cloud", cloud);
|
_cloudViewer->addCloud("octomap_cloud", cloud);
|
||||||
|
_cloudViewer->setCloudPointSize("octomap_cloud", _preferencesDialog->getOctomapPointSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UINFO("Octomap show 3d map time = %fs", time.ticks());
|
UINFO("Octomap show 3d map time = %fs", time.ticks());
|
||||||
}
|
}
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
|
if(stats)
|
||||||
|
{
|
||||||
|
stats->insert(std::make_pair("GUI/Octomap Rendering/ms", (float)timer.restart()*1000.0f));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Update occupancy grid map in 3D map view and graph view
|
// Update occupancy grid map in 3D map view and graph view
|
||||||
@@ -2326,6 +2402,10 @@ void MainWindow::updateMapCloud(
|
|||||||
if(_preferencesDialog->isGridMapIncremental())
|
if(_preferencesDialog->isGridMapIncremental())
|
||||||
{
|
{
|
||||||
_occupancyGrid->update(poses, 0, _preferencesDialog->getGridMapFootprintRadius());
|
_occupancyGrid->update(poses, 0, _preferencesDialog->getGridMapFootprintRadius());
|
||||||
|
if(stats)
|
||||||
|
{
|
||||||
|
stats->insert(std::make_pair("GUI/Grid Update/ms", (float)timer.restart()*1000.0f));
|
||||||
|
}
|
||||||
map8S = _occupancyGrid->getMap(xMin, yMin);
|
map8S = _occupancyGrid->getMap(xMin, yMin);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2359,6 +2439,10 @@ void MainWindow::updateMapCloud(
|
|||||||
_ui->graphicsView_graphView->update();
|
_ui->graphicsView_graphView->update();
|
||||||
|
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
|
if(stats)
|
||||||
|
{
|
||||||
|
stats->insert(std::make_pair("GUI/Grid Rendering/ms", (float)timer.restart()*1000.0f));
|
||||||
|
}
|
||||||
|
|
||||||
if(!_preferencesDialog->getGridMapShown())
|
if(!_preferencesDialog->getGridMapShown())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -412,6 +412,8 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
connect(_ui->checkBox_octomap_2dgrid, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
connect(_ui->checkBox_octomap_2dgrid, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||||
connect(_ui->checkBox_octomap_show3dMap, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
connect(_ui->checkBox_octomap_show3dMap, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||||
connect(_ui->checkBox_octomap_cubeRendering, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
connect(_ui->checkBox_octomap_cubeRendering, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||||
|
connect(_ui->spinBox_octomap_pointSize, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||||
|
connect(_ui->doubleSpinBox_octomap_occupancyThr, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||||
|
|
||||||
connect(_ui->groupBox_organized, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
connect(_ui->groupBox_organized, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||||
connect(_ui->doubleSpinBox_mesh_angleTolerance, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
connect(_ui->doubleSpinBox_mesh_angleTolerance, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||||
@@ -1313,6 +1315,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
|
|||||||
_ui->checkBox_octomap_2dgrid->setChecked(true);
|
_ui->checkBox_octomap_2dgrid->setChecked(true);
|
||||||
_ui->checkBox_octomap_show3dMap->setChecked(true);
|
_ui->checkBox_octomap_show3dMap->setChecked(true);
|
||||||
_ui->checkBox_octomap_cubeRendering->setChecked(true);
|
_ui->checkBox_octomap_cubeRendering->setChecked(true);
|
||||||
|
_ui->spinBox_octomap_pointSize->setValue(5);
|
||||||
_ui->doubleSpinBox_octomap_occupancyThr->setValue(0.5);
|
_ui->doubleSpinBox_octomap_occupancyThr->setValue(0.5);
|
||||||
}
|
}
|
||||||
else if(groupBox->objectName() == _ui->groupBox_logging1->objectName())
|
else if(groupBox->objectName() == _ui->groupBox_logging1->objectName())
|
||||||
@@ -1692,6 +1695,7 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
|
|||||||
_ui->checkBox_octomap_show3dMap->setChecked(settings.value("octomap_3dmap", _ui->checkBox_octomap_show3dMap->isChecked()).toBool());
|
_ui->checkBox_octomap_show3dMap->setChecked(settings.value("octomap_3dmap", _ui->checkBox_octomap_show3dMap->isChecked()).toBool());
|
||||||
_ui->checkBox_octomap_cubeRendering->setChecked(settings.value("octomap_cube", _ui->checkBox_octomap_cubeRendering->isChecked()).toBool());
|
_ui->checkBox_octomap_cubeRendering->setChecked(settings.value("octomap_cube", _ui->checkBox_octomap_cubeRendering->isChecked()).toBool());
|
||||||
_ui->doubleSpinBox_octomap_occupancyThr->setValue(settings.value("octomap_occupancy_thr", _ui->doubleSpinBox_octomap_occupancyThr->value()).toDouble());
|
_ui->doubleSpinBox_octomap_occupancyThr->setValue(settings.value("octomap_occupancy_thr", _ui->doubleSpinBox_octomap_occupancyThr->value()).toDouble());
|
||||||
|
_ui->spinBox_octomap_pointSize->setValue(settings.value("octomap_point_size", _ui->spinBox_octomap_pointSize->value()).toInt());
|
||||||
|
|
||||||
_ui->groupBox_organized->setChecked(settings.value("meshing", _ui->groupBox_organized->isChecked()).toBool());
|
_ui->groupBox_organized->setChecked(settings.value("meshing", _ui->groupBox_organized->isChecked()).toBool());
|
||||||
_ui->doubleSpinBox_mesh_angleTolerance->setValue(settings.value("meshing_angle", _ui->doubleSpinBox_mesh_angleTolerance->value()).toDouble());
|
_ui->doubleSpinBox_mesh_angleTolerance->setValue(settings.value("meshing_angle", _ui->doubleSpinBox_mesh_angleTolerance->value()).toDouble());
|
||||||
@@ -2077,6 +2081,7 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const
|
|||||||
settings.setValue("octomap_3dmap", _ui->checkBox_octomap_show3dMap->isChecked());
|
settings.setValue("octomap_3dmap", _ui->checkBox_octomap_show3dMap->isChecked());
|
||||||
settings.setValue("octomap_cube", _ui->checkBox_octomap_cubeRendering->isChecked());
|
settings.setValue("octomap_cube", _ui->checkBox_octomap_cubeRendering->isChecked());
|
||||||
settings.setValue("octomap_occupancy_thr", _ui->doubleSpinBox_octomap_occupancyThr->value());
|
settings.setValue("octomap_occupancy_thr", _ui->doubleSpinBox_octomap_occupancyThr->value());
|
||||||
|
settings.setValue("octomap_point_size", _ui->spinBox_octomap_pointSize->value());
|
||||||
|
|
||||||
|
|
||||||
settings.setValue("meshing", _ui->groupBox_organized->isChecked());
|
settings.setValue("meshing", _ui->groupBox_organized->isChecked());
|
||||||
@@ -4067,6 +4072,10 @@ double PreferencesDialog::getOctomapOccupancyThr() const
|
|||||||
{
|
{
|
||||||
return _ui->doubleSpinBox_octomap_occupancyThr->value();
|
return _ui->doubleSpinBox_octomap_occupancyThr->value();
|
||||||
}
|
}
|
||||||
|
int PreferencesDialog::getOctomapPointSize() const
|
||||||
|
{
|
||||||
|
return _ui->spinBox_octomap_pointSize->value();
|
||||||
|
}
|
||||||
|
|
||||||
double PreferencesDialog::getVoxel() const
|
double PreferencesDialog::getVoxel() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -86,7 +86,7 @@
|
|||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>15</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page_22">
|
<widget class="QWidget" name="page_22">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
||||||
@@ -1958,7 +1958,33 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
|||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_72" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout_72" columnstretch="0,1">
|
||||||
<item row="2" column="1">
|
<item row="5" column="1">
|
||||||
|
<widget class="QLabel" name="label_octomap_treeDepth_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Occupancy threshold.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_octomap_treeDepth_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cube rendering. Disable to show as a point cloud (a lot less GPU power required).</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
<widget class="QLabel" name="label_octomap_treeDepth">
|
<widget class="QLabel" name="label_octomap_treeDepth">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Octomap maximum tree depth (max 16). The highest depth means the smallest resolution of the map (cell size). At smallest resolution the octomap shows RGB colors. Other resolutions produce z-axis gradient colored octomap.</string>
|
<string>Octomap maximum tree depth (max 16). The highest depth means the smallest resolution of the map (cell size). At smallest resolution the octomap shows RGB colors. Other resolutions produce z-axis gradient colored octomap.</string>
|
||||||
@@ -1971,7 +1997,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QSpinBox" name="spinBox_octomap_treeDepth">
|
<widget class="QSpinBox" name="spinBox_octomap_treeDepth">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
@@ -1984,7 +2010,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox_octomap_2dgrid">
|
<widget class="QCheckBox" name="checkBox_octomap_2dgrid">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
@@ -1994,7 +2020,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QLabel" name="label_octomap_treeDepth_2">
|
<widget class="QLabel" name="label_octomap_treeDepth_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show 2D occupancy grid map from OctoMap projection.</string>
|
<string>Show 2D occupancy grid map from OctoMap projection.</string>
|
||||||
@@ -2030,42 +2056,19 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="5" column="0">
|
||||||
<widget class="QLabel" name="label_octomap_treeDepth_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Occupancy threshold.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_octomap_occupancyThr">
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_octomap_occupancyThr">
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<double>1.000000000000000</double>
|
<double>1.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.050000000000000</double>
|
||||||
|
</property>
|
||||||
<property name="value">
|
<property name="value">
|
||||||
<double>0.500000000000000</double>
|
<double>0.500000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLabel" name="label_octomap_treeDepth_5">
|
|
||||||
<property name="text">
|
|
||||||
<string>Cube rendering. Disable to show as a point cloud (a lot less GPU power required).</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox_octomap_cubeRendering">
|
<widget class="QCheckBox" name="checkBox_octomap_cubeRendering">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -2076,6 +2079,32 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLabel" name="label_octomap_treeDepth_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Point size. When cube rendering is disabled.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QSpinBox" name="spinBox_octomap_pointSize">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>99</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
Reference in New Issue
Block a user