ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange |
1 | initial version |
In the end, I've found a solution.
Using a global variable std::weak_ptr<MyNode> MyNode::instance_;
, I've initialized it in the main and registered it as a signal handler:
// Set the instance pointer to the shared pointer of the main node
MyNode::setInstance(node);
// Register the signal handler for SIGINT (CTRL+C)
signal(SIGINT, MyNode::signalHandler);
before adding and spinning the node.
I had to add some function to the node, of course:
class MyNode : public rclcpp::Node {
public:
std::atomic<bool> is_terminated_ {false};
void stopThread();
void startThread();
static void signalHandler(int signum);
static std::shared_ptr<MyNode> getInstance();
static void setInstance(rclcpp::Node::SharedPtr instance);
private:
std::thread helping_thread_;
static std::weak_ptr<MyNode> instance_; // Weak pointer to the instance of the node
}
void MyNode::setInstance(rclcpp::Node::SharedPtr instance) {
instance_ = std::static_pointer_cast<MyNode>(instance);
}
std::shared_ptr<MyNode> MyNode::getInstance() {
return instance_.lock();
}
void MyNode::signalHandler(int signum) {
// Stop the thread gracefully
std::shared_ptr<MyNode> node = getInstance();
if (node) {
node->stopThread();
}
rclcpp::shutdown();
}
void MyNode::startThread() {
if (!this->helping_thread_.joinable()) {
this->helping_thread_ = std::thread(&MyNode::spawnedThread, this);
}
}
void MyNode::stopThread() {
if (this->helping_thread_.joinable()) {
this->is_terminated_ = true;
this->helping_thread_.join();
}
}
where spawnedThread
is the main function used in the additional thread.
I don't really like using global variables and such, but for now this works as intended.