forked from BehaviorTree/BehaviorTree.CPP
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
aaab50f
commit e781fcd
Showing
23 changed files
with
25,865 additions
and
150 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#include "behaviortree_cpp/bt_factory.h" | ||
#include "behaviortree_cpp/loggers/bt_observer.h" | ||
|
||
/** Show the use of the TreeObserver. | ||
*/ | ||
|
||
// clang-format off | ||
|
||
static const char* xml_text = R"( | ||
<root BTCPP_format="4"> | ||
<BehaviorTree ID="MainTree"> | ||
<Sequence> | ||
<Fallback> | ||
<AlwaysFailure name="failing_action"/> | ||
<SubTree ID="SubTreeA" name="mysub"/> | ||
</Fallback> | ||
<AlwaysSuccess name="last_action"/> | ||
</Sequence> | ||
</BehaviorTree> | ||
<BehaviorTree ID="SubTreeA"> | ||
<Sequence> | ||
<AlwaysSuccess name="action_subA"/> | ||
<SubTree ID="SubTreeB" name="sub_nested"/> | ||
<SubTree ID="SubTreeB" /> | ||
</Sequence> | ||
</BehaviorTree> | ||
<BehaviorTree ID="SubTreeB"> | ||
<AlwaysSuccess name="action_subB"/> | ||
</BehaviorTree> | ||
</root> | ||
)"; | ||
|
||
// clang-format on | ||
|
||
int main() | ||
{ | ||
BT::BehaviorTreeFactory factory; | ||
|
||
factory.registerBehaviorTreeFromText(xml_text); | ||
auto tree = factory.createTree("MainTree"); | ||
|
||
// Helper function to print the tree. | ||
BT::printTreeRecursively(tree.rootNode()); | ||
|
||
// The purpose of the observer is to save some statistics about the number of times | ||
// a certain node returns SUCCESS or FAILURE. | ||
// This is particularly useful to create unit tests and to check if | ||
// a certain set of transitions happened as expected | ||
BT::TreeObserver observer(tree); | ||
|
||
// Print the unique ID and the corresponding human readable path | ||
// Path is also expected to be unique. | ||
std::map<uint16_t, std::string> ordered_UID_to_path; | ||
for(const auto& [name, uid]: observer.pathToUID()) { | ||
ordered_UID_to_path[uid] = name; | ||
} | ||
|
||
for(const auto& [uid, name]: ordered_UID_to_path) { | ||
std::cout << uid << " -> " << name << std::endl; | ||
} | ||
|
||
// Tick the tree multiple times, until action_B is finally ticked. | ||
// Since we use const reference, we can check this statistic periodically. | ||
const auto& action_B_stats = observer.getStatistics("last_action"); | ||
|
||
tree.tickOnce(); | ||
|
||
|
||
std::cout << "----------------" << std::endl; | ||
// print all the statistics | ||
for(const auto& [uid, name]: ordered_UID_to_path) { | ||
const auto& stats = observer.getStatistics(uid); | ||
|
||
std::cout << "[" << name | ||
<< "] \tT/S/F: " << stats.tick_count | ||
<< "/" << stats.success_count | ||
<< "/" << stats.failure_count | ||
<< std::endl; | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#include "behaviortree_cpp/bt_factory.h" | ||
#include "dummy_nodes.h" | ||
|
||
// clang-format off | ||
|
||
static const char* xml_text = R"( | ||
<root BTCPP_format="4"> | ||
<BehaviorTree ID="MainTree"> | ||
<Sequence> | ||
<SaySomething name="talk" message="hello world"/> | ||
<Fallback> | ||
<AlwaysFailure name="failing_action"/> | ||
<SubTree ID="MySub" name="mysub"/> | ||
</Fallback> | ||
<SaySomething message="before last_action"/> | ||
<Script code="msg:='after last_action'"/> | ||
<AlwaysSuccess name="last_action"/> | ||
<SaySomething message="{msg}"/> | ||
</Sequence> | ||
</BehaviorTree> | ||
<BehaviorTree ID="MySub"> | ||
<Sequence> | ||
<AlwaysSuccess name="action_subA"/> | ||
<AlwaysSuccess name="action_subB"/> | ||
</Sequence> | ||
</BehaviorTree> | ||
</root> | ||
)"; | ||
|
||
// clang-format on | ||
|
||
int main(int argc, char** argv) | ||
{ | ||
using namespace DummyNodes; | ||
BT::BehaviorTreeFactory factory; | ||
|
||
factory.registerNodeType<SaySomething>("SaySomething"); | ||
|
||
// We use lambdasand registerSimpleAction, to create | ||
// a "dummy" node, that we want to create instead of a given one. | ||
|
||
// Simple node that just prints its name and return SUCCESS | ||
factory.registerSimpleAction("TestAction", [](BT::TreeNode& self){ | ||
std::cout << "TestAction substituting: "<< self.name() << std::endl; | ||
return BT::NodeStatus::SUCCESS; | ||
}); | ||
|
||
// Action that is meant to substitute SaySomething. | ||
// It will try to use the input port "message" | ||
factory.registerSimpleAction("TestSaySomething", [](BT::TreeNode& self){ | ||
auto msg = self.getInput<std::string>("message"); | ||
if (!msg) | ||
{ | ||
throw BT::RuntimeError( "missing required input [message]: ", msg.error() ); | ||
} | ||
std::cout << "TestSaySomething: " << msg.value() << std::endl; | ||
return BT::NodeStatus::SUCCESS; | ||
}); | ||
|
||
// These configurations will be passed to a TestNode | ||
BT::TestNodeConfig test_config; | ||
// Convert the node in asynchronous and wait 2000 ms | ||
test_config.async_delay = std::chrono::milliseconds(2000); | ||
// Execute this postcondition, once completed | ||
test_config.post_script = "msg ='message SUBSTITUED'"; | ||
|
||
//---------------------------- | ||
// pass "no_sub" as first argument to avoid adding rules | ||
bool skip_substitution = (argc == 2) && std::string(argv[1]) == "no_sub"; | ||
|
||
if(!skip_substitution) | ||
{ | ||
// Substitute nodes which match this wildcard pattern with TestAction | ||
factory.addSubstitutionRule("mysub/action_*", "TestAction"); | ||
|
||
// Substitute the node with name [talk] with TestSaySomething | ||
factory.addSubstitutionRule("talk", "TestSaySomething"); | ||
|
||
// Substitute the node with name [last_action] with a TestNode, | ||
// configured using test_config | ||
factory.addSubstitutionRule("last_action", test_config); | ||
} | ||
|
||
factory.registerBehaviorTreeFromText(xml_text); | ||
|
||
// During the construction phase of the tree, the substitution | ||
// rules will be used to instantiate the test nodes, instead of the | ||
// original ones. | ||
auto tree = factory.createTree("MainTree"); | ||
tree.tickWhileRunning(); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* Copyright (C) 2022 Davide Faconti - All Rights Reserved | ||
* | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), | ||
* to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "behaviortree_cpp/action_node.h" | ||
#include "behaviortree_cpp/decorators/timer_queue.h" | ||
#include "behaviortree_cpp/scripting/script_parser.hpp" | ||
|
||
namespace BT | ||
{ | ||
|
||
struct TestNodeConfig | ||
{ | ||
/// status to return when the action is completed | ||
NodeStatus return_status = NodeStatus::SUCCESS; | ||
|
||
/// script to execute when actions is completed | ||
std::string post_script; | ||
|
||
/// if async_delay > 0, this action become asynchronous and wait this amount of time | ||
std::chrono::milliseconds async_delay = std::chrono::milliseconds(0); | ||
|
||
/// C++ callback to execute at the beginning | ||
std::function<void()> pre_func; | ||
|
||
/// C++ callback to execute at the end | ||
std::function<void()> post_func; | ||
}; | ||
|
||
/** | ||
* @brief The TestNode is a Node that can be configure to: | ||
* | ||
* 1. Return a specific status (SUCCESS / FAILURE) | ||
* 2. Execute a post condition script (unless halted) | ||
* 3. Either complete immediately (synchronous action), or after a | ||
* given period of time (asynchronous action) | ||
* | ||
* This behavior is changed by the parameters pased with TestNodeConfig. | ||
* | ||
* This particular node is created by the factory when TestNodeConfig is | ||
* added as a substitution rule: | ||
* | ||
* TestNodeConfig test_config; | ||
* // change fields of test_config | ||
* factory.addSubstitutionRule(pattern, test_config); | ||
* | ||
* See tutorial 11 for more details. | ||
*/ | ||
class TestNode : public BT::StatefulActionNode | ||
{ | ||
public: | ||
TestNode(const std::string& name, const NodeConfig& config) : | ||
StatefulActionNode(name, config) | ||
{ | ||
setRegistrationID("TestNode"); | ||
} | ||
|
||
static PortsList providedPorts() | ||
{ | ||
return {}; | ||
} | ||
|
||
void setConfig(const TestNodeConfig& config); | ||
|
||
private: | ||
|
||
virtual NodeStatus onStart() override; | ||
|
||
virtual NodeStatus onRunning() override; | ||
|
||
virtual void onHalted() override; | ||
|
||
NodeStatus onCompleted(); | ||
|
||
TestNodeConfig _test_config; | ||
ScriptFunction _executor; | ||
TimerQueue<> _timer; | ||
std::atomic_bool _completed; | ||
}; | ||
|
||
} // namespace BT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.