Closed kenyoshizoe closed 4 months ago
To get access to to the node handle passed into your behavior via
BT::RosNodeParams& params
you need to convert the weak pointer by asking for a lock to it
auto node = params.nh.lock();
I'd like to provide additional information regarding the error message.
The bad_weak_ptr occurred when constructing a tree composed solely of a derived class of RosTopicPubNode. Indeed, in RosTopicPubNode, it appears that weak_ptr is directly assigned to shared_ptr. (I've checked other programs, and it seems that only RosTopicPubNode is using shared_ptr instead of weak_ptr.) https://github.com/BehaviorTree/BehaviorTree.ROS2/blob/8790909163f96a0946ef7504aa3379f4d85ced35/behaviortree_ros2/include/behaviortree_ros2/bt_topic_pub_node.hpp#L87-L88 https://github.com/BehaviorTree/BehaviorTree.ROS2/blob/8790909163f96a0946ef7504aa3379f4d85ced35/behaviortree_ros2/include/behaviortree_ros2/bt_topic_pub_node.hpp#L102-L106
The error message:
Behavior Tree exception: The ROS node went out of scope. RosNodeParams doesn't take the ownership of the node.
was encountered when constructing a tree containing many nodes, so it may take some time to identify which node is causing the issue. It's possible that the implementation of my class, which directly inherits from the behaviortree.cpp class, might be flawed.
I requested to expose rclcpp::Node::SharedPtr
, but it might also be acceptable to use std::weak_ptr<rclcpp::Node>
. (The following code worked correctly when written as follows.)
std::weak_ptr<rclcpp::Node> TreeExecutionServer::node()
{
return std::dynamic_pointer_cast<rclcpp::Node>(p_->node);
}
void registerNodesIntoFactory(BT::BehaviorTreeFactory& factory) {
// Register Nodes
BT::RosNodeParams params;
params.nh = node();
I agree. I will expose that, much easier.
When I implemented the override of
void registerNodesIntoFactory(BT::BehaviorTreeFactory& factory)
, I wrote it like this:This caused the following exceptions during tree construction:
Instead, when I changed the API to directly assign rclcpp::Node::SharedPtr to nh, it worked perfectly. Why doesn't
TreeExecutionServer
directly exposerclcpp::Node::SharedPtr
? If there are no issues, I would like to add an API to directly exposerclcpp::Node::SharedPtr
.