包含 CallbackGroups 后 ROS 通信没有响应

ROS communication not responding after including CallbackGroups

我有一个关于 ROS2 中 rclcpp 的回调组的问题。我正在尝试以指定的更新速率通过 rclcpp::TimerBase 运行 进行更新周期 运行,同时节点应该在订阅中收听传入消息。据我了解,实现它的方法是使用带有 CallbackGroups 的 MultiThreadExceutor。因此,我创建了一个 Reentrant Type CallbackGroup,我向其中添加了计时器和订阅。但是,一旦我将计时器添加到 CallbackGroup,计时器就会停止工作。也许我忘了什么? CallbackGroups 或 Node 是否需要在指定的上下文中?还是我完全误解了 CallbackGroups 的概念?如果您能提供任何帮助,我们将很高兴!

到目前为止我尝试了什么:SingleThreadExecutor 显示了同样的问题,删除 CallbackGroup 显示了预期的行为,定时器是 运行ning 并且调用了 update()。试图找出问题并发现,它是在 MTE 的 运行(...) 方法期间,在父 class 的 get_next_executable(:::) 中( rclcpp::executor::Executor) 在 Executor 的 wait_for_work(...) 函数中第 447-448 行:

    rcl_ret_t status = rcl_wait(&wait_set_, std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count());

如果我放弃

    memory_strategy_->number_of_ready_timers()

在 MultiThreadedExecutor 中它显示 1,所以计时器似乎已注册,对吧?

头文件:controller_node_test/controller_node_test.h:

#ifndef CONTROLLER_NODE_H
#define CONTROLLER_NODE_H

#include "rclcpp/rclcpp.hpp"
#include "controller_node_test/multi_threaded_executor.hpp"
#include "chrono"
#include <ctime>

using std::placeholders::_1;

namespace controller_node
{
    class ControllerNode : public rclcpp::Node {
        public:
        ControllerNode();
        ~ControllerNode();

        private:

        rclcpp::TimerBase::SharedPtr update_timer_;

        void update();

    };
} // namespace controller_node

源文件:controller_node_test.cpp

#include "controller_node_test/controller_node_test.h"

namespace controller_node
{

    ControllerNode::ControllerNode() : rclcpp::Node("controller_node"){
        rclcpp::callback_group::CallbackGroup::SharedPtr update_group = this->create_callback_group(rclcpp::callback_group::CallbackGroupType::Reentrant);
        update_timer_ = this->create_wall_timer(
                                                                    std::chrono::milliseconds(100),
                                                                    std::bind(&ControllerNode::update, this),
                                                                    update_group);
    }

    ControllerNode::~ControllerNode(){

    }

    void ControllerNode::update(){
        std::cout << "Timer: " << std::this_thread::get_id() << std::endl;
    }
} // namespace controller_node

int main(int argc, char * argv[])
{
    rclcpp::init(argc, argv);
    rclcpp::executors::MultiThreadedExecutor exec;
    auto controller_node = std::make_shared<controller_node::ControllerNode>();
    exec.add_node(controller_node);
    exec.spin();
    rclcpp::shutdown();
    return 0;
}

问题是,

    std::cout << "Timer: " << std::this_thread::get_id() << std::endl;

从来没有被调用,所以计时器根本不工作。

我删除了代码中所有不必要的部分以使您更清楚,所以如果它不能编译请告诉我。非常感谢任何帮助!我只是不明白那里到底发生了什么,现在我需要你的帮助...谢谢!

您对如何使用 CallbackGroups 有了正确的认识。

您发布的示例不起作用的原因:在您的 ControllerNode 构造函数中您声明了一个局部变量 rclcpp::callback_group::CallbackGroup::SharedPtr cbg

当构造函数returns时,指针的引用计数变为0并且CallbackGroup被销毁。您需要保留对 CallbackGroup 的引用,您的示例应该有效。

例如

class ControllerNode : public rclcpp::Node {
public:
  ControllerNode() : rclcpp::Node("controller_node") {
    cbg_ = create_callback_group(rclcpp::callback_group::CallbackGroupType::Reentrant);
    update_timer_ = create_wall_timer(
      100ms, std::bind(&ControllerNode::update, this), cbg_);
  }

private:
  rclcpp::TimerBase::SharedPtr update_timer_;
  rclcpp::callback_group::CallbackGroup::SharedPtr cbg_;
  void update() {
    std::cout << "Timer: " << std::this_thread::get_id() << std::endl;
  }
};