Skip to content

Commit

Permalink
user can now add PortsList to SimpleNodes (discussed in #41)
Browse files Browse the repository at this point in the history
  • Loading branch information
Davide Faconti authored and facontidavide committed Jan 16, 2019
1 parent e76ef47 commit 109647c
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 33 deletions.
11 changes: 7 additions & 4 deletions examples/t03_sequence_star.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ using namespace BT;

// clang-format off

const std::string xml_text_sequence = R"(
static const char* xml_text_sequence = R"(
<root main_tree_to_execute = "MainTree" >
Expand All @@ -25,14 +25,14 @@ const std::string xml_text_sequence = R"(
<TemperatureOK />
<SaySomething message="mission started..." />
<MoveBase goal="1;2;3"/>
<SaySomething message="mission completed!" />
<SaySomething2 message="mission completed!" />
</Sequence>
</BehaviorTree>
</root>
)";

const std::string xml_text_sequence_star = R"(
static const char* xml_text_sequence_star = R"(
<root main_tree_to_execute = "MainTree" >
Expand All @@ -42,7 +42,7 @@ const std::string xml_text_sequence_star = R"(
<TemperatureOK />
<SaySomething message="mission started..." />
<MoveBase goal="1;2;3"/>
<SaySomething message="mission completed!" />
<SaySomething2 message="mission completed!" />
</SequenceStar>
</BehaviorTree>
Expand All @@ -67,6 +67,9 @@ int main()
factory.registerNodeType<MoveBaseAction>("MoveBase");
factory.registerNodeType<SaySomething>("SaySomething");

PortsList say_something_ports = {{"message", PortType::INPUT}};
factory.registerSimpleAction("SaySomething2", SaySomethingSimple, say_something_ports );

// Compare the state transitions and messages using either
// xml_text_sequence and xml_text_sequence_star

Expand Down
40 changes: 31 additions & 9 deletions include/behaviortree_cpp/bt_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,41 @@ class BehaviorTreeFactory
bool unregisterBuilder(const std::string& ID);

/// The most generic way to register your own builder.
void registerBuilder(const TreeNodeManifest& manifest, NodeBuilder builder);
void registerBuilder(const TreeNodeManifest& manifest, const NodeBuilder& builder);

/// Register a SimpleActionNode
/**
* @brief registerSimpleAction help you register nodes of type SimpleActionNode.
*
* @param ID registration ID
* @param tick_functor the callback to be invoked in the tick() method.
* @param ports if your SimpleNode requires ports, provide the list here.
*
* */
void registerSimpleAction(const std::string& ID,
const SimpleActionNode::TickFunctor& tick_functor);

/// Register a SimpleConditionNode
const SimpleActionNode::TickFunctor& tick_functor,
PortsList ports = {});
/**
* @brief registerSimpleCondition help you register nodes of type SimpleConditionNode.
*
* @param ID registration ID
* @param tick_functor the callback to be invoked in the tick() method.
* @param ports if your SimpleNode requires ports, provide the list here.
*
* */
void registerSimpleCondition(const std::string& ID,
const SimpleConditionNode::TickFunctor& tick_functor);

/// Register a SimpleDecoratorNode
const SimpleConditionNode::TickFunctor& tick_functor,
PortsList ports = {});
/**
* @brief registerSimpleDecorator help you register nodes of type SimpleDecoratorNode.
*
* @param ID registration ID
* @param tick_functor the callback to be invoked in the tick() method.
* @param ports if your SimpleNode requires ports, provide the list here.
*
* */
void registerSimpleDecorator(const std::string& ID,
const SimpleDecoratorNode::TickFunctor& tick_functor);
const SimpleDecoratorNode::TickFunctor& tick_functor,
PortsList ports = {});

