struct mola::TSDF::TInsertionOptions
Overview
Options for insertObservation()
#include <TSDF.h> struct TInsertionOptions: public mrpt::config::CLoadableOptions { // fields bool bootstrap_with_points = true; uint32_t bootstrap_min_scans = 10; uint32_t bootstrap_max_scans = 200; double bootstrap_field_ready_fraction = 0.9; uint32_t bootstrap_knn = 10; double bootstrap_max_plane_deviation = 0.5; double truncation_distance = .0; double truncation_voxels = 4.0; double ray_tube_voxels = 1.5; double tube_sigma_voxels = 0.4; double max_weight = 64.0; double min_weight_for_query = 1.0; double remove_voxels_farther_than = .0; uint64_t max_voxels = 0; bool weight_by_range = false; double weight_range_ref = 10.0; bool weight_by_incidence = false; // methods void loadFromConfigFile( const mrpt::config::CConfigFileBase& source, const std::string& section ); void dumpToTextStream(std::ostream& out) const; void writeToStream(mrpt::serialization::CArchive& out) const; void readFromStream(mrpt::serialization::CArchive& in); };
Fields
bool bootstrap_with_points = true
Answer queries from a point cloud accumulated over the first scans, and switch to the field once the field can answer.
A field map is empty in a way a point map is not. One scan of points is immediately queryable; one scan of field is not, because a trilinear query needs all eight surrounding voxels and adjacent beams are more than a voxel apart at working range. Without a warm-up the first registration finds no surface at all, the caller discards the map as a failed start, and the run never gets going.
uint32_t bootstrap_min_scans = 10
Scans to accumulate before the field is tested at all.
This and bootstrap_max_plane_deviation interact, and neither works alone: on the sequences a fine voxel fails to start, lengthening the warm-up by itself and loosening the plane test by itself each leave the run incomplete, while doing both completes it.
uint32_t bootstrap_max_scans = 200
Hard bound on the warm-up, in scans. If the field still cannot answer by then, the switch happens anyway and a message is printed: a map that quietly stayed a point cloud under this class’s name would misreport what was measured.
double bootstrap_field_ready_fraction = 0.9
Fraction of the last scan’s points at which the field must return a valid query for the warm-up to end.
uint32_t bootstrap_knn = 10
Neighbors used for the warm-up plane fit.
double bootstrap_max_plane_deviation = 0.5
Maximum distance [m] any neighbor may sit from the plane fitted through the neighborhood, for that plane to be used, or <=0 to accept every fit.
The default is deliberately loose, near the decimation voxel size of a typical pipeline, because the warm-up turns out to need many pairings more than it needs good ones: a poorly fitted plane is diluted by the others in the same solve, while a rejected one removes its information outright. Tightening this starves the first registrations and the run fails to start, which is the very thing the warm-up exists to prevent.
double truncation_distance = .0
Half-width of the band updated around each surface, in meters. If <=0, it defaults to truncation_voxels times the voxel size. This is also the maximum distance at which a query can find a surface, so it must comfortably exceed the expected registration prior error.
double truncation_voxels = 4.0
Used only when truncation_distance is <= 0.
double ray_tube_voxels = 1.5
Radius of the cylinder around each measurement ray that receives samples, in units of the voxel size. This is the coverage knob: it has to reach at least half the spacing between adjacent beams at working range, or the field is undefined between them and most scan points find no surface to pair against.
double tube_sigma_voxels = 0.4
Standard deviation of the Gaussian profile applied across the tube, in units of the voxel size, or <=0 for a flat profile. This is the bias knob, and it is separate from the coverage one on purpose.
A sample is stored as its distance along its own ray, which for an off-axis voxel over-estimates the distance to the surface, so averaging samples over a wide tube pushes the zero level set away from the sensor. Making the profile narrow keeps the average dominated by near-axis rays while the cutoff above still fills the gaps between beams.
double max_weight = 64.0
Weight cap of a voxel. It bounds how slowly the field can follow a change in the scene, and it is what makes the average a running one.
double min_weight_for_query = 1.0
Minimum accumulated weight for a voxel to take part in a query.
double remove_voxels_farther_than = .0
If !=0, remove voxels farther (Chebyshev distance) than this, in meters, from the current sensor pose.
A field map must not be given a point map’s extent. It allocates a band of voxels around every surface rather than one cell per measured point, so its footprint grows with the retained volume and with the inverse cube of the voxel size, not with the point count.
uint64_t max_voxels = 0
If !=0, a hard ceiling on the number of voxels. Once exceeded, the effective extent is shrunk until the map fits, so the footprint is bounded whatever the voxel size, the scene density or the trajectory.
This exists because remove_voxels_farther_than alone does not bound anything usefully: at a fixed extent the voxel count still scales as the inverse cube of the voxel size and with how much surface the scene puts inside that extent, and a run that diverges sweeps an arbitrary volume. Measured on kitti-05 at a 0.3 m voxel, a 155 m extent peaked at 110 GB.
The eviction is by distance, not by age, so it stays a pure function of the map contents and the sensor pose and does not depend on insertion order.
bool weight_by_range = false
If true, each sample is weighted by (ref_range/range)^2, the usual range-dependent confidence of a range measurement. Default off, so the map class is one axis on its own.
double weight_range_ref = 10.0
Reference range for weight_by_range, in meters.
bool weight_by_incidence = false
If true, each sample is weighted by the cosine of the incidence angle between the ray and the local surface normal, approximated by the field gradient already present. Default off, for the same reason.