Skip to content

Commit c1ad9fe

Browse files
committed
fix bt_utils
Signed-off-by: Tony Najjar <[email protected]>
1 parent 4ecd651 commit c1ad9fe

File tree

2 files changed

+101
-7
lines changed

2 files changed

+101
-7
lines changed

nav2_behavior_tree/include/nav2_behavior_tree/bt_utils.hpp

+34-4
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,36 @@ inline geometry_msgs::msg::PoseStamped convertFromString(const StringView key)
104104
}
105105
}
106106

107+
/**
108+
* @brief Parse XML string to std::vector<geometry_msgs::msg::PoseStamped>
109+
* @param key XML string
110+
* @return std::vector<geometry_msgs::msg::PoseStamped>
111+
*/
112+
template<>
113+
inline std::vector<geometry_msgs::msg::PoseStamped> convertFromString(const StringView key)
114+
{
115+
auto parts = BT::splitString(key, ';');
116+
if (parts.size() % 9 != 0) {
117+
throw std::runtime_error("invalid number of fields for std::vector<PoseStamped> attribute)");
118+
} else {
119+
std::vector<geometry_msgs::msg::PoseStamped> poses;
120+
for (size_t i = 0; i < parts.size(); i += 9) {
121+
geometry_msgs::msg::PoseStamped pose_stamped;
122+
pose_stamped.header.stamp = rclcpp::Time(BT::convertFromString<int64_t>(parts[i]));
123+
pose_stamped.header.frame_id = BT::convertFromString<std::string>(parts[i + 1]);
124+
pose_stamped.pose.position.x = BT::convertFromString<double>(parts[i + 2]);
125+
pose_stamped.pose.position.y = BT::convertFromString<double>(parts[i + 3]);
126+
pose_stamped.pose.position.z = BT::convertFromString<double>(parts[i + 4]);
127+
pose_stamped.pose.orientation.x = BT::convertFromString<double>(parts[i + 5]);
128+
pose_stamped.pose.orientation.y = BT::convertFromString<double>(parts[i + 6]);
129+
pose_stamped.pose.orientation.z = BT::convertFromString<double>(parts[i + 7]);
130+
pose_stamped.pose.orientation.w = BT::convertFromString<double>(parts[i + 8]);
131+
poses.push_back(pose_stamped);
132+
}
133+
return poses;
134+
}
135+
}
136+
107137
/**
108138
* @brief Parse XML string to geometry_msgs::msg::PoseStampedArray
109139
* @param key XML string
@@ -112,13 +142,14 @@ inline geometry_msgs::msg::PoseStamped convertFromString(const StringView key)
112142
template<>
113143
inline geometry_msgs::msg::PoseStampedArray convertFromString(const StringView key)
114144
{
115-
// 9 real numbers separated by semicolons
116145
auto parts = BT::splitString(key, ';');
117-
if (parts.size() % 9 != 0) {
146+
if ((parts.size() - 2) % 9 != 0) {
118147
throw std::runtime_error("invalid number of fields for PoseStampedArray attribute)");
119148
} else {
120149
geometry_msgs::msg::PoseStampedArray pose_stamped_array;
121-
for (size_t i = 0; i < parts.size(); i += 9) {
150+
pose_stamped_array.header.stamp = rclcpp::Time(BT::convertFromString<int64_t>(parts[0]));
151+
pose_stamped_array.header.frame_id = BT::convertFromString<std::string>(parts[1]);
152+
for (size_t i = 2; i < parts.size(); i += 9) {
122153
geometry_msgs::msg::PoseStamped pose_stamped;
123154
pose_stamped.header.stamp = rclcpp::Time(BT::convertFromString<int64_t>(parts[i]));
124155
pose_stamped.header.frame_id = BT::convertFromString<std::string>(parts[i + 1]);
@@ -143,7 +174,6 @@ inline geometry_msgs::msg::PoseStampedArray convertFromString(const StringView k
143174
template<>
144175
inline nav_msgs::msg::Path convertFromString(const StringView key)
145176
{
146-
// 9 real numbers separated by semicolons
147177
auto parts = BT::splitString(key, ';');
148178
if ((parts.size() - 2) % 9 != 0) {
149179
throw std::runtime_error("invalid number of fields for Path attribute)");

nav2_behavior_tree/test/test_bt_utils.cpp

+67-3
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,77 @@ TEST(PoseStampedPortTest, test_correct_syntax)
194194
EXPECT_EQ(value.pose.orientation.w, 7.0);
195195
}
196196

197+
TEST(PoseStampedVectorPortTest, test_wrong_syntax)
198+
{
199+
std::string xml_txt =
200+
R"(
201+
<root BTCPP_format="4">
202+
<BehaviorTree ID="MainTree">
203+
<PoseStampedVectorPortTest test="0;map;1.0;2.0;3.0;4.0;5.0;6.0;7.0;0;map;1.0;2.0;3.0;4.0;5.0;6.0" />
204+
</BehaviorTree>
205+
</root>)";
206+
207+
BT::BehaviorTreeFactory factory;
208+
factory.registerNodeType<TestNode<std::vector<geometry_msgs::msg::PoseStamped>>>(
209+
"PoseStampedVectorPortTest");
210+
EXPECT_THROW(factory.createTreeFromText(xml_txt), std::exception);
211+
212+
xml_txt =
213+
R"(
214+
<root BTCPP_format="4">
215+
<BehaviorTree ID="MainTree">
216+
<PoseStampedVectorPortTest test="0;map;1.0;2.0;3.0;4.0;5.0;6.0;7.0;0;map;1.0;2.0;3.0;4.0;5.0;6.0;7.0;8.0" />
217+
</BehaviorTree>
218+
</root>)";
219+
220+
EXPECT_THROW(factory.createTreeFromText(xml_txt), std::exception);
221+
}
222+
223+
TEST(PoseStampedVectorPortTest, test_correct_syntax)
224+
{
225+
std::string xml_txt =
226+
R"(
227+
<root BTCPP_format="4">
228+
<BehaviorTree ID="MainTree">
229+
<PoseStampedVectorPortTest test="0;map;1.0;2.0;3.0;4.0;5.0;6.0;7.0;0;odom;8.0;9.0;10.0;11.0;12.0;13.0;14.0" />
230+
</BehaviorTree>
231+
</root>)";
232+
233+
BT::BehaviorTreeFactory factory;
234+
factory.registerNodeType<TestNode<std::vector<geometry_msgs::msg::PoseStamped>>>(
235+
"PoseStampedVectorPortTest");
236+
auto tree = factory.createTreeFromText(xml_txt);
237+
238+
tree = factory.createTreeFromText(xml_txt);
239+
std::vector<geometry_msgs::msg::PoseStamped> values;
240+
tree.rootNode()->getInput("test", values);
241+
EXPECT_EQ(rclcpp::Time(values[0].header.stamp).nanoseconds(), 0);
242+
EXPECT_EQ(values[0].header.frame_id, "map");
243+
EXPECT_EQ(values[0].pose.position.x, 1.0);
244+
EXPECT_EQ(values[0].pose.position.y, 2.0);
245+
EXPECT_EQ(values[0].pose.position.z, 3.0);
246+
EXPECT_EQ(values[0].pose.orientation.x, 4.0);
247+
EXPECT_EQ(values[0].pose.orientation.y, 5.0);
248+
EXPECT_EQ(values[0].pose.orientation.z, 6.0);
249+
EXPECT_EQ(values[0].pose.orientation.w, 7.0);
250+
EXPECT_EQ(rclcpp::Time(values[1].header.stamp).nanoseconds(), 0);
251+
EXPECT_EQ(values[1].header.frame_id, "odom");
252+
EXPECT_EQ(values[1].pose.position.x, 8.0);
253+
EXPECT_EQ(values[1].pose.position.y, 9.0);
254+
EXPECT_EQ(values[1].pose.position.z, 10.0);
255+
EXPECT_EQ(values[1].pose.orientation.x, 11.0);
256+
EXPECT_EQ(values[1].pose.orientation.y, 12.0);
257+
EXPECT_EQ(values[1].pose.orientation.z, 13.0);
258+
EXPECT_EQ(values[1].pose.orientation.w, 14.0);
259+
}
260+
197261
TEST(PoseStampedArrayPortTest, test_wrong_syntax)
198262
{
199263
std::string xml_txt =
200264
R"(
201265
<root BTCPP_format="4">
202266
<BehaviorTree ID="MainTree">
203-
<PoseStampedArrayPortTest test="0;map;1.0;2.0;3.0;4.0;5.0;6.0;7.0;0;map;1.0;2.0;3.0;4.0;5.0;6.0" />
267+
<PoseStampedArrayPortTest test="0;map;0;map;1.0;2.0;3.0;4.0;5.0;6.0;7.0;0;map;1.0;2.0;3.0;4.0;5.0;6.0" />
204268
</BehaviorTree>
205269
</root>)";
206270

@@ -213,7 +277,7 @@ TEST(PoseStampedArrayPortTest, test_wrong_syntax)
213277
R"(
214278
<root BTCPP_format="4">
215279
<BehaviorTree ID="MainTree">
216-
<PoseStampedArrayPortTest test="0;map;1.0;2.0;3.0;4.0;5.0;6.0;7.0;0;map;1.0;2.0;3.0;4.0;5.0;6.0;7.0;8.0" />
280+
<PoseStampedArrayPortTest test="0;map;0;map;1.0;2.0;3.0;4.0;5.0;6.0;7.0;0;map;1.0;2.0;3.0;4.0;5.0;6.0;7.0;8.0" />
217281
</BehaviorTree>
218282
</root>)";
219283

@@ -226,7 +290,7 @@ TEST(PoseStampedArrayPortTest, test_correct_syntax)
226290
R"(
227291
<root BTCPP_format="4">
228292
<BehaviorTree ID="MainTree">
229-
<PoseStampedArrayPortTest test="0;map;1.0;2.0;3.0;4.0;5.0;6.0;7.0;0;odom;8.0;9.0;10.0;11.0;12.0;13.0;14.0" />
293+
<PoseStampedArrayPortTest test="0;map;0;map;1.0;2.0;3.0;4.0;5.0;6.0;7.0;0;odom;8.0;9.0;10.0;11.0;12.0;13.0;14.0" />
230294
</BehaviorTree>
231295
</root>)";
232296

0 commit comments

Comments
 (0)