包含 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;
}
};
我有一个关于 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;
}
};