diff --git a/CMakeLists.txt b/CMakeLists.txt index e9a51414b..c42689653 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,13 +99,12 @@ list(APPEND BT_SOURCE src/actions/sleep_node.cpp src/decorators/delay_node.cpp + src/decorators/entry_updated_nodes.cpp src/decorators/inverter_node.cpp src/decorators/repeat_node.cpp src/decorators/retry_node.cpp - src/decorators/timeout_node.cpp - src/decorators/skip_unless_updated.cpp src/decorators/subtree_node.cpp - src/decorators/wait_update.cpp + src/decorators/timeout_node.cpp src/controls/if_then_else_node.cpp src/controls/fallback_node.cpp diff --git a/include/behaviortree_cpp/behavior_tree.h b/include/behaviortree_cpp/behavior_tree.h index 346303304..008219cb7 100644 --- a/include/behaviortree_cpp/behavior_tree.h +++ b/include/behaviortree_cpp/behavior_tree.h @@ -33,8 +33,7 @@ #include "behaviortree_cpp/decorators/run_once_node.h" #include "behaviortree_cpp/decorators/subtree_node.h" #include "behaviortree_cpp/decorators/loop_node.h" -#include "behaviortree_cpp/decorators/skip_unless_updated.h" -#include "behaviortree_cpp/decorators/wait_update.h" +#include "behaviortree_cpp/decorators/entry_updated_nodes.h" #include "behaviortree_cpp/actions/always_success_node.h" #include "behaviortree_cpp/actions/always_failure_node.h" diff --git a/include/behaviortree_cpp/decorators/skip_unless_updated.h b/include/behaviortree_cpp/decorators/entry_updated_nodes.h similarity index 77% rename from include/behaviortree_cpp/decorators/skip_unless_updated.h rename to include/behaviortree_cpp/decorators/entry_updated_nodes.h index 62e86aa9f..d9d20c4b0 100644 --- a/include/behaviortree_cpp/decorators/skip_unless_updated.h +++ b/include/behaviortree_cpp/decorators/entry_updated_nodes.h @@ -16,31 +16,31 @@ namespace BT { - /** - * @brief The SkipUnlessUpdated checks the Timestamp in an entry + * @brief The EntryUpdatedNode checks the Timestamp in an entry * to determine if the value was updated since the last time (true, * the first time). * - * If it is, the child will be executed, otherwise SKIPPED is returned. + * If it is, the child will be executed, otherwise [if_not_updated] value is returned. */ -class SkipUnlessUpdated : public DecoratorNode +class EntryUpdatedNode : public DecoratorNode { public: - SkipUnlessUpdated(const std::string& name, const NodeConfig& config); + EntryUpdatedNode(const std::string& name, const NodeConfig& config, + NodeStatus if_not_updated); - ~SkipUnlessUpdated() override = default; + ~EntryUpdatedNode() override = default; static PortsList providedPorts() { - return { InputPort("entry", "Skip this branch unless the blackboard value " - "was updated") }; + return { InputPort("entry", "Entry to check") }; } private: int64_t sequence_id_ = -1; std::string entry_key_; bool still_executing_child_ = false; + NodeStatus if_not_updated_; NodeStatus tick() override; diff --git a/include/behaviortree_cpp/decorators/wait_update.h b/include/behaviortree_cpp/decorators/wait_update.h deleted file mode 100644 index d4d4487d9..000000000 --- a/include/behaviortree_cpp/decorators/wait_update.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (C) 2024 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/decorator_node.h" - -namespace BT -{ -/** - * @brief The WaitValueUpdate checks the Timestamp in an entry - * to determine if the value was updated since the last time (true, - * the first time). - * - * If it is, the child will be executed, otherwise RUNNING is returned. - */ -class WaitValueUpdate : public DecoratorNode -{ -public: - WaitValueUpdate(const std::string& name, const NodeConfig& config); - - ~WaitValueUpdate() override = default; - - static PortsList providedPorts() - { - return { InputPort("entry", "Sleep until the entry in the blackboard is " - "updated") }; - } - -private: - int64_t sequence_id_ = -1; - std::string entry_key_; - bool still_executing_child_ = false; - - NodeStatus tick() override; - - void halt() override; -}; - -} // namespace BT diff --git a/src/bt_factory.cpp b/src/bt_factory.cpp index cbd9a59eb..964954773 100644 --- a/src/bt_factory.cpp +++ b/src/bt_factory.cpp @@ -95,8 +95,8 @@ BehaviorTreeFactory::BehaviorTreeFactory() : _p(new PImpl) registerNodeType>("LoopDouble"); registerNodeType>("LoopString"); - registerNodeType("SkipUnlessUpdated"); - registerNodeType("WaitValueUpdate"); + registerNodeType("SkipUnlessUpdated", NodeStatus::SKIPPED); + registerNodeType("WaitValueUpdate", NodeStatus::RUNNING); for(const auto& it : _p->builders) { diff --git a/src/decorators/skip_unless_updated.cpp b/src/decorators/entry_updated_nodes.cpp similarity index 84% rename from src/decorators/skip_unless_updated.cpp rename to src/decorators/entry_updated_nodes.cpp index 53122ee17..20dfd520d 100644 --- a/src/decorators/skip_unless_updated.cpp +++ b/src/decorators/entry_updated_nodes.cpp @@ -10,13 +10,14 @@ * 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. */ -#include "behaviortree_cpp/decorators/skip_unless_updated.h" +#include "behaviortree_cpp/decorators/entry_updated_nodes.h" namespace BT { -SkipUnlessUpdated::SkipUnlessUpdated(const std::string& name, const NodeConfig& config) - : DecoratorNode(name, config) +EntryUpdatedNode::EntryUpdatedNode(const std::string& name, const NodeConfig& config, + NodeStatus if_not_updated) + : DecoratorNode(name, config), if_not_updated_(if_not_updated) { const auto entry_str = config.input_ports.at("entry"); StringView stripped_key; @@ -30,7 +31,7 @@ SkipUnlessUpdated::SkipUnlessUpdated(const std::string& name, const NodeConfig& } } -NodeStatus SkipUnlessUpdated::tick() +NodeStatus EntryUpdatedNode::tick() { // continue executing an asynchronous child if(still_executing_child_) @@ -46,7 +47,7 @@ NodeStatus SkipUnlessUpdated::tick() auto seq = static_cast(entry->sequence_id); if(seq == sequence_id_) { - return NodeStatus::SKIPPED; + return if_not_updated_; } sequence_id_ = seq; } @@ -56,7 +57,7 @@ NodeStatus SkipUnlessUpdated::tick() return status; } -void SkipUnlessUpdated::halt() +void EntryUpdatedNode::halt() { still_executing_child_ = false; } diff --git a/src/decorators/wait_update.cpp b/src/decorators/wait_update.cpp deleted file mode 100644 index 6a56c46c4..000000000 --- a/src/decorators/wait_update.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (C) 2024 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. -*/ - -#include "behaviortree_cpp/decorators/wait_update.h" - -namespace BT -{ - -WaitValueUpdate::WaitValueUpdate(const std::string& name, const NodeConfig& config) - : DecoratorNode(name, config) -{ - const auto entry_str = config.input_ports.at("entry"); - StringView stripped_key; - if(isBlackboardPointer(entry_str, &stripped_key)) - { - entry_key_ = stripped_key; - } - else - { - entry_key_ = entry_str; - } -} - -NodeStatus WaitValueUpdate::tick() -{ - // continue executing an asynchronous child - if(still_executing_child_) - { - auto status = child()->executeTick(); - still_executing_child_ = (status == NodeStatus::RUNNING); - return status; - } - - { - auto entry = config().blackboard->getEntry(entry_key_); - std::unique_lock lk(entry->entry_mutex); - auto seq = static_cast(entry->sequence_id); - if(seq == sequence_id_) - { - return NodeStatus::SKIPPED; - } - sequence_id_ = seq; - } - - auto status = child()->executeTick(); - still_executing_child_ = (status == NodeStatus::RUNNING); - return status; -} - -void WaitValueUpdate::halt() -{ - still_executing_child_ = false; -} - -} // namespace BT