Nav2 Navigation Stack - rolling  main
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 #include "nav2_msgs/msg/waypoint_status.hpp"
32 
33 // The follow templates are required when using Groot 2 to visualize the BT. They
34 // convert the data types into JSON format easy for visualization.
35 
36 namespace builtin_interfaces::msg
37 {
38 
39 BT_JSON_CONVERTER(builtin_interfaces::msg::Time, msg)
40 {
41  add_field("sec", &msg.sec);
42  add_field("nanosec", &msg.nanosec);
43 }
44 
45 } // namespace builtin_interfaces::msg
46 
47 namespace std_msgs::msg
48 {
49 
50 BT_JSON_CONVERTER(std_msgs::msg::Header, msg)
51 {
52  add_field("stamp", &msg.stamp);
53  add_field("frame_id", &msg.frame_id);
54 }
55 
56 } // namespace std_msgs::msg
57 
58 namespace geometry_msgs::msg
59 {
60 
61 BT_JSON_CONVERTER(geometry_msgs::msg::Point, msg)
62 {
63  add_field("x", &msg.x);
64  add_field("y", &msg.y);
65  add_field("z", &msg.z);
66 }
67 
68 BT_JSON_CONVERTER(geometry_msgs::msg::Quaternion, msg)
69 {
70  add_field("x", &msg.x);
71  add_field("y", &msg.y);
72  add_field("z", &msg.z);
73  add_field("w", &msg.w);
74 }
75 
76 BT_JSON_CONVERTER(geometry_msgs::msg::Pose, msg)
77 {
78  add_field("position", &msg.position);
79  add_field("orientation", &msg.orientation);
80 }
81 
82 BT_JSON_CONVERTER(geometry_msgs::msg::PoseStamped, msg)
83 {
84  add_field("header", &msg.header);
85  add_field("pose", &msg.pose);
86 }
87 
88 } // namespace geometry_msgs::msg
89 
90 namespace nav_msgs::msg
91 {
92 
93 BT_JSON_CONVERTER(nav_msgs::msg::Goals, msg)
94 {
95  add_field("header", &msg.header);
96  add_field("goals", &msg.goals);
97 }
98 
99 BT_JSON_CONVERTER(nav_msgs::msg::Path, msg)
100 {
101  add_field("header", &msg.header);
102  add_field("poses", &msg.poses);
103 }
104 
105 } // namespace nav_msgs::msg
106 
107 namespace nav2_msgs::msg
108 {
109 
110 BT_JSON_CONVERTER(nav2_msgs::msg::WaypointStatus, msg)
111 {
112  add_field("waypoint_status", &msg.waypoint_status);
113  add_field("waypoint_index", &msg.waypoint_index);
114  add_field("waypoint_pose", &msg.waypoint_pose);
115  add_field("error_code", &msg.error_code);
116  add_field("error_msg", &msg.error_msg);
117 }
118 
119 } // namespace nav2_msgs::msg
120 
121 namespace std
122 {
123 
124 inline void from_json(const nlohmann::json & js, std::chrono::milliseconds & dest)
125 {
126  if (js.contains("ms")) {
127  dest = std::chrono::milliseconds(js.at("ms").get<int>());
128  } else {
129  throw std::runtime_error("Invalid JSON for std::chrono::milliseconds");
130  }
131 }
132 
133 inline void to_json(nlohmann::json & js, const std::chrono::milliseconds & src)
134 {
135  js["__type"] = "std::chrono::milliseconds";
136  js["ms"] = src.count();
137 }
138 
139 } // namespace std
140 
141 #endif // NAV2_BEHAVIOR_TREE__JSON_UTILS_HPP_