Lucyanno Frota
Lucyanno Frota

Reputation: 92

Point Cloud Library (PCL) filtering timeout

I have a function that shoud run in a controlled amount of time. But this function uses pcl::StatisticalOutlierRemoval and i didn't find any reasonable way to cancel the this function other than killing the thread arbitrarily.

I have something like this:

void cloud_filtering(pcl::PointCloud<pcl::PointXYZRGB>::SharedPtr pcl_unfilt, pcl::PointCloud<pcl::PointXYZRGB>::SharedPtr pcl_filt) const{

      // do something

      pcl::StatisticalOutlierRemoval<pcl::PointXYZRGB> sor;
      sor.setInputCloud(*pcl_unfilt);
      sor.setMeanK(50);
      sor.setStddevMulThresh(1.0);
      sor.filter(*pcl_filt);

      // do something

}

This function is executed by an independent thread that should have some timeout. The thread is launched using std::async and the completion is checked using the returned future.

auto future = std::async(
      std::launch::async,
      &cloud_filtering,this,pcl_unfilt,pcl_filt
)

Usually, this function is executed pretty fast, but not always, and I don't really need all the responses (It depends on the sampled input of the function). So what I want to do is, if the function takes more than a given timeout it gets safely canceled so I can launch a new thread with other samples.

By safely canceled I mean avoid memory leaks or zombie threads.

Upvotes: 2

Views: 148

Answers (1)

Lemonina
Lemonina

Reputation: 915

#include <future>
#include <chrono>

void cloud_filtering(pcl::PointCloud<pcl::PointXYZRGB>::SharedPtr pcl_unfilt, pcl::PointCloud<pcl::PointXYZRGB>::SharedPtr pcl_filt, std::promise<void>&& promise) const{
    // do something
    
    pcl::StatisticalOutlierRemoval<pcl::PointXYZRGB> sor;
    sor.setInputCloud(*pcl_unfilt);
    sor.setMeanK(50);
    sor.setStddevMulThresh(1.0);
    sor.filter(*pcl_filt);

    // do something

    promise.set_value(); // signal completion
}

// function to call with a timeout
bool cloud_filtering_with_timeout(pcl::PointCloud<pcl::PointXYZRGB>::SharedPtr pcl_unfilt, pcl::PointCloud<pcl::PointXYZRGB>::SharedPtr pcl_filt, int timeout_ms) {
    std::promise<void> promise;
    auto future = promise.get_future();
    auto task = std::async(std::launch::async, &cloud_filtering, this, pcl_unfilt, pcl_filt, std::move(promise));
    bool completed = false;
    if (future.wait_for(std::chrono::milliseconds(timeout_ms)) == std::future_status::timeout) {
        // timeout occurred, cancel task
        task.get(); // this will call std::terminate() if the task is still running
        completed = false;
    } else {
        completed = true;
    }
    return completed;
}
  • cloud_filtering_with_timeout takes input point clouds + timeout in milliseconds -- returns boolean value(whether the function completed before the timeout or not)

std::promise signals cloud_filtering completion -- std::future waits for completion with timeout(timeout occurs before function completes -- task.get() call will cancel the task - throws std::future_error -- will be caught + ignored by std::async)

PS. isn't a clean way to cancel pcl::StatisticalOutlierRemoval but should avoid memory leaks and zombie threads

Upvotes: 1

Related Questions