bt_factory.cpp
Go to the documentation of this file.
00001 /*  Copyright (C) 2018 Davide Faconti -  All Rights Reserved
00002 *
00003 *   Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
00004 *   to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
00005 *   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:
00006 *   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
00007 *
00008 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00009 *   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,
00010 *   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.
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 }   // end namespace


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Feb 2 2019 03:50:09