/**
* @brief registerFromPlugin load a shared library and execute the function BT_REGISTER_NODES (see macro).
Expand Down
12 changes: 12 additions & 0 deletions sample_nodes/dummy_nodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,16 @@ BT::NodeStatus SaySomething::tick()
std::cout << "Robot says: " << msg << std::endl;
return BT::NodeStatus::SUCCESS;
}

BT::NodeStatus SaySomethingSimple(BT::TreeNode &self)
{
std::string msg;
if (!self.getInput("message", msg))
{
throw BT::RuntimeError("missing required input [message]");
}
std::cout << "Robot says: " << msg << std::endl;
return BT::NodeStatus::SUCCESS;
}

}
4 changes: 4 additions & 0 deletions sample_nodes/dummy_nodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ class SaySomething : public BT::SyncActionNode
}
};

//Same as class SaySomething, but to be registered with SimpleActionNode
BT::NodeStatus SaySomethingSimple(BT::TreeNode& self);


inline void RegisterNodes(BT::BehaviorTreeFactory& factory)
{
static GripperInterface gi;
Expand Down
21 changes: 12 additions & 9 deletions src/bt_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ bool BehaviorTreeFactory::unregisterBuilder(const std::string& ID)
return true;
}

void BehaviorTreeFactory::registerBuilder(const TreeNodeManifest& manifest, NodeBuilder builder)
void BehaviorTreeFactory::registerBuilder(const TreeNodeManifest& manifest, const NodeBuilder& builder)
{
auto it = builders_.find( manifest.registration_ID);
if (it != builders_.end())
Expand All @@ -75,36 +75,39 @@ void BehaviorTreeFactory::registerBuilder(const TreeNodeManifest& manifest, Node
manifests_.insert( {manifest.registration_ID, manifest} );
}

void BehaviorTreeFactory::registerSimpleCondition(
const std::string& ID, const SimpleConditionNode::TickFunctor& tick_functor)
void BehaviorTreeFactory::registerSimpleCondition(const std::string& ID,
const SimpleConditionNode::TickFunctor& tick_functor,
PortsList ports)
{
NodeBuilder builder = [tick_functor, ID](const std::string& name, const NodeConfiguration& config) {
return std::unique_ptr<TreeNode>(new SimpleConditionNode(name, tick_functor, config));
};

TreeNodeManifest manifest = { NodeType::CONDITION, ID, {} };
TreeNodeManifest manifest = { NodeType::CONDITION, ID, std::move(ports) };
registerBuilder(manifest, builder);
}

void BehaviorTreeFactory::registerSimpleAction(const std::string& ID,
const SimpleActionNode::TickFunctor& tick_functor)
const SimpleActionNode::TickFunctor& tick_functor,
PortsList ports)
{
NodeBuilder builder = [tick_functor, ID](const std::string& name, const NodeConfiguration& config) {
return std::unique_ptr<TreeNode>(new SimpleActionNode(name, tick_functor, config));
};

TreeNodeManifest manifest = { NodeType::ACTION, ID, {} };
TreeNodeManifest manifest = { NodeType::ACTION, ID, std::move(ports) };
registerBuilder(manifest, builder);
}

void BehaviorTreeFactory::registerSimpleDecorator(
const std::string& ID, const SimpleDecoratorNode::TickFunctor& tick_functor)
void BehaviorTreeFactory::registerSimpleDecorator(const std::string& ID,
const SimpleDecoratorNode::TickFunctor& tick_functor,
PortsList ports)
{
NodeBuilder builder = [tick_functor, ID](const std::string& name, const NodeConfiguration& config) {
return std::unique_ptr<TreeNode>(new SimpleDecoratorNode(name, tick_functor, config));
};

TreeNodeManifest manifest = { NodeType::DECORATOR, ID, {} };
TreeNodeManifest manifest = { NodeType::DECORATOR, ID, std::move(ports) };
registerBuilder(manifest, builder);
}

Expand Down
20 changes: 9 additions & 11 deletions src/xml_parsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,20 +431,18 @@ TreeNode::Ptr XMLParser::Pimpl::createNodeFromXML(const XMLElement *element,
for(const auto& remap_it: remapping_parameters)
{
const auto& port_name = remap_it.first;
auto port_type = PortType::INOUT; // default if missing from manifest

auto port_it = manifest.ports.find( port_name );
if( port_it != manifest.ports.end() )
{
port_type = port_it->second;
}
if( port_type != PortType::OUTPUT )
{
config.input_ports.insert( remap_it );
}
if( port_type != PortType::INPUT )
{
config.output_ports.insert( remap_it );
auto port_type = port_it->second;
if( port_type != PortType::OUTPUT )
{
config.input_ports.insert( remap_it );
}
if( port_type != PortType::INPUT )
{
config.output_ports.insert( remap_it );
}
}
}
child_node = factory.instantiateTreeNode(instance_name, ID, config);
Expand Down

0 comments on commit 109647c

Please sign in to comment.