action_node.cpp
Go to the documentation of this file.
00001 /* Copyright (C) 2015-2018 Michele Colledanchise -  All Rights Reserved
00002  * Copyright (C) 2018 Davide Faconti -  All Rights Reserved
00003 *
00004 *   Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
00005 *   to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
00006 *   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:
00007 *   The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
00008 *
00009 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00010 *   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,
00011 *   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.
00012 */
00013 
00014 #include "behaviortree_cpp/action_node.h"
00015 #include "coroutine/coroutine.h"
00016 
00017 namespace BT
00018 {
00019 ActionNodeBase::ActionNodeBase(const std::string& name, const NodeParameters& parameters)
00020   : LeafNode::LeafNode(name, parameters)
00021 {
00022 }
00023 
00024 NodeStatus ActionNodeBase::executeTick()
00025 {
00026     initializeOnce();
00027     NodeStatus prev_status = status();
00028 
00029     if (prev_status == NodeStatus::IDLE || prev_status == NodeStatus::RUNNING)
00030     {
00031         setStatus(tick());
00032     }
00033     return status();
00034 }
00035 
00036 //-------------------------------------------------------
00037 
00038 SimpleActionNode::SimpleActionNode(const std::string& name,
00039                                    SimpleActionNode::TickFunctor tick_functor,
00040                                    const NodeParameters& params)
00041   : ActionNodeBase(name, params), tick_functor_(std::move(tick_functor))
00042 {
00043 }
00044 
00045 NodeStatus SimpleActionNode::tick()
00046 {
00047     NodeStatus prev_status = status();
00048 
00049     if (prev_status == NodeStatus::IDLE)
00050     {
00051         setStatus(NodeStatus::RUNNING);
00052         prev_status = NodeStatus::RUNNING;
00053     }
00054 
00055     NodeStatus status = tick_functor_(*this);
00056     if (status != prev_status)
00057     {
00058         setStatus(status);
00059     }
00060     return status;
00061 }
00062 
00063 //-------------------------------------------------------
00064 
00065 AsyncActionNode::AsyncActionNode(const std::string& name, const NodeParameters& parameters)
00066   : ActionNodeBase(name, parameters), loop_(true)
00067 {
00068     thread_ = std::thread(&AsyncActionNode::waitForTick, this);
00069 }
00070 
00071 AsyncActionNode::~AsyncActionNode()
00072 {
00073     if (thread_.joinable())
00074     {
00075         stopAndJoinThread();
00076     }
00077 }
00078 
00079 void AsyncActionNode::waitForTick()
00080 {
00081     while (loop_.load())
00082     {
00083         tick_engine_.wait();
00084 
00085         // check loop_ again because the tick_engine_ could be
00086         // notified from the method stopAndJoinThread
00087         if (loop_ && status() == NodeStatus::IDLE)
00088         {
00089             setStatus(NodeStatus::RUNNING);
00090             setStatus(tick());
00091         }
00092     }
00093 }
00094 
00095 NodeStatus AsyncActionNode::executeTick()
00096 {
00097     initializeOnce();
00098     //send signal to other thread.
00099     // The other thread is in charge for changing the status
00100     if (status() == NodeStatus::IDLE)
00101     {
00102         tick_engine_.notify();
00103     }
00104 
00105     // block as long as the state is NodeStatus::IDLE
00106     const NodeStatus stat = waitValidStatus();
00107     return stat;
00108 }
00109 
00110 void AsyncActionNode::stopAndJoinThread()
00111 {
00112     loop_.store(false);
00113     tick_engine_.notify();
00114     if (thread_.joinable())
00115     {
00116         thread_.join();
00117     }
00118 }
00119 
00120 //-------------------------------------
00121 struct CoroActionNode::Pimpl
00122 {
00123     coroutine::routine_t coro;
00124     Pimpl(): coro(0) {}
00125 };
00126 
00127 
00128 CoroActionNode::CoroActionNode(const std::string &name,
00129                                const NodeParameters &parameters):
00130   ActionNodeBase (name, parameters),
00131   _p(new  Pimpl)
00132 {
00133 }
00134 
00135 CoroActionNode::~CoroActionNode()
00136 {
00137     halt();
00138 }
00139 
00140 void CoroActionNode::setStatusRunningAndYield()
00141 {
00142     setStatus( NodeStatus::RUNNING );
00143     coroutine::yield();
00144 }
00145 
00146 NodeStatus CoroActionNode::executeTick()
00147 {
00148     initializeOnce();
00149     if (status() == NodeStatus::IDLE)
00150     {
00151         _p->coro = coroutine::create( [this]() { setStatus(tick()); } );
00152     }
00153 
00154     if( _p->coro != 0)
00155     {
00156         auto res = coroutine::resume(_p->coro);
00157 
00158         if( res == coroutine::ResumeResult::FINISHED)
00159         {
00160             coroutine::destroy(_p->coro);
00161             _p->coro = 0;
00162         }
00163     }
00164     return status();
00165 }
00166 
00167 void CoroActionNode::halt()
00168 {
00169     if( _p->coro != 0 )
00170     {
00171         coroutine::destroy(_p->coro);
00172         _p->coro = 0;
00173     }
00174 }
00175 
00176 SyncActionNode::SyncActionNode(const std::string &name, const NodeParameters &parameters):
00177     ActionNodeBase(name, parameters)
00178 {}
00179 
00180 NodeStatus SyncActionNode::executeTick()
00181 {
00182     auto stat = ActionNodeBase::executeTick();
00183     if( stat == NodeStatus::RUNNING)
00184     {
00185         throw std::logic_error("SyncActionNode MUSt never return RUNNING");
00186     }
00187     return stat;
00188 }
00189 
00190 
00191 
00192 }


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