15#include "auto_apms_behavior_tree_core/node.hpp"
16#include "rclcpp/logging.hpp"
17#include "rcutils/error_handling.h"
18#include "rcutils/logging.h"
20#define INPUT_KEY_MSG "message"
21#define INPUT_KEY_LEVEL "level"
26class Logger :
public BT::SyncActionNode
29 Logger(
const std::string & instance_name,
const BT::NodeConfig & config,
const core::RosNodeContext & context)
30 : SyncActionNode(instance_name, config), context_(context)
34 static BT::PortsList providedPorts()
37 BT::InputPort<std::string>(
38 INPUT_KEY_LEVEL,
"INFO",
39 "Logger level. Must be one of [UNSET, DEBUG, INFO, WARN, ERROR, FATAL] but is not case sensitive."),
40 BT::InputPort<BT::AnyTypeAllowed>(INPUT_KEY_MSG,
"Message to be logged via rclcpp::Logger.")};
43 BT::NodeStatus tick() override final
45 const std::string level_str = getInput<std::string>(INPUT_KEY_LEVEL).value();
48 rcutils_logging_severity_level_from_string(level_str.c_str(), rcutils_get_default_allocator(), &level) !=
50 const std::string error = rcutils_get_error_string().str;
51 rcutils_reset_error();
52 throw exceptions::RosNodeError(
53 "Cannot convert input of port '" + std::string(INPUT_KEY_LEVEL) +
54 "' to a valid logging severity level: " + error);
56 const BT::PortsRemapping::iterator it = config().input_ports.find(INPUT_KEY_MSG);
57 if (it == config().input_ports.end())
return BT::NodeStatus::SUCCESS;
60 if (isBlackboardPointer(it->second)) {
62 if (
const BT::Expected<BT::Any> expected = getInput<BT::Any>(INPUT_KEY_MSG)) {
63 const BT::Any & any = expected.value();
64 msg = it->second +
" (Cannot convert " + BT::demangle(any.type()) +
" to string)";
65 if (
const BT::Expected<std::string> casted = any.tryCast<std::string>()) {
66 msg = casted.value().c_str();
69 throw exceptions::RosNodeError(context_.getFullyQualifiedTreeNodeName(
this) +
" - " + expected.error());
76 msg = context_.getFullyQualifiedTreeNodeName(
this,
false) +
" - " + msg + (msg.back() ==
'.' ?
"" :
".");
77 RCUTILS_LOG_COND_NAMED(
78 level, RCUTILS_LOG_CONDITION_EMPTY, RCUTILS_LOG_CONDITION_EMPTY, context_.getBaseLogger().get_name(),
80 return BT::NodeStatus::SUCCESS;
84 const core::RosNodeContext context_;
#define AUTO_APMS_BEHAVIOR_TREE_DECLARE_NODE(type)
Macro for registering a behavior tree node plugin.
Useful tooling for incorporating behavior trees for task development.