Nav2 Navigation Stack - lyrical  lyrical
ROS 2 Navigation Stack
ros_topic_logger.hpp
1 // Copyright (c) 2019 Intel Corporation
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 // http://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 #ifndef NAV2_BEHAVIOR_TREE__ROS_TOPIC_LOGGER_HPP_
16 #define NAV2_BEHAVIOR_TREE__ROS_TOPIC_LOGGER_HPP_
17 
18 #include <vector>
19 #include <memory>
20 #include <utility>
21 #include <string>
22 
23 #include "behaviortree_cpp/loggers/abstract_logger.h"
24 #include "rclcpp/clock.hpp"
25 #include "rclcpp/logger.hpp"
26 #include "rclcpp/logging.hpp"
27 #include "nav2_msgs/msg/behavior_tree_log.hpp"
28 #include "nav2_msgs/msg/behavior_tree_status_change.hpp"
29 #include "tf2/time.hpp"
30 #include "tf2_ros/buffer_interface.hpp"
31 #include "nav2_ros_common/interface_factories.hpp"
32 
33 namespace nav2_behavior_tree
34 {
35 
39 class RosTopicLogger : public BT::StatusChangeLogger
40 {
41 public:
49  const nav2::LifecycleNode::WeakPtr & ros_node,
50  const BT::Tree & tree,
51  bool log_idle = true)
52  : StatusChangeLogger(tree.rootNode())
53  {
54  auto node = ros_node.lock();
55  clock_ = node->get_clock();
56  logger_ = node->get_logger().get_child("ros_topic_logger");
57  log_pub_ = nav2::interfaces::create_publisher<nav2_msgs::msg::BehaviorTreeLog>(
58  node, "behavior_tree_log");
59  log_pub_->on_activate();
60  enableTransitionToIdle(log_idle);
61  }
62 
70  void callback(
71  BT::Duration timestamp,
72  const BT::TreeNode & node,
73  BT::NodeStatus prev_status,
74  BT::NodeStatus status) override
75  {
76  nav2_msgs::msg::BehaviorTreeStatusChange event;
77 
78  // BT timestamps are a duration since the epoch. Need to convert to a time_point
79  // before converting to a msg.
80  event.timestamp = tf2_ros::toMsg(tf2::TimePoint(timestamp));
81  event.node_name = node.name();
82  event.uid = node.UID();
83  event.previous_status = toStr(prev_status, false);
84  event.current_status = toStr(status, false);
85  event_log_.push_back(std::move(event));
86 
87  auto prev_pad = std::string(kStatusWidth - toStr(prev_status, false).size(), ' ');
88  auto curr_pad = std::string(kStatusWidth - toStr(status, false).size(), ' ');
89  RCLCPP_DEBUG(
90  logger_, "[%.3f]: %s%s -> %s%s %s",
91  std::chrono::duration<double>(timestamp).count(),
92  toStr(prev_status, true).c_str(), prev_pad.c_str(),
93  toStr(status, true).c_str(), curr_pad.c_str(),
94  node.name().c_str() );
95  }
96 
100  void flush() override
101  {
102  if (!event_log_.empty()) {
103  auto log_msg = std::make_unique<nav2_msgs::msg::BehaviorTreeLog>();
104  log_msg->timestamp = clock_->now();
105  log_msg->event_log = event_log_;
106  log_pub_->publish(std::move(log_msg));
107  event_log_.clear();
108  }
109  }
110 
111 protected:
112  // Longest BT status string is 7 chars (RUNNING, SUCCESS, FAILURE); pad shorter ones (IDLE)
113  static constexpr size_t kStatusWidth = 7;
114  rclcpp::Clock::SharedPtr clock_;
115  rclcpp::Logger logger_{rclcpp::get_logger("bt_navigator")};
116  nav2::Publisher<nav2_msgs::msg::BehaviorTreeLog>::SharedPtr log_pub_;
117  std::vector<nav2_msgs::msg::BehaviorTreeStatusChange> event_log_;
118 };
119 
120 } // namespace nav2_behavior_tree
121 
122 #endif // NAV2_BEHAVIOR_TREE__ROS_TOPIC_LOGGER_HPP_
A class to publish BT logs on BT status change.
RosTopicLogger(const nav2::LifecycleNode::WeakPtr &ros_node, const BT::Tree &tree, bool log_idle=true)
A constructor for nav2_behavior_tree::RosTopicLogger.
void flush() override
Clear log buffer if any.
void callback(BT::Duration timestamp, const BT::TreeNode &node, BT::NodeStatus prev_status, BT::NodeStatus status) override
Callback function which is called each time BT changes status.