How to understand the difference rclcpp::spin() and rclcpp::executor::Executor::spin_once()?

asked 2018-06-28 00:30:55 -0500

RachelRen gravatar image

environment:ros2,ament,ubuntu 16.04

Hardware connection is normal and use ros2 topic list can get "/movidius_ncs_stream/detected_objects"

1.I don't understand why rclcpp::executor::Executor::spin_once() don't call callback function.

2.When I use executor.spin_until_future_complete(),its result is always timeout.

My code snippet is as follows:

template<typename DurationT>
void wait_for_future(
  rclcpp::executor::Executor & executor,
  std::shared_future<void> & future,
  const DurationT & timeout)
{
  using rclcpp::executor::FutureReturnCode;
  rclcpp::executor::FutureReturnCode future_ret;
  auto start_time = std::chrono::steady_clock::now();
  future_ret = executor.spin_until_future_complete(future, timeout);
  auto elapsed_time = std::chrono::steady_clock::now() - start_time;
  EXPECT_EQ(FutureReturnCode::SUCCESS, future_ret) <<
    "future failed to be set after: " <<
    std::chrono::duration_cast<std::chrono::milliseconds>(elapsed_time).count() <<
    " milliseconds\n";
}
TEST(UnitTestStream, testStream) {
  auto node = rclcpp::Node::make_shared("movidius_ncs_stream_tests");

  std::promise<void> sub_called;
  std::shared_future<void> sub_called_future(sub_called.get_future());

  auto callback = 
  [&sub_called](const object_msgs::msg::ObjectsInBoxes::SharedPtr msg) -> void
  {
     std::cout<<"show image"<<std::endl;
     test_pass = true;
     sub_called.set_value();
  };
  rclcpp::executors::SingleThreadedExecutor executor;
  executor.add_node(node);
  {
    std::cout<<"before"<<std::endl;
    auto sub = node->create_subscription<object_msgs::msg::ObjectsInBoxes>(
      "/movidius_ncs_stream/detected_objects",
      callback,rmw_qos_profile_default);

    sub_called = std::promise<bool>();
    sub_called_future = sub_called.get_future();
    wait_for_future(executor, sub_called_future, std::chrono::seconds(5));
    executor.spin_once(std::chrono::seconds(0));
    EXPECT_TRUE(test_pass);
  }
}
int main(int argc, char ** argv) 
{
  testing::InitGoogleTest(&argc, argv);
  rclcpp::init(argc, argv);
  auto offset = std::chrono::seconds(5);
  system("realsense_ros2_camera &");
  system("api_composition &");
  system(
    "launch `ros2 pkg prefix movidius_ncs_launch`/share/movidius_ncs_launch/launch/"
    "ncs_stream_launch.py &");
  rclcpp::sleep_for(offset);
  int ret = RUN_ALL_TESTS();
  system("killall api_composition &");
  system("killall realsense_ros2_camera &");
  rclcpp::shutdown();
  return ret;
}

the result future_ret is FutureReturnCode::TIMEOUT,I don't know why?

Thanks very much!

edit retag flag offensive close merge delete

Comments

Have you tried increasing the timeout duration? I assume that the EXPECT_TRUE(test_pass) succeeds based on your question?

William gravatar image William  ( 2018-06-28 01:19:51 -0500 )edit

Yes,I have.

I pre-defined test_pass = false,This test can run,but its result is failed.

What puzzles me is why the result of the executor.spin_until_future_complete() is always timeout.

I think that because of the result of the future_ret is timeout resulted in no callback executed

RachelRen gravatar image RachelRen  ( 2018-06-28 06:27:13 -0500 )edit