Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/behaviortree_cpp/loggers/bt_observer.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ class TreeObserver : public StatusChangeLogger
Duration last_timestamp = {};
};

// find the statistics of a node, based on its path
// find the statistics of a node, based on its path.
// If more nodes have the same path, this is the first one in depth-first order.
const NodeStatistics& getStatistics(const std::string& path) const;

// find the statistics of a node, based on its TreeNode::UID()
Expand Down
16 changes: 5 additions & 11 deletions src/loggers/bt_observer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,17 @@ TreeObserver::TreeObserver(const BT::Tree& tree) : StatusChangeLogger(tree.rootN
}
}

if(_path_to_uid.count(node.fullPath()) != 0)
{
throw LogicError("TreeObserver not built correctly. Report issue");
}
_path_to_uid[node.fullPath()] = node.UID();
// Nodes with the same name in the same subtree share the same path:
// keep the first one, the others can be found by UID.
_path_to_uid.try_emplace(node.fullPath(), node.UID());
_uid_to_path[node.UID()] = node.fullPath();
_statistics[node.UID()] = {};
};

for(const auto& subtree : tree.subtrees)
{
recursiveStep(*subtree->nodes.front());
}

for(const auto& [path, uid] : _path_to_uid)
{
_statistics[uid] = {};
_uid_to_path[uid] = path;
}
}

TreeObserver::~TreeObserver()
Expand Down
33 changes: 33 additions & 0 deletions tests/gtest_loggers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "behaviortree_cpp/loggers/bt_cout_logger.h"
#include "behaviortree_cpp/loggers/bt_file_logger_v2.h"
#include "behaviortree_cpp/loggers/bt_minitrace_logger.h"
#include "behaviortree_cpp/loggers/bt_observer.h"
#include "behaviortree_cpp/loggers/bt_sqlite_logger.h"

#include <array>
Expand Down Expand Up @@ -620,3 +621,35 @@ TEST_F(LoggerTest, Logger_DisabledDuringExecution)

ASSERT_TRUE(std::filesystem::exists(filepath));
}

TEST(TreeObserverTest, NodesWithTheSameName)
{
// Two siblings with the same name have the same fullPath()
static const char* xml_text = R"(
<root BTCPP_format="4">
<BehaviorTree ID="MainTree">
<Sequence>
<AlwaysSuccess name="step"/>
<AlwaysSuccess name="step"/>
</Sequence>
</BehaviorTree>
</root>)";

BehaviorTreeFactory factory;
auto tree = factory.createTreeFromText(xml_text);

std::unique_ptr<TreeObserver> observer;
ASSERT_NO_THROW(observer = std::make_unique<TreeObserver>(tree));
ASSERT_EQ(tree.tickWhileRunning(), NodeStatus::SUCCESS);

const auto& nodes = tree.subtrees.front()->nodes;
ASSERT_EQ(nodes.size(), 3u);
EXPECT_EQ(observer->statistics().size(), 3u);
EXPECT_EQ(observer->uidToPath().size(), 3u);
for(const auto& node : nodes)
{
EXPECT_EQ(observer->uidToPath().at(node->UID()), node->fullPath());
EXPECT_EQ(observer->getStatistics(node->UID()).success_count, 1u);
}
EXPECT_EQ(observer->pathToUID().at("step"), nodes[1]->UID());
}
Loading