Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "behaviortree_cpp/bt_factory.h"
00014 #include "behaviortree_cpp/shared_library.h"
00015
00016 namespace BT
00017 {
00018 BehaviorTreeFactory::BehaviorTreeFactory()
00019 {
00020 registerNodeType<FallbackNode>("Fallback");
00021 registerNodeType<FallbackStarNode>("FallbackStar");
00022 registerNodeType<SequenceNode>("Sequence");
00023 registerNodeType<SequenceStarNode>("SequenceStar");
00024 registerNodeType<ParallelNode>("ParallelNode");
00025
00026 registerNodeType<InverterNode>("Inverter");
00027 registerNodeType<RetryNode>("RetryUntilSuccesful");
00028 registerNodeType<RepeatNode>("Repeat");
00029 registerNodeType<TimeoutNode>("Timeout");
00030
00031 registerNodeType<ForceSuccessDecorator>("ForceSuccess");
00032 registerNodeType<ForceFailureDecorator>("ForceFailure");
00033
00034 registerNodeType<AlwaysSuccess>("AlwaysSuccess");
00035 registerNodeType<AlwaysFailure>("AlwaysFailure");
00036 registerNodeType<SetBlackboard>("SetBlackboard");
00037
00038 registerNodeType<DecoratorSubtreeNode>("SubTree");
00039
00040 registerNodeType<BlackboardPreconditionNode<int>>("BlackboardCheckInt");
00041 registerNodeType<BlackboardPreconditionNode<double>>("BlackboardCheckDouble");
00042 registerNodeType<BlackboardPreconditionNode<std::string>>("BlackboardCheckString");
00043
00044 for( const auto& it: builders_)
00045 {
00046 builtin_IDs_.insert( it.first );
00047 }
00048 }
00049
00050 bool BehaviorTreeFactory::unregisterBuilder(const std::string& ID)
00051 {
00052 auto it = builders_.find(ID);
00053 if (it == builders_.end())
00054 {
00055 return false;
00056 }
00057 builders_.erase(ID);
00058 return true;
00059 }
00060
00061 void BehaviorTreeFactory::registerBuilder(const TreeNodeManifest& manifest, NodeBuilder builder)
00062 {
00063 auto it = builders_.find( manifest.registration_ID);
00064 if (it != builders_.end())
00065 {
00066 throw BehaviorTreeException("ID '" + manifest.registration_ID + "' already registered");
00067 }
00068
00069 builders_.insert(std::make_pair(manifest.registration_ID, builder));
00070 manifests_.push_back(manifest);
00071 sortTreeNodeManifests();
00072 }
00073
00074 void BehaviorTreeFactory::registerSimpleCondition(
00075 const std::string& ID, const SimpleConditionNode::TickFunctor& tick_functor)
00076 {
00077 NodeBuilder builder = [tick_functor, ID](const std::string& name, const NodeParameters& params) {
00078 return std::unique_ptr<TreeNode>(new SimpleConditionNode(name, tick_functor, params));
00079 };
00080
00081 TreeNodeManifest manifest = { NodeType::CONDITION, ID, NodeParameters() };
00082 registerBuilder(manifest, builder);
00083 }
00084
00085 void BehaviorTreeFactory::registerSimpleAction(const std::string& ID,
00086 const SimpleActionNode::TickFunctor& tick_functor)
00087 {
00088 NodeBuilder builder = [tick_functor, ID](const std::string& name, const NodeParameters& params) {
00089 return std::unique_ptr<TreeNode>(new SimpleActionNode(name, tick_functor, params));
00090 };
00091
00092 TreeNodeManifest manifest = { NodeType::ACTION, ID, NodeParameters() };
00093 registerBuilder(manifest, builder);
00094 }
00095
00096 void BehaviorTreeFactory::registerSimpleDecorator(
00097 const std::string& ID, const SimpleDecoratorNode::TickFunctor& tick_functor)
00098 {
00099 NodeBuilder builder = [tick_functor, ID](const std::string& name, const NodeParameters& params) {
00100 return std::unique_ptr<TreeNode>(new SimpleDecoratorNode(name, tick_functor, params));
00101 };
00102
00103 TreeNodeManifest manifest = { NodeType::DECORATOR, ID, NodeParameters() };
00104 registerBuilder(manifest, builder);
00105 }
00106
00107 void BehaviorTreeFactory::registerFromPlugin(const std::string file_path)
00108 {
00109 BT::SharedLibrary loader;
00110 loader.load(file_path);
00111 typedef void (*Func)(BehaviorTreeFactory&);
00112
00113 if (loader.hasSymbol(PLUGIN_SYMBOL))
00114 {
00115 Func func = (Func)loader.getSymbol(PLUGIN_SYMBOL);
00116 func(*this);
00117 }
00118 else
00119 {
00120 std::cout << "ERROR loading library [" << file_path << "]: can't find symbol ["
00121 << PLUGIN_SYMBOL << "]" << std::endl;
00122 }
00123 }
00124
00125 std::unique_ptr<TreeNode> BehaviorTreeFactory::instantiateTreeNode(
00126 const std::string& ID, const std::string& name,
00127 const NodeParameters& params,
00128 const Blackboard::Ptr& blackboard) const
00129 {
00130 auto it = builders_.find(ID);
00131 if (it == builders_.end())
00132 {
00133 std::cerr << ID << " not included in this list:" << std::endl;
00134 for (const auto& it: builders_)
00135 {
00136 std::cerr << it.first << std::endl;
00137 }
00138 throw std::invalid_argument("ID '" + ID + "' not registered");
00139 }
00140 std::unique_ptr<TreeNode> node = it->second(name, params);
00141 node->setRegistrationName(ID);
00142 node->setBlackboard(blackboard);
00143 node->initializeOnce();
00144
00145 return node;
00146 }
00147
00148 const std::map<std::string, NodeBuilder>& BehaviorTreeFactory::builders() const
00149 {
00150 return builders_;
00151 }
00152
00153 const std::vector<TreeNodeManifest>& BehaviorTreeFactory::manifests() const
00154 {
00155 return manifests_;
00156 }
00157
00158 const std::set<std::string> &BehaviorTreeFactory::builtinNodes() const
00159 {
00160 return builtin_IDs_;
00161 }
00162
00163 void BehaviorTreeFactory::sortTreeNodeManifests()
00164 {
00165 std::sort(manifests_.begin(), manifests_.end(),
00166 [](const TreeNodeManifest& a, const TreeNodeManifest& b) {
00167 int comp = std::strcmp(toStr(a.type), toStr(b.type));
00168 if (comp == 0)
00169 {
00170 return a.registration_ID < b.registration_ID;
00171 }
00172 return comp < 0;
00173 });
00174 }
00175
00176 }