AutoAPMS
Resilient Robot Mission Management
Loading...
Searching...
No Matches
state_observer.cpp
1// Copyright 2024 Robin Müller
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "auto_apms_behavior_tree/executor/state_observer.hpp"
16
17#include <chrono>
18
20{
21
23 const BT::Tree & tree, const rclcpp::Logger & node_logger, std::chrono::seconds max_logging_interval)
24: StatusChangeLogger{tree.rootNode()},
25 logger_{node_logger},
26 root_tree_id_{tree.subtrees[0]->tree_ID},
27 max_logging_interval_{max_logging_interval}
28{
29}
30
31void TreeStateObserver::flush() { running_action_history_.clear(); }
32
33void TreeStateObserver::setLogging(bool active) { logging_active_ = active; }
34
35const std::vector<std::string> & TreeStateObserver::getRunningActionHistory() const { return running_action_history_; }
36
37const std::string & TreeStateObserver::getLastRunningActionName() const { return last_running_action_name_; }
38
39uint16_t TreeStateObserver::createStateChangeBitmask(BT::NodeStatus prev_status, BT::NodeStatus curr_status)
40{
41 return static_cast<uint16_t>(prev_status) << 8 | static_cast<uint16_t>(curr_status);
42}
43
45 BT::Duration timestamp, const BT::TreeNode & node, BT::NodeStatus prev_status, BT::NodeStatus status)
46{
47 if (node.type() == BT::NodeType::ACTION && status == BT::NodeStatus::RUNNING) {
48 auto name = node.registrationName() == node.name() ? node.name() : node.registrationName() + ": " + node.name();
49 running_action_history_.push_back(name);
50 last_running_action_name_ = name;
51 }
52
57 if (!logging_active_) return;
58 const auto key = std::make_pair(node.UID(), createStateChangeBitmask(prev_status, status));
59 const bool is_first_log = last_log_map_.count(key) == 0;
60
61 if (is_first_log || timestamp - last_log_map_[key] > max_logging_interval_) {
62 if (node.registrationName() == node.name()) {
63 RCLCPP_INFO(
64 logger_, "[%s] %s '%s' -- %s -> %s", root_tree_id_.c_str(), BT::toStr(node.type()).c_str(), node.name().c_str(),
65 BT::toStr(prev_status, true).c_str(), BT::toStr(status, true).c_str());
66 } else {
67 RCLCPP_INFO(
68 logger_, "[%s] %s '%s: %s' -- %s -> %s", root_tree_id_.c_str(), BT::toStr(node.type()).c_str(),
69 node.registrationName().c_str(), node.name().c_str(), BT::toStr(prev_status, true).c_str(),
70 BT::toStr(status, true).c_str());
71 }
72 last_log_map_[key] = timestamp;
73 }
74}
75
76} // namespace auto_apms_behavior_tree
virtual void flush() override
Reset the internal state variables.
const std::string & getLastRunningActionName() const
Get the name of the last action node that returned BT::NodeStatus::RUNNING.
virtual void callback(BT::Duration timestamp, const BT::TreeNode &node, BT::NodeStatus prev_status, BT::NodeStatus status) override
TreeStateObserver(const BT::Tree &tree, const rclcpp::Logger &node_logger, std::chrono::seconds max_logging_interval=std::chrono::seconds(0))
Constructor.
const std::vector< std::string > & getRunningActionHistory() const
Get all names of action nodes that returned BT::NodeStatus::RUNNING since the last time TreeStateObse...
void setLogging(bool active)
Configure whether the observer should write to the logger.
Useful tooling for incorporating behavior trees for task development.
Definition builder.hpp:30