Closed
Description
Describe the bug
Using release 4.6.2.
I was trying to register a node that depends on an interface in its constructor:
#include <behaviortree_cpp/bt_factory.h>
// interface
struct IMotor {
virtual void doMove() = 0;
};
// implementation
struct LinearMotor : public IMotor {
void doMove() override {}
};
// node using interface
class PathFollow : public BT::StatefulActionNode {
public:
PathFollow(const std::string& name, const BT::NodeConfig& config, IMotor& motor)
: BT::StatefulActionNode(name, config), imotor_(motor) {}
static BT::PortsList providedPorts() { return {}; }
BT::NodeStatus onStart() override { return BT::NodeStatus::SUCCESS; }
BT::NodeStatus onRunning() override { return BT::NodeStatus::SUCCESS; }
void onHalted() override {}
private:
IMotor& imotor_;
};
int main() {
LinearMotor motor;
BT::BehaviorTreeFactory factory;
factory.registerNodeType<PathFollow>("PathFollow", motor);
factory.registerNodeType<PathFollow>("PathFollow", PathFollow::providedPorts(), motor);
factory.registerNodeType<PathFollow, LinearMotor&>("PathFollow", PathFollow::providedPorts(), motor);
factory.registerNodeType<PathFollow, IMotor&>("PathFollow", PathFollow::providedPorts(), motor);
}
Trying different ways to register the node, none of them compile. Is there a way to use an interface as an extra argument? Already checked the tutorial 8 and normal examples with values compile without problems.
Here is the compilation output:
In file included from /interface.cc:1:
/usr/local/include/behaviortree_cpp/bt_factory.h: In instantiation of ‘void BT::BehaviorTreeFactory::registerNodeType(const string&, ExtraArgs ...) [with T = PathFollow; ExtraArgs = {LinearMotor}; std::string = std::__cxx11::basic_string<char>]’:
/interface.cc:30:39: required from here
/usr/local/include/behaviortree_cpp/bt_factory.h:379:21: error: static assertion failed: [registerNode]: since you have a static method providedPorts(),
you MUST add a constructor with signature:
(const std::string&, const NodeConfig&)
379 | static_assert(!(has_static_ports_list && !param_constructable),
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/behaviortree_cpp/bt_factory.h:379:21: note: ‘((!(bool)has_static_ports_list) || ((bool)param_constructable))’ evaluates to false
/usr/local/include/behaviortree_cpp/bt_factory.h: In instantiation of ‘void BT::BehaviorTreeFactory::registerNodeType(const string&, const PortsList&, ExtraArgs ...) [with T = PathFollow; ExtraArgs = {LinearMotor}; std::string = std::__cxx11::basic_string<char>; BT::PortsList = std::unordered_map<std::__cxx11::basic_string<char>, BT::PortInfo>]’:
/interface.cc:31:39: required from here
/usr/local/include/behaviortree_cpp/bt_factory.h:343:41: error: static assertion failed: [registerNode]: the registered class must have at least one of these two constructors:
(const std::string&, const NodeConfig&) or (const std::string&)
Check also if the constructor is public!)
343 | static_assert(default_constructable || param_constructable,
| ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/behaviortree_cpp/bt_factory.h:343:41: note: ‘(((bool)default_constructable) || ((bool)param_constructable))’ evaluates to false
/usr/local/include/behaviortree_cpp/bt_factory.h: In instantiation of ‘void BT::BehaviorTreeFactory::registerNodeType(const string&, const PortsList&, ExtraArgs ...) [with T = PathFollow; ExtraArgs = {IMotor&}; std::string = std::__cxx11::basic_string<char>; BT::PortsList = std::unordered_map<std::__cxx11::basic_string<char>, BT::PortInfo>]’:
/interface.cc:33:48: required from here
/usr/local/include/behaviortree_cpp/bt_factory.h:349:67: error: cannot allocate an object of abstract type ‘IMotor’
349 | registerBuilder(CreateManifest<T>(ID, ports), CreateBuilder<T>(args...));
| ~~~~~~~~~~~~~~~~^~~~~~~~~
/interface.cc:4:8: note: because the following virtual functions are pure within ‘IMotor’:
4 | struct IMotor {
| ^~~~~~
/interface.cc:5:16: note: ‘virtual void IMotor::doMove()’
5 | virtual void doMove() = 0;
|
This node should be "param_constructable" with the LinearMotor struct passed to it. Any guess on how to do it? Am I missing something basic?
Metadata
Metadata
Assignees
Labels
No labels