Skip to content

Commit 27dcb5d

Browse files
author
Michael Jeronimo
authored
Merge pull request #1 from mjeronimo/pose-iterator
Add a decorator node that sequences its input poses
2 parents e26da68 + a4b4147 commit 27dcb5d

File tree

9 files changed

+204
-88
lines changed

9 files changed

+204
-88
lines changed

‎ros2_behavior_tree/examples/minimal/main.cpp‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,17 @@ static const char bt_xml[] =
6666
<ThrottleTickRate hz="1.0">
6767
<Sequence>
6868
<Message msg="GetPoseNearRobot"/>
69-
<GetPoseNearRobot robot_pose="{leader_pose}" nearby_pose="{nearby_pose}"/>
70-
<Message msg="Computing path to the goal"/>
71-
<ComputePathToPose action_name="compute_path_to_pose" server_timeout="1000" ros2_node="{ros_node_2}" goal="{nearby_pose}" planner_id="GridBased" path="{path}"/>
69+
<GetPosesNearRobot robot_pose="{leader_pose}" nearby_poses="{nearby_poses}"/>
70+
<ForEachPose poses="{nearby_poses}" pose="{goal_pose}">
71+
<Sequence>
72+
<Message msg="Computing path to the goal"/>
73+
<ComputePathToPose action_name="compute_path_to_pose" server_timeout="1000" ros2_node="{ros_node_2}" goal="{goal_pose}" planner_id="GridBased" path="{path_to_follow}"/>
74+
</Sequence>
75+
</ForEachPose>
7276
<AsyncWait msec="1000"/>
7377
</Sequence>
7478
</ThrottleTickRate>
75-
<FollowPath action_name="follow_path" server_timeout="1000" ros2_node="{ros_node_2}" path="{path}" controller_id="FollowPath"/>
79+
<FollowPath action_name="follow_path" server_timeout="1000" ros2_node="{ros_node_2}" path="{path_to_follow}" controller_id="FollowPath"/>
7680
</PipelineSequence>
7781
</DistanceConstraint>
7882
</ReactiveSequence>

‎ros2_behavior_tree/include/ros2_behavior_tree/action/async_wait_node.hpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ class AsyncWaitNode : public BT::AsyncActionNode
6767
// Wait for the specified duration
6868
std::mutex mtx;
6969
std::unique_lock<std::mutex> lck(mtx);
70-
auto status = cv_.wait_for(lck, std::chrono::milliseconds(wait_duration_));
70+
cv_.wait_for(lck, std::chrono::milliseconds(wait_duration_));
7171

72-
return (status == std::cv_status::timeout) ? BT::NodeStatus::SUCCESS : BT::NodeStatus::FAILURE;
72+
return BT::NodeStatus::SUCCESS;
7373
}
7474

7575
private:

‎ros2_behavior_tree/include/ros2_behavior_tree/action/compute_path_to_pose_node.hpp‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
#ifndef ROS2_BEHAVIOR_TREE__ACTION__COMPUTE_PATH_TO_POSE_NODE_HPP_
1616
#define ROS2_BEHAVIOR_TREE__ACTION__COMPUTE_PATH_TO_POSE_NODE_HPP_
1717

18-
#include <memory>
1918
#include <string>
20-
#include <vector>
2119

2220
#include "ros2_behavior_tree/ros2_action_client_node.hpp"
2321
#include "nav2_msgs/action/compute_path_to_pose.hpp"

‎ros2_behavior_tree/include/ros2_behavior_tree/action/follow_path_node.hpp‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
#ifndef ROS2_BEHAVIOR_TREE__ACTION__FOLLOW_PATH_NODE_HPP_
1616
#define ROS2_BEHAVIOR_TREE__ACTION__FOLLOW_PATH_NODE_HPP_
1717

18-
#include <memory>
1918
#include <string>
20-
#include <vector>
2119

2220
#include "ros2_behavior_tree/ros2_action_client_node.hpp"
2321
#include "nav2_msgs/action/follow_path.hpp"

‎ros2_behavior_tree/include/ros2_behavior_tree/action/get_pose_near_robot_node.hpp‎

