0
$\begingroup$

Rosanswers logo

I used the following link to create the MultiThreadedExecutor code I have written bellow.

The issue I am having is that when using ctrl + c, I receive a

[INFO] [rclcpp]: signal_handler(signal_value=2)

message but, the thread still hangs. I do not quite understand how the ROS2 signal handler works. Is there a way I can catch the [INFO] [rclcpp]: signal_handler(signal_value=2) message to exit out of the spin and close the program?

using rclcpp::executors::MultiThreadedExecutor;
using builtin_interfaces::msg::Time;

std::shared_ptr<rclcpp::Node> master_node;

int value=0;


class test{

public:
    static void topic_callback(test_msgs::msg::Test::SharedPtr msg)
  {
    std::cout  <<" Subscriber Received [" << msg->data << "]" << std::endl;
    value = msg->data;
  }

};

int main()
{

  rclcpp::shutdown();
  test *t;
  t = new test();
  rclcpp::init(0, nullptr);

  MultiThreadedExecutor executor;
  master_node = rclcpp::Node::make_shared("MasterNode");
  executor.add_node(master_node); 


  rclcpp::Publisher<test_msgs::msg::Test2>::SharedPtr publisher_;
  rclcpp::Subscription<test_msgs::msg::Test>::SharedPtr subscription_;


  subscription_ = master_node->create_subscription<test_msgs::msg::Test>("Test",t->topic_callback);  
  publisher_ =  master_node->create_publisher<test_msgs::msg::Test2>("Test2");
  rclcpp::Clock ros_clock(RCL_ROS_TIME);
  Time ros_now = ros_clock.now();
  std::thread executor_thread(std::bind(&MultiThreadedExecutor::spin, &executor));
  executor_thread.detach();


while(rclcpp::is_initialized)
  {
    auto message = test_msgs::msg::Test();
    message.header.stamp.nanosec = ros_now.nanosec;
    publisher_->publish(message);
    usleep(3000000);
  } 
    rclcpp::shutdown();

}

Originally posted by Obeseturtle on ROS Answers with karma: 185 on 2019-03-05

Post score: 1


Original comments

Comment by William on 2019-03-06:
Btw, why do you start with rclcpp::shutdown()?

Comment by William on 2019-03-06:
Why are you detaching the thread? Why not join it at the end of the main loop. spin() will exit when SIGINT is received automatically.

Comment by Obeseturtle on 2019-03-06:
The main thread has to be independent to the child thread that is used for the subscriber callback. The main thread is used to make heavy calculations and is constantly jumping to other classes. If i use join, the main thread gets stuck in the callback.

Comment by Obeseturtle on 2019-03-06:
The reason I start with rclcpp::shutdown() is because the node took a while before shutting down. Sometimes when using ros2 node list, I would have multiple instances of the same node. I researched this issue and in one of the discussions it was mentioned to better have a shutdown in the beginning.

Comment by Obeseturtle on 2019-03-06:
I will try to find the discussion and link to it.

Comment by Dirk Thomas on 2019-03-07:
If you are literally using while(rclcpp:ok) you are missing the parenthesis again to actually call the function (same as in the original snippet with while(rclcpp::is_initialized)).

Comment by Obeseturtle on 2019-03-07:
I understand now. I have tried using while(rclcpp::ok()) and the example program shuts down. The segmentation fault I am experiencing in my main program is being caused by something else. The rclcpp shutdown is being properly called. Thank you for the patients you have showed.

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

The condition rclcpp::is_initialized seems wrong. It doesn't actually call the function.

Please try rclcpp::ok() instead.


Originally posted by Dirk Thomas with karma: 16276 on 2019-03-06

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by William on 2019-03-06:
Those functions are the same: http://docs.ros2.org/crystal/api/rclcpp/namespacerclcpp.html#ac9460447dae147a331cab70668a7ddd2

Comment by William on 2019-03-06:
But rclcpp::ok() is the "right" thing to use going forward.

Comment by Obeseturtle on 2019-03-06:
Thank you, I will make sure to use rclcpp::ok() from now on. The underline problem still exist though. The SIGINT is being captured by ROS2 executor. I wanted to catch it using my main program and some how tell the executor to shutdown. I tried executor.cancle(); with no avail.

Comment by Obeseturtle on 2019-03-06:
What happens is that the main thread shuts down but, the ROS2 executor is still running causing a segmentation error. Is there a proper way to access the rclcpp::signal_handler and exit out of the executor spin? I apologize for the inconvenience.

Comment by William on 2019-03-06:
The spin should stop automatically if the signal handler is being run (which it appears to be since you are getting the log message).

Comment by William on 2019-03-06:
You can register a callback for "on shutdown" rather than installing your own signal handler: http://docs.ros2.org/crystal/api/rclcpp/namespacerclcpp.html#a01e2c223964ccca7ede393af47fac025

Comment by Obeseturtle on 2019-03-06:
Thank you for your reply. As you mentioned, the signal handler is being run and the subscriber callback thread is being shutdown. The While loop will not exit though, meaning that the main thread is active. If I understood you correctly, the "on shutdown" should be used to end the main thread?

Comment by William on 2019-03-06:
You said there is a segmentation fault? You should update your question with the crash details. You only need the on_shutdown if you need to do something special for SIGINT, that's not the case here.

Comment by Obeseturtle on 2019-03-06:
The segmentation fault occurs in the main program. The main program inits a singleton class which I use to create the Main ROS Node and a executor, this executor uses a child thread for the callbacks. The main thread has its own SIGINT handler but, the executor's spin is capturing the signal 1st

Comment by Obeseturtle on 2019-03-06:
The main thread shuts down after the child thread but, I receive a segmentation fault. If the program is shutdown properly without using ctrl+c. The deconstructor for the singleton class is called which then uses the rclcpp::shutdown meaning I do not receive the segmentation fault.

Comment by Obeseturtle on 2019-03-06:
This is why I want to control the sequence of the shutdown. If I do this, I could call each deconstructor in order avoiding the segmentation fault. The only problem is that my c++ is not at a level which I could understand how to properly exit out of the executors spin

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.