Nav2 Navigation Stack - jazzy  jazzy
ROS 2 Navigation Stack
json_utils.hpp
1 // Copyright (c) 2025 Alberto J. Tudela Roldán
2 // Copyright (c) 2025 Grupo Avispa, DTE, Universidad de Málaga
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #ifndef NAV2_BEHAVIOR_TREE__JSON_UTILS_HPP_
17 #define NAV2_BEHAVIOR_TREE__JSON_UTILS_HPP_
18 
19 #include <string>
20 #include <set>
21 #include <vector>
22 
23 #include "rclcpp/time.hpp"
24 #include "rclcpp/node.hpp"
25 #include "behaviortree_cpp/json_export.h"
26 #include "geometry_msgs/msg/point.hpp"
27 #include "geometry_msgs/msg/pose_stamped.hpp"
28 #include "geometry_msgs/msg/quaternion.hpp"
29 #include "nav_msgs/msg/goals.hpp"
30 #include "nav_msgs/msg/path.hpp"
31 
32 // The follow templates are required when using Groot 2 to visualize the BT. They
33 // convert the data types into JSON format easy for visualization.
34 
35 namespace builtin_interfaces::msg
36 {
37 
38 BT_JSON_CONVERTER(builtin_interfaces::msg::Time, msg)
39 {
40  add_field("sec", &msg.sec);
41  add_field("nanosec", &msg.nanosec);
42 }
43 
44 } // namespace builtin_interfaces::msg
45 
46 namespace std_msgs::msg
47 {
48 
49 BT_JSON_CONVERTER(std_msgs::msg::Header, msg)
50 {
51  add_field("stamp", &msg.stamp);
52  add_field("frame_id", &msg.frame_id);
53 }
54 
55 } // namespace std_msgs::msg
56 
57 namespace geometry_msgs::msg
58 {
59 
60 BT_JSON_CONVERTER(geometry_msgs::msg::Point, msg)
61 {
62  add_field("x", &msg.x);
63  add_field("y", &msg.y);
64  add_field("z", &msg.z);
65 }
66 
67 BT_JSON_CONVERTER(geometry_msgs::msg::Quaternion, msg)
68 {
69  add_field("x", &msg.x);
70  add_field("y", &msg.y);
71  add_field("z", &msg.z);
72  add_field("w", &msg.w);
73 }
74 
75 BT_JSON_CONVERTER(geometry_msgs::msg::Pose, msg)
76 {
77  add_field("position", &msg.position);
78  add_field("orientation", &msg.orientation);
79 }
80 
81 BT_JSON_CONVERTER(geometry_msgs::msg::PoseStamped, msg)
82 {
83  add_field("header", &msg.header);
84  add_field("pose", &msg.pose);
85 }
86 
87 } // namespace geometry_msgs::msg
88 
89 namespace nav_msgs::msg
90 {
91 
92 BT_JSON_CONVERTER(nav_msgs::msg::Goals, msg)
93 {
94  add_field("header", &msg.header);
95  add_field("goals", &msg.goals);
96 }
97 
98 BT_JSON_CONVERTER(nav_msgs::msg::Path, msg)
99 {
100  add_field("header", &msg.header);
101  add_field("poses", &msg.poses);
102 }
103 
104 } // namespace nav_msgs::msg
105 
106 
107 namespace std
108 {
109 
110 inline void from_json(const nlohmann::json & js, std::chrono::milliseconds & dest)
111 {
112  if (js.contains("ms")) {
113  dest = std::chrono::milliseconds(js.at("ms").get<int>());
114  } else {
115  throw std::runtime_error("Invalid JSON for std::chrono::milliseconds");
116  }
117 }
118 
119 inline void to_json(nlohmann::json & js, const std::chrono::milliseconds & src)
120 {
121  js["__type"] = "std::chrono::milliseconds";
122  js["ms"] = src.count();
123 }
124 
125 } // namespace std
126 
127 #endif // NAV2_BEHAVIOR_TREE__JSON_UTILS_HPP_