Skip to content

Commit ffec3a3

Browse files
committed
bugfix on nested messages
1 parent e473e38 commit ffec3a3

File tree

5 files changed

+51
-16
lines changed

5 files changed

+51
-16
lines changed

Docker/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get install libncurses5-dev libncursesw5-
2020
RUN apt-get update && apt-get install qtbase5-dev libqt5svg5-dev libzmq3-dev libdw-dev -y
2121
RUN apt-get update && apt-get install -y gosu
2222

23+
2324
COPY entrypoint.sh /entrypoint.sh
2425
COPY deps.repos /deps.repos
2526
# Make sure it is executable

Docker/deps.repos

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ repositories:
1818
groot:
1919
type: git
2020
url: [email protected]:haru-project/Groot.git
21-
version: jazzy
21+
version: jazzy
22+
23+

Docker/docker-compose.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ services:
1717
- ./.vscode:/home/user/eut_bt_ros2_ws/.vscode
1818
- ../behaviortree_ros2:/home/user/eut_bt_ros2_ws/src/behaviortree_ros2
1919
- ../btcpp_ros2_interfaces:/home/user/eut_bt_ros2_ws/src/btcpp_ros2_interfaces
20-
- ../bt_examples:/home/user/eut_bt_ros2_ws/src/bt_examples
20+
- ../bt_examples:/home/user/eut_bt_ros2_ws/src/bt_examples
21+
- ../../behavior_tree_temi:/home/user/eut_bt_ros2_ws/src/behavior_tree_temi
22+
2123
tty: true
2224
stdin_open: true
2325
environment:

Docker/entrypoint.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,4 @@ exec gosu "$USERNAME" bash -c "
9292
colcon build --symlink-install;
9393
9494
exec \"$@\";
95-
"
95+
"

behaviortree_ros2/include/behaviortree_ros2/serialization_policies.hpp

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include "behaviortree_ros2/parser_utils.hpp"
55
#include "behaviortree_eut_plugins/utils/deserialize_json.h"
6+
#include <boost/property_tree/ptree.hpp>
7+
#include <boost/property_tree/json_parser.hpp>
68

79
namespace BT_ROS
810

@@ -89,30 +91,57 @@ struct AutomaticSerialization
8991
return ports;
9092
}
9193

92-
93-
void onNewMessage(const std::shared_ptr<MessageType>& _message, BT::TreeNode& _tree_node,
94-
const std::string& _base_port_name = "")
94+
// Helper to extract nested fields "header.frame_id" [header][frame_id]
95+
nlohmann::json getNestedValue(const nlohmann::json& j, const std::string& dotted_key)
9596
{
96-
if(isMsgEmpty<MessageType>()) { return; }
97+
std::istringstream iss(dotted_key);
98+
std::string token;
99+
const nlohmann::json* current = &j;
100+
while (std::getline(iss, token, '.'))
101+
{
102+
if (!current->contains(token))
103+
throw std::runtime_error("Missing key: " + token + " in " + dotted_key);
104+
current = &((*current)[token]);
105+
}
106+
107+
return *current;
108+
}
97109

110+
void onNewMessage( const std::shared_ptr<MessageType>& _message, BT::TreeNode& _tree_node, const std::string& _base_port_name = "")
111+
{
112+
if(isMsgEmpty<MessageType>()) { return; }
113+
98114
std::vector<uint8_t> buffer_in = RosMsgParser::BuildMessageBuffer(*(_message.get()), topic_type_);
99115
std::string json_text;
100116
RosMsgParser::ROS2_Deserializer deserializer_;
101117
parser_->deserializeIntoJson(buffer_in, &json_text, &deserializer_, 0, true, true);
102118
nlohmann::json json_parsed = nlohmann::json::parse(json_text);
103-
119+
104120
const auto& field_ports = fieldPorts<MessageType>({RosMsgParser::ROSType("builtin_interfaces/Time")});
121+
105122
for(const auto& field_port : field_ports)
106123
{
107-
// Time and duration defaults to ros::Time::now and zero
108-
// TODO should we allow users to set this themselves? If so, how would they
109-
// write it? Maybe a custom convertFromString()?
110124
const auto type_id = field_port.second.type().typeID();
111-
if(type_id == RosMsgParser::TIME ||
112-
type_id == RosMsgParser::DURATION) { continue; }
113-
114-
std::string port_name = _base_port_name.empty() ? field_port.first : _base_port_name + "_" + field_port.first;
115-
BT::EutUtils::deserializeField(_tree_node, port_name, json_parsed[field_port.first]);
125+
if(type_id == RosMsgParser::TIME || type_id == RosMsgParser::DURATION)
126+
continue;
127+
128+
std::string port_name = _base_port_name.empty()
129+
? field_port.first
130+
: _base_port_name + "_" + field_port.first;
131+
132+
try
133+
{
134+
nlohmann::json value = getNestedValue(json_parsed, field_port.first);
135+
136+
BT::EutUtils::deserializeField(_tree_node, port_name, value);
137+
138+
}
139+
catch(const std::exception& e)
140+
{
141+
std::cerr << "Warning: could not deserialize field " << field_port.first
142+
<< ": " << e.what() << std::endl;
143+
}
144+
116145
}
117146
}
118147

@@ -249,3 +278,4 @@ struct CustomSerialization
249278
} // namespace BT_ROS
250279

251280
#endif
281+

0 commit comments

Comments
 (0)