Class CallbackWrapperBase

Inheritance Relationships

Derived Type

Class Documentation

class CallbackWrapperBase

Object that wraps a generic function call so that it may be inserted into a ROS callback queue.

Once inserted, the function will be called from within the thread that services that callback queue. It will be intermingled with any other standard ROS callbacks (message subscription callbacks, service callbacks, timer callbacks, etc.), analogous to adding callbacks for an additional topic subscriber.

boost::bind/std::bind can be used to provide input arguments. Note that bind() uses a pass-by- value mechanism. If arguments should be passed by reference instead (i.e. copies are expensive or the function modifies the input in place), wrap the input arguments with boost::ref() or std::ref().

The CallbackWrapper class uses the C++11 promise/future mechanism to provide the return data after the callback has been executed in the callback queue’s thread. This is done by getting a future<T> from the CallbackWrapper before it is inserted into the callback queue. You can then block until the return value is ready by calling future.wait(), and the value can be retrieved using future.get(). Even if the function returns void, it can still be useful to get a copy of the CallbackWrapper’s future. The future.wait() function is still valid for void types, thus allowing you to block until the callback function has been executed.

See C++11 documentation for more details on promises and futures:

Example usage:

class MyClass
{
public:
  double processData(const std::vector<double>& data)
  {
    return std::accumulate(data.begin(), data.end(), 0.0);
  }
};

auto callback_queue = std::make_shared<CallbackAdapter>(
  rclcpp::contexts::get_global_default_context());
node->get_node_waitables_interface()->add_waitable(callback_queue, (rclcpp::CallbackGroup::SharedPtr) nullptr);
MyClass my_object;
std::vector<double> really_big_data(1000000);
auto callback = boost::make_shared<CallbackWrapper<double> >(
  std::bind(&MyClass::processData, &my_object, std::ref(really_big_data)));
callback_queue->add_callback(callback);
std::future<double> result = callback->getFuture();
result.wait();
RCLCPP_INFO_STREAM(rclcpp::get_logger("fuse"), "The result is: " << result.get());

Subclassed by fuse_core::CallbackWrapper< T >

Public Functions

virtual void call() = 0

Call this function. This is used by the callback queue.