mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 17:40:23 +08:00
Parameters: Changed Grid/FromDepth to Grid/Sensor to add a new choice to use both scan and depth for local grids. Increased version to 0.20.15.
This commit is contained in:
@@ -58,7 +58,7 @@ public:
|
||||
float getCellSize() const {return cellSize_;}
|
||||
void setCloudAssembling(bool enabled);
|
||||
float getMinMapSize() const {return minMapSize_;}
|
||||
bool isGridFromDepth() const {return occupancyFromDepth_;}
|
||||
bool isGridFromDepth() const {return occupancySensor_;}
|
||||
bool isFullUpdate() const {return fullUpdate_;}
|
||||
float getUpdateError() const {return updateError_;}
|
||||
bool isMapFrameProjection() const {return projMapFrame_;}
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
cv::Mat & groundCells,
|
||||
cv::Mat & obstacleCells,
|
||||
cv::Mat & emptyCells,
|
||||
cv::Point3f & viewPoint) const;
|
||||
cv::Point3f & viewPoint);
|
||||
|
||||
void createLocalMap(
|
||||
const LaserScan & cloud,
|
||||
@@ -118,7 +118,7 @@ private:
|
||||
int scanDecimation_;
|
||||
float cellSize_;
|
||||
bool preVoxelFiltering_;
|
||||
bool occupancyFromDepth_;
|
||||
int occupancySensor_;
|
||||
bool projMapFrame_;
|
||||
float maxObstacleHeight_;
|
||||
int normalKSearch_;
|
||||
|
||||
@@ -723,15 +723,15 @@ class RTABMAP_EXP Parameters
|
||||
#endif
|
||||
|
||||
// Occupancy Grid
|
||||
RTABMAP_PARAM(Grid, FromDepth, bool, true, "Create occupancy grid from depth image(s), otherwise it is created from laser scan.");
|
||||
RTABMAP_PARAM(Grid, Sensor, int, 1, "Create occupancy grid from selected sensor: 0=laser scan, 1=depth image(s) or 2=both laser scan and depth image(s).");
|
||||
RTABMAP_PARAM(Grid, DepthDecimation, unsigned int, 4, uFormat("[%s=true] Decimation of the depth image before creating cloud.", kGridDepthDecimation().c_str()));
|
||||
RTABMAP_PARAM(Grid, RangeMin, float, 0.0, "Minimum range from sensor.");
|
||||
RTABMAP_PARAM(Grid, RangeMax, float, 5.0, "Maximum range from sensor. 0=inf.");
|
||||
RTABMAP_PARAM_STR(Grid, DepthRoiRatios, "0.0 0.0 0.0 0.0", uFormat("[%s=true] Region of interest ratios [left, right, top, bottom].", kGridFromDepth().c_str()));
|
||||
RTABMAP_PARAM_STR(Grid, DepthRoiRatios, "0.0 0.0 0.0 0.0", uFormat("[%s>=1] Region of interest ratios [left, right, top, bottom].", kGridSensor().c_str()));
|
||||
RTABMAP_PARAM(Grid, FootprintLength, float, 0.0, "Footprint length used to filter points over the footprint of the robot.");
|
||||
RTABMAP_PARAM(Grid, FootprintWidth, float, 0.0, "Footprint width used to filter points over the footprint of the robot. Footprint length should be set.");
|
||||
RTABMAP_PARAM(Grid, FootprintHeight, float, 0.0, "Footprint height used to filter points over the footprint of the robot. Footprint length and width should be set.");
|
||||
RTABMAP_PARAM(Grid, ScanDecimation, int, 1, uFormat("[%s=false] Decimation of the laser scan before creating cloud.", kGridFromDepth().c_str()));
|
||||
RTABMAP_PARAM(Grid, ScanDecimation, int, 1, uFormat("[%s=0 or 2] Decimation of the laser scan before creating cloud.", kGridSensor().c_str()));
|
||||
RTABMAP_PARAM(Grid, CellSize, float, 0.05, "Resolution of the occupancy grid.");
|
||||
RTABMAP_PARAM(Grid, PreVoxelFiltering, bool, true, uFormat("Input cloud is downsampled by voxel filter (voxel size is \"%s\") before doing segmentation of obstacles and ground.", kGridCellSize().c_str()));
|
||||
RTABMAP_PARAM(Grid, MapFrameProjection, bool, false, "Projection in map frame. On a 3D terrain and a fixed local camera transform (the cloud is created relative to ground), you may want to disable this to do the projection in robot frame instead.");
|
||||
@@ -745,9 +745,9 @@ class RTABMAP_EXP Parameters
|
||||
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()));
|
||||
#ifdef RTABMAP_OCTOMAP
|
||||
RTABMAP_PARAM(Grid, 3D, bool, true, uFormat("A 3D occupancy grid is required if you want an OctoMap (3D ray tracing). Set to false if you want only a 2D map, the cloud will be projected on xy plane. A 2D map can be still generated if checked, but it requires more memory and time to generate it. Ignored if laser scan is 2D and \"%s\" is false.", kGridFromDepth().c_str()));
|
||||
RTABMAP_PARAM(Grid, 3D, bool, true, uFormat("A 3D occupancy grid is required if you want an OctoMap (3D ray tracing). Set to false if you want only a 2D map, the cloud will be projected on xy plane. A 2D map can be still generated if checked, but it requires more memory and time to generate it. Ignored if laser scan is 2D and \"%s\" is 0.", kGridSensor().c_str()));
|
||||
#else
|
||||
RTABMAP_PARAM(Grid, 3D, bool, false, uFormat("A 3D occupancy grid is required if you want an OctoMap (3D ray tracing). Set to false if you want only a 2D map, the cloud will be projected on xy plane. A 2D map can be still generated if checked, but it requires more memory and time to generate it. Ignored if laser scan is 2D and \"%s\" is false.", kGridFromDepth().c_str()));
|
||||
RTABMAP_PARAM(Grid, 3D, bool, false, uFormat("A 3D occupancy grid is required if you want an OctoMap (3D ray tracing). Set to false if you want only a 2D map, the cloud will be projected on xy plane. A 2D map can be still generated if checked, but it requires more memory and time to generate it. Ignored if laser scan is 2D and \"%s\" is 0.", kGridSensor().c_str()));
|
||||
#endif
|
||||
RTABMAP_PARAM(Grid, GroundIsObstacle, bool, false, uFormat("[%s=true] Ground segmentation (%s) is ignored, all points are obstacles. Use this only if you want an OctoMap with ground identified as an obstacle (e.g., with an UAV).", kGrid3D().c_str(), kGridNormalsSegmentation().c_str()));
|
||||
RTABMAP_PARAM(Grid, NoiseFilteringRadius, float, 0.0, "Noise filtering radius (0=disabled). Done after segmentation.");
|
||||
|
||||
@@ -52,7 +52,7 @@ OccupancyGrid::OccupancyGrid(const ParametersMap & parameters) :
|
||||
scanDecimation_(Parameters::defaultGridScanDecimation()),
|
||||
cellSize_(Parameters::defaultGridCellSize()),
|
||||
preVoxelFiltering_(Parameters::defaultGridPreVoxelFiltering()),
|
||||
occupancyFromDepth_(Parameters::defaultGridFromDepth()),
|
||||
occupancySensor_(Parameters::defaultGridSensor()),
|
||||
projMapFrame_(Parameters::defaultGridMapFrameProjection()),
|
||||
maxObstacleHeight_(Parameters::defaultGridMaxObstacleHeight()),
|
||||
normalKSearch_(Parameters::defaultGridNormalK()),
|
||||
@@ -91,7 +91,7 @@ OccupancyGrid::OccupancyGrid(const ParametersMap & parameters) :
|
||||
|
||||
void OccupancyGrid::parseParameters(const ParametersMap & parameters)
|
||||
{
|
||||
Parameters::parse(parameters, Parameters::kGridFromDepth(), occupancyFromDepth_);
|
||||
Parameters::parse(parameters, Parameters::kGridSensor(), occupancySensor_);
|
||||
Parameters::parse(parameters, Parameters::kGridDepthDecimation(), cloudDecimation_);
|
||||
if(cloudDecimation_ == 0)
|
||||
{
|
||||
@@ -284,12 +284,12 @@ void OccupancyGrid::createLocalMap(
|
||||
cv::Mat & groundCells,
|
||||
cv::Mat & obstacleCells,
|
||||
cv::Mat & emptyCells,
|
||||
cv::Point3f & viewPoint) const
|
||||
cv::Point3f & viewPoint)
|
||||
{
|
||||
UDEBUG("scan format=%s, occupancyFromDepth_=%d normalsSegmentation_=%d grid3D_=%d",
|
||||
node.sensorData().laserScanRaw().isEmpty()?"NA":node.sensorData().laserScanRaw().formatName().c_str(), occupancyFromDepth_?1:0, normalsSegmentation_?1:0, grid3D_?1:0);
|
||||
UDEBUG("scan format=%s, occupancySensor_=%d normalsSegmentation_=%d grid3D_=%d",
|
||||
node.sensorData().laserScanRaw().isEmpty()?"NA":node.sensorData().laserScanRaw().formatName().c_str(), occupancySensor_, normalsSegmentation_?1:0, grid3D_?1:0);
|
||||
|
||||
if((node.sensorData().laserScanRaw().is2d()) && !occupancyFromDepth_)
|
||||
if((node.sensorData().laserScanRaw().is2d()) && occupancySensor_ == 0)
|
||||
{
|
||||
UDEBUG("2D laser scan");
|
||||
//2D
|
||||
@@ -328,7 +328,7 @@ void OccupancyGrid::createLocalMap(
|
||||
else
|
||||
{
|
||||
// 3D
|
||||
if(!occupancyFromDepth_)
|
||||
if(occupancySensor_ == 0 || occupancySensor_ == 2)
|
||||
{
|
||||
if(!node.sensorData().laserScanRaw().isEmpty())
|
||||
{
|
||||
@@ -350,14 +350,35 @@ void OccupancyGrid::createLocalMap(
|
||||
viewPoint = cv::Point3f(t.x(), t.y(), t.z());
|
||||
|
||||
UDEBUG("scan format=%d", scan.format());
|
||||
|
||||
bool normalSegmentationTmp = normalsSegmentation_;
|
||||
float minGroundHeightTmp = minGroundHeight_;
|
||||
float maxGroundHeightTmp = maxGroundHeight_;
|
||||
if(scan.is2d())
|
||||
{
|
||||
// if 2D, assume the whole scan is obstacle
|
||||
normalsSegmentation_ = false;
|
||||
minGroundHeight_ = std::numeric_limits<int>::min();
|
||||
maxGroundHeight_ = std::numeric_limits<int>::min()+100;
|
||||
}
|
||||
|
||||
createLocalMap(scan, node.getPose(), groundCells, obstacleCells, emptyCells, viewPoint);
|
||||
|
||||
if(scan.is2d())
|
||||
{
|
||||
// restore
|
||||
normalsSegmentation_ = normalSegmentationTmp;
|
||||
minGroundHeight_ = minGroundHeightTmp;
|
||||
maxGroundHeight_ = maxGroundHeightTmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UWARN("Cannot create local map, scan is empty (node=%d, %s=false).", node.id(), Parameters::kGridFromDepth().c_str());
|
||||
UWARN("Cannot create local map, scan is empty (node=%d, %s=0).", node.id(), Parameters::kGridSensor().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if(occupancySensor_ >= 1)
|
||||
{
|
||||
pcl::IndicesPtr indices(new std::vector<int>);
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
||||
@@ -407,7 +428,49 @@ void OccupancyGrid::createLocalMap(
|
||||
const Transform & t = node.sensorData().stereoCameraModel().localTransform();
|
||||
viewPoint = cv::Point3f(t.x(), t.y(), t.z());
|
||||
}
|
||||
|
||||
cv::Mat scanGroundCells;
|
||||
cv::Mat scanObstacleCells;
|
||||
cv::Mat scanEmptyCells;
|
||||
if(occupancySensor_ == 2)
|
||||
{
|
||||
// backup
|
||||
scanGroundCells = groundCells.clone();
|
||||
scanObstacleCells = obstacleCells.clone();
|
||||
scanEmptyCells = emptyCells.clone();
|
||||
}
|
||||
|
||||
createLocalMap(LaserScan(util3d::laserScanFromPointCloud(*cloud, indices), 0, 0.0f), node.getPose(), groundCells, obstacleCells, emptyCells, viewPoint);
|
||||
|
||||
if(occupancySensor_ == 2)
|
||||
{
|
||||
if(grid3D_)
|
||||
{
|
||||
// We should convert scans to 4 channels (XYZRGB) to be compatible
|
||||
scanGroundCells = util3d::laserScanFromPointCloud(*util3d::laserScanToPointCloudRGB(LaserScan::backwardCompatibility(scanGroundCells), Transform::getIdentity(), 255, 255, 255)).data();
|
||||
scanObstacleCells = util3d::laserScanFromPointCloud(*util3d::laserScanToPointCloudRGB(LaserScan::backwardCompatibility(scanObstacleCells), Transform::getIdentity(), 255, 255, 255)).data();
|
||||
scanEmptyCells = util3d::laserScanFromPointCloud(*util3d::laserScanToPointCloudRGB(LaserScan::backwardCompatibility(scanEmptyCells), Transform::getIdentity(), 255, 255, 255)).data();
|
||||
}
|
||||
|
||||
UDEBUG("groundCells, depth: size=%d channels=%d vs scan: size=%d channels=%d", groundCells.cols, groundCells.channels(), scanGroundCells.cols, scanGroundCells.channels());
|
||||
UDEBUG("obstacleCells, depth: size=%d channels=%d vs scan: size=%d channels=%d", obstacleCells.cols, obstacleCells.channels(), scanObstacleCells.cols, scanObstacleCells.channels());
|
||||
UDEBUG("emptyCells, depth: size=%d channels=%d vs scan: size=%d channels=%d", emptyCells.cols, emptyCells.channels(), scanEmptyCells.cols, scanEmptyCells.channels());
|
||||
|
||||
if(!groundCells.empty() && !scanGroundCells.empty())
|
||||
cv::hconcat(groundCells, scanGroundCells, groundCells);
|
||||
else if(!scanGroundCells.empty())
|
||||
groundCells = scanGroundCells;
|
||||
|
||||
if(!obstacleCells.empty() && !scanObstacleCells.empty())
|
||||
cv::hconcat(obstacleCells, scanObstacleCells, obstacleCells);
|
||||
else if(!scanObstacleCells.empty())
|
||||
obstacleCells = scanObstacleCells;
|
||||
|
||||
if(!emptyCells.empty() && !scanEmptyCells.empty())
|
||||
cv::hconcat(emptyCells, scanEmptyCells, emptyCells);
|
||||
else if(!scanEmptyCells.empty())
|
||||
emptyCells = scanEmptyCells;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,6 +234,9 @@ const std::map<std::string, std::pair<bool, std::string> > & Parameters::getRemo
|
||||
{
|
||||
// removed parameters
|
||||
|
||||
// 0.20.15
|
||||
removedParameters_.insert(std::make_pair("Grid/FromDepth", std::make_pair(true, Parameters::kGridSensor())));
|
||||
|
||||
// 0.20.9
|
||||
removedParameters_.insert(std::make_pair("OdomORBSLAM2/VocPath", std::make_pair(true, Parameters::kOdomORBSLAMVocPath())));
|
||||
removedParameters_.insert(std::make_pair("OdomORBSLAM2/Bf", std::make_pair(true, Parameters::kOdomORBSLAMBf())));
|
||||
|
||||
Reference in New Issue
Block a user