Lines changed: 0 additions & 76 deletions
This file was deleted.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright (c) 2018 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 ROS2_BEHAVIOR_TREE__ACTION__GET_POSES_NEAR_ROBOT_NODE_HPP_
16+
#define ROS2_BEHAVIOR_TREE__ACTION__GET_POSES_NEAR_ROBOT_NODE_HPP_
17+
18+
#include <string>
19+
#include <memory>
20+
#include <vector>
21+
22+
#include "behaviortree_cpp_v3/action_node.h"
23+
#include "geometry_msgs/msg/pose_stamped.hpp"
24+
#include "rclcpp/rclcpp.hpp"
25+
#include "tf2_geometry_msgs/tf2_geometry_msgs.h"
26+
27+
namespace ros2_behavior_tree
28+
{
29+
30+
class GetPosesNearRobotNode : public BT::SyncActionNode
31+
{
32+
public:
33+
GetPosesNearRobotNode(const std::string & name, const BT::NodeConfiguration & config)
34+
: BT::SyncActionNode(name, config)
35+
{
36+
}
37+
38+
static BT::PortsList providedPorts()
39+
{
40+
return {
41+
BT::InputPort<std::shared_ptr<geometry_msgs::msg::PoseStamped>>("robot_pose",
42+
"The current pose of the robot"),
43+
BT::OutputPort<std::vector<geometry_msgs::msg::PoseStamped>>("nearby_poses",
44+
"Poses near the robot")
45+
};
46+
}
47+
48+
BT::NodeStatus tick() override
49+
{
50+
std::shared_ptr<geometry_msgs::msg::PoseStamped> robot_pose;
51+
if (!getInput<std::shared_ptr<geometry_msgs::msg::PoseStamped>>("robot_pose", robot_pose)) {
52+
throw BT::RuntimeError("Missing parameter [robot_pose] in GetPosesNearRobot node");
53+
}
54+
55+
std::vector<geometry_msgs::msg::PoseStamped> nearby_poses;
56+
57+
// TODO(mjeronimo): Hard-coded values until we implement this operation
58+
59+
geometry_msgs::msg::PoseStamped pose1;
60+
pose1.pose.position.x = robot_pose->pose.position.x - 1.2;
61+
pose1.pose.position.y = robot_pose->pose.position.y;
62+
pose1.pose.position.z = robot_pose->pose.position.z;
63+
pose1.pose.orientation.x = robot_pose->pose.orientation.x;
64+
pose1.pose.orientation.y = robot_pose->pose.orientation.y;
65+
pose1.pose.orientation.z = robot_pose->pose.orientation.z;
66+
pose1.pose.orientation.w = robot_pose->pose.orientation.w;
67+
68+
nearby_poses.push_back(pose1);
69+
70+
geometry_msgs::msg::PoseStamped pose2;
71+
pose2.pose.position.x = robot_pose->pose.position.x;
72+
pose2.pose.position.y = robot_pose->pose.position.y - 1.2;
73+
pose2.pose.position.z = robot_pose->pose.position.z;
74+
pose2.pose.orientation.x = robot_pose->pose.orientation.x;
75+
pose2.pose.orientation.y = robot_pose->pose.orientation.y;
76+
pose2.pose.orientation.z = robot_pose->pose.orientation.z;
77+
pose2.pose.orientation.w = robot_pose->pose.orientation.w;
78+
79+
nearby_poses.push_back(pose2);
80+
81+
if (!setOutput<std::vector<geometry_msgs::msg::PoseStamped>>("nearby_poses", nearby_poses)) {
82+
throw BT::RuntimeError(
83+
"Failed to set output port value [nearby_poses] for GetPosesNearRobot");
84+
}
85+
86+
return BT::NodeStatus::SUCCESS;
87+
}
88+
};
89+
90+
} // namespace ros2_behavior_tree
91+
92+
#endif // ROS2_BEHAVIOR_TREE__ACTION__GET_POSES_NEAR_ROBOT_NODE_HPP_
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright (c) 2018 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 ROS2_BEHAVIOR_TREE__DECORATOR__FOR_EACH_POSE_NODE_HPP_
16+
#define ROS2_BEHAVIOR_TREE__DECORATOR__FOR_EACH_POSE_NODE_HPP_
17+
18+
#include <string>
19+
#include <memory>
20+
#include <vector>
21+
22+
#include "behaviortree_cpp_v3/action_node.h"
23+
#include "geometry_msgs/msg/pose_stamped.hpp"
24+
#include "rclcpp/rclcpp.hpp"
25+
#include "tf2_geometry_msgs/tf2_geometry_msgs.h"
26+
27+
namespace ros2_behavior_tree
28+
{
29+
30+
class ForEachPoseNode : public BT::DecoratorNode
31+
{
32+
public:
33+
ForEachPoseNode(const std::string & name, const BT::NodeConfiguration & config)
34+
: BT::DecoratorNode(name, config)
35+
{
36+
}
37+
38+
static BT::PortsList providedPorts()
39+
{
40+
return {
41+
BT::InputPort<std::vector<geometry_msgs::msg::PoseStamped>>("poses", "Poses to iterate over"),
42+
BT::OutputPort<geometry_msgs::msg::PoseStamped>("pose", "The next pose in the sequence")
43+
};
44+
}
45+
46+
BT::NodeStatus tick() override
47+
{
48+
std::vector<geometry_msgs::msg::PoseStamped> poses;
49+
if (!getInput<std::vector<geometry_msgs::msg::PoseStamped>>("poses", poses)) {
50+
throw BT::RuntimeError("Missing parameter [poses] in GetNextPose node");
51+
}
52+
53+
if (poses.size() == 0) {
54+
return BT::NodeStatus::FAILURE;
55+
}
56+
57+
setStatus(BT::NodeStatus::RUNNING);
58+
59+
if (!setOutput<geometry_msgs::msg::PoseStamped>("pose", poses[0])) {
60+
throw BT::RuntimeError("Failed to set output port value [next_pose] for GetNextPose");
61+
}
62+
63+
for (int i = 0; i < poses.size(); ) {
64+
if (!setOutput<geometry_msgs::msg::PoseStamped>("pose", poses[i])) {
65+
throw BT::RuntimeError("Failed to set output port value [next_pose] for GetNextPose");
66+
}
67+
68+
auto child_state = child_node_->executeTick();
69+
70+
switch (child_state) {
71+
case BT::NodeStatus::SUCCESS:
72+
return BT::NodeStatus::SUCCESS;
73+
74+
case BT::NodeStatus::RUNNING:
75+
continue;
76+
77+
case BT::NodeStatus::FAILURE:
78+
// Try the next one
79+
i++;
80+
continue;
81+
82+
default:
83+
throw BT::LogicError("Invalid status return from BT node");
84+
}
85+
}
86+
87+
// None of the poses worked, so fail
88+
child()->halt();
89+
return BT::NodeStatus::FAILURE;
90+
}
91+
};
92+
93+
} // namespace ros2_behavior_tree
94+
95+
#endif // ROS2_BEHAVIOR_TREE__DECORATOR__FOR_EACH_POSE_NODE_HPP_

‎ros2_behavior_tree/src/behavior_tree.cpp‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <vector>
2020

2121
#include "behaviortree_cpp_v3/xml_parsing.h"
22+
#include "behaviortree_cpp_v3/loggers/bt_cout_logger.h"
2223
#include "rclcpp/rclcpp.hpp"
2324

2425
namespace ros2_behavior_tree
@@ -50,6 +51,8 @@ BehaviorTree::execute(
5051
// Create the corresponding Behavior Tree
5152
BT::Tree tree = xml_parser_.instantiateTree(blackboard_);
5253

54+
BT::StdCoutLogger logger(tree);
55+
5356
// Set up a loop rate controller based on the desired tick period
5457
rclcpp::WallRate loop_rate(tick_period);
5558

‎ros2_behavior_tree/src/node_registrar.cpp‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@
2121
#include "ros2_behavior_tree/action/create_ros2_node.hpp"
2222
#include "ros2_behavior_tree/action/create_transform_buffer_node.hpp"
2323
#include "ros2_behavior_tree/action/follow_path_node.hpp"
24-
#include "ros2_behavior_tree/action/get_pose_near_robot_node.hpp"
24+
#include "ros2_behavior_tree/action/get_poses_near_robot_node.hpp"
2525
#include "ros2_behavior_tree/action/transform_pose_node.hpp"
2626
#include "ros2_behavior_tree/condition/can_transform_node.hpp"
2727
#include "ros2_behavior_tree/control/first_result_node.hpp"
2828
#include "ros2_behavior_tree/control/pipeline_sequence_node.hpp"
2929
#include "ros2_behavior_tree/control/recovery_node.hpp"
3030
#include "ros2_behavior_tree/control/round_robin_node.hpp"
3131
#include "ros2_behavior_tree/decorator/distance_constraint_node.hpp"
32+
#include "ros2_behavior_tree/decorator/for_each_pose_node.hpp"
3233
#include "ros2_behavior_tree/decorator/forever_node.hpp"
3334
#include "ros2_behavior_tree/decorator/repeat_until_node.hpp"
3435
#include "ros2_behavior_tree/decorator/throttle_tick_rate_node.hpp"
@@ -57,7 +58,8 @@ NodeRegistrar::RegisterNodes(BT::BehaviorTreeFactory & factory)
5758
factory.registerNodeType<ros2_behavior_tree::FirstResultNode>("FirstResult");
5859
factory.registerNodeType<ros2_behavior_tree::FollowPathNode>("FollowPath");
5960
factory.registerNodeType<ros2_behavior_tree::ForeverNode>("Forever");
60-
factory.registerNodeType<ros2_behavior_tree::GetPoseNearRobotNode>("GetPoseNearRobot");
61+
factory.registerNodeType<ros2_behavior_tree::ForEachPoseNode>("ForEachPose");
62+
factory.registerNodeType<ros2_behavior_tree::GetPosesNearRobotNode>("GetPosesNearRobot");
6163
factory.registerNodeType<ros2_behavior_tree::PipelineSequenceNode>("PipelineSequence");
6264
factory.registerNodeType<ros2_behavior_tree::RecoveryNode>("Recovery");
6365
factory.registerNodeType<ros2_behavior_tree::RepeatUntilNode>("RepeatUntil");

0 commit comments

Comments
 (0)