Closed laurafbec closed 1 year ago
I believe @sea-bass has modified the code to allow passing of the node as a parameter. There's a pull request on pytree's GitHub for it and so you will need to build from source to use his examples. I'm running rolling on 20.04 so I have to build everything from source. I just followed the package installs/build process from the dockerfile and it worked well (it uses @sea-bass 's fork of py_trees_ros)
Thanks @madgrizzle!! I'm been using the cpp lib but I think that this is the problem! thanks again!!
Yeah, seems my response was completely off-base since you aren't using py-trees :) But that's weird to me nevertheless.
:D Yes...I've tried by building behaviortree_cpp from source instead using the ROS2 package but I've the same problem...I don't know...
@laurafbec Are you getting issues with running the examples themselves, or is this you playing with the code?
Either way, this all stems from my own example code and should have nothing to do with behaviortree.cpp library.
GetLocationFromQueue
is a custom node that indeed takes an extra argument in the constructor, which is a pointer to a ROS2 node.
In src/autonomy_node.cpp
, there is this helper function:
// Helper to register behaviors that accept a pointer to a ROS node.
template <class NodeBehaviorT>
void registerRosNodeType(BT::BehaviorTreeFactory& factory,
const std::string& registration_ID,
rclcpp::Node::SharedPtr node_ptr) {
BT::NodeBuilder builder = [=](const std::string& name,
const BT::NodeConfiguration& config) {
return std::make_unique<NodeBehaviorT>(name, config, node_ptr);
};
factory.registerBuilder<NodeBehaviorT>(registration_ID, builder);
}
Meaning if you want to register this node for building a behavior tree, you must use this helper and not the regular node registration method. For example:
// Will not work
factory.registerNodeType<GetLocationFromQueue>("SetLocations");
// Should work
// NOTE: shared_from_this() is a pointer to the ROS2 node, since we're calling it from a node's member function.
registerRosNodeType<GetLocationFromQueue>(factory, "GetLocationFromQueue", shared_from_this());
If you actually roll back to the commit before the latest, you'll see this example wasn't always the case. Before, these nodes had the standard 2-arg constructor meaning you could use BT::BehaviorTreeFactory::registerNodeType
, but then had to override the init()
function of each node to pass in the node pointer after registration. IMO the code was not as nice that way and this latest change was directly recommended by the behaviortree.cpp developer.
Hope this helps!
Thanks @sea-bass!! I was playing with the code. I've tested it some days ago but I've realized you made some changes that simplify the code and avoid the init() function, so I wanted to test them. I didn't realized the register process has changed. Thanks again for your help and your work! It's very helpful for beginners!
Great to hear that was it, and thank you for the kind words :)
Hi @sea-bass! Thanks for your repo. It's being very useful to me in order to start learning BTs on ROS2. When testing this definition of the constructor GetLocationFromQueue
I get the error
$HOME/turtlebot3_ws/install/behaviortree_cpp_v3/include/behaviortree_cpp_v3/bt_factory.h:338:45: error: static assertion failed: [registerNode]: the registered class must have at least one of these two constructors: (const std::string&, const NodeConfiguration&) or (const std::string&).
Is it due to the behaviortreecpp lib version in ROS2 galactic package? Thanks in advance