Robotics StackExchange | Archived questions

MultiThreadedExecutor thread affinity for certain callbacks?

I'd like have certain callbacks have thread affinity and others get whatever they are handed from the pool. There is some related affinity discussion here from a few years ago: https://github.com/ros2/rclcpp/issues/108

In my current case it is a timer update that needs to run on the same thread id, while service and topic callbacks ought to run concurrently on any thread available (subject to lock guards where needed within them).

I'd like to do something expedient in the short term but also make progress towards a better and longer term solution (if in discussion only).

Some ideas come to mind:

Asked by lucasw on 2019-01-25 19:28:48 UTC

Comments

It's looking like std::async and rclcpp::WallRate with the number 2 option will work for me.

Asked by lucasw on 2019-01-25 21:18:16 UTC

Not an answer, but perhaps can be a(nother) source of inspiration/information: Mixed Real-Time Criticality with ROS2 - the Callback-group-level Executor (slides).

Asked by gvdhoorn on 2019-01-27 04:11:18 UTC

Answers

In one case I had a couple of nodes, one which needed a single thread and the other which doesn't care about thread affinity but blocks for a long time (it needs to do something other than select() and block).

Below I spin the one node in a regular std::thread and the other runs separate for that (maybe for symmetry it ought to be in another std thread also...):

void run_usb_cam(FooType foo)
{
  rclcpp::executors::SingleThreadedExecutor executor;
  auto usb_cam = std::make_shared<usb_cam::UsbCam>(foo);
  executor.add_node(usb_cam);
  executor.spin();
}
...

  rclcpp::executors::SingleThreadedExecutor single_executor;
  // imgui_ros has to be single threaded for now to avoid context switches with opengl
  auto imgui_ros = std::make_shared<imgui_ros::ImguiRos>(foo);
  single_executor.add_node(imgui_ros);

  std::thread cam_thread(std::bind(run_usb_cam, foo));
  single_executor.spin();
  cam_thread.join();

https://github.com/lucasw/imgui_ros/blob/crystal/imgui_ros/src/nodes/usb_cam_viewer.cpp

I initially tried a while loop with spin_some on both executors, but even if one of the executors is multi threaded spin_some doesn't return until all the jobs it was running (however concurrently) are complete, so it blocks the other executor.

Asked by lucasw on 2019-02-04 16:10:35 UTC

Comments