class mola::PointTimeOutlierFilter

Overview

Drops the points of a LiDAR scan whose per-point time (the “t” field) is far outside the range that the previous scans of the same sensor had.

Per-point times come from the sensor clock. A clock that jumps (e.g. a timing input with spurious edges) gives some columns of a scan times that are seconds away from the rest, and the scan reference time (e.g. the middle of its time range) then moves by that much.

The usual range is the median of the minimum and of the maximum time of the last window_length scans, as given (before this filter), so a minority of bad scans in the window does not move it. It is widened by a margin: the largest of margin_ratio of its width, min_margin, and the sensor period (median interval between consecutive scan stamps), so that sensors that only report the directions with returns (a narrow sector one moment, the whole sweep the next) never lose points of a normal sweep. A scan within that band is accepted as is; otherwise, the points out of it are removed, with all their fields. Nothing is removed until the window holds min_window_length scans.

Cost: one pass over the time field per scan; a second one, compacting all fields in place, only for scans with outliers.

One instance per sensor: different sensors have different time ranges.

#include <PointTimeOutlierFilter.h>

class PointTimeOutlierFilter
{
public:
    // structs

    struct Parameters;
    struct Result;

    // construction

    PointTimeOutlierFilter();
    PointTimeOutlierFilter(const Parameters& p);

    // methods

    Result process(const std::vector<mrpt::maps::CPointsMap*>& clouds, double stamp);
    Result check(const std::vector<mrpt::maps::CPointsMap*>& clouds) const;
    std::optional<std::pair<double, double>> usual_range() const;
    std::optional<std::pair<double, double>> accepted_range() const;
    const Parameters& parameters() const;
    void reset();

    static std::size_t remove_points(
        mrpt::maps::CPointsMap& pc,
        const std::vector<uint8_t>& keep
        );
};

Methods

Result process(const std::vector<mrpt::maps::CPointsMap*>& clouds, double stamp)

Checks one scan, given as the point clouds (layers) of one observation taken at stamp [s]. Clouds without a “t” field are ignored. The scan time range and stamp are added to the window afterwards.

Result check(const std::vector<mrpt::maps::CPointsMap*>& clouds) const

As process(), but against the current window only, which is left unchanged (e.g. to re-process old scans with what was learned live).

std::optional<std::pair<double, double>> usual_range() const

The usual time range [min, max] of the window, once it is warmed up.

std::optional<std::pair<double, double>> accepted_range() const

The range a scan must be within, once the window is warmed up.

static std::size_t remove_points(
    mrpt::maps::CPointsMap& pc,
    const std::vector<uint8_t>& keep
    )

Removes, in place and keeping the order, the points of pc whose keep entry is zero, from all its fields.

Returns:

removed points.