Skip to content

Commit 2e66e54

Browse files
committed
added example of move_base action
1 parent 7dba541 commit 2e66e54

File tree

4 files changed

+134
-4
lines changed

4 files changed

+134
-4
lines changed

CMakeLists.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
1212

1313
######################################################
1414

15-
set(ROS_DEPENDENCIES roscpp std_msgs message_generation behaviortree_cpp)
15+
set(ROS_DEPENDENCIES
16+
roscpp std_msgs behaviortree_cpp_v3 actionlib_msgs actionlib message_generation)
1617

1718
find_package(catkin REQUIRED COMPONENTS ${ROS_DEPENDENCIES} )
1819
find_package(GTest)
@@ -45,10 +46,13 @@ include_directories( include ${catkin_INCLUDE_DIRS})
4546
# LIBRARIES
4647

4748
add_library(behaviortree_ros
48-
src/loggers/rosout_logger.cpp )
49+
src/loggers/rosout_logger.cpp
50+
src/actions/movebase_client.cpp
51+
)
4952

5053
target_link_libraries(behaviortree_ros ${catkin_LIBRARIES})
5154

55+
5256
######################################################
5357
# TESTS
5458

package.xml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,15 @@
1313

1414
<build_depend>roscpp</build_depend>
1515
<build_depend>std_msgs</build_depend>
16-
<build_depend>behaviortree_cpp</build_depend>
16+
<build_depend>behaviortree_cpp_v3</build_depend>
17+
<build_depend>actionlib</build_depend>
18+
<build_depend>actionlib_msgs</build_depend>
1719

1820
<run_depend>roscpp</run_depend>
1921
<run_depend>std_msgs</run_depend>
20-
<run_depend>behaviortree_cpp</run_depend>
22+
<run_depend>behaviortree_cpp_v3</run_depend>
23+
<run_depend>actionlib</run_depend>
24+
<run_depend>actionlib_msgs</run_depend>
2125

2226
<build_depend>message_generation</build_depend>
2327
<run_depend>message_generation</run_depend>

src/actions/movebase_client.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include "movebase_client.h"
2+
3+
BT::NodeStatus MoveBase::tick() {
4+
// if no server is present, fail after 2 seconds
5+
if (!_client.waitForServer(ros::Duration(2.0))) {
6+
ROS_ERROR("Can't contact move_base server");
7+
return BT::NodeStatus::FAILURE;
8+
}
9+
10+
// Take the goal from the InputPort of the Node
11+
Pose2D goal;
12+
if (!getInput<Pose2D>("goal", goal)) {
13+
// if I can't get this, there is something wrong with your BT.
14+
// For this reason throw an exception instead of returning FAILURE
15+
throw BT::RuntimeError("missing required input [goal]");
16+
}
17+
18+
// Reset this flag
19+
_aborted = false;
20+
21+
ROS_INFO("Sending goal %f %f", goal.x, goal.y);
22+
23+
// Build the message from Pose2D
24+
move_base_msgs::MoveBaseGoal msg;
25+
msg.target_pose.header.frame_id = "map";
26+
msg.target_pose.header.stamp = ros::Time::now();
27+
msg.target_pose.pose.position.x = goal.x;
28+
msg.target_pose.pose.position.y = goal.y;
29+
tf::Quaternion rot = tf::createQuaternionFromYaw(goal.theta);
30+
tf::quaternionTFToMsg(rot, msg.target_pose.pose.orientation);
31+
32+
_client.sendGoal(msg);
33+
34+
while (!_aborted && !_client.waitForResult(ros::Duration(0.02))) {
35+
// polling at 50 Hz. No big deal in terms of CPU
36+
}
37+
38+
if (_aborted) {
39+
// this happens only if method halt() was invoked
40+
_client.cancelAllGoals();
41+
ROS_ERROR("MoveBase aborted");
42+
return BT::NodeStatus::FAILURE;
43+
}
44+
45+
if (_client.getState() != actionlib::SimpleClientGoalState::SUCCEEDED) {
46+
ROS_ERROR("MoveBase failed");
47+
return BT::NodeStatus::FAILURE;
48+
}
49+
50+
ROS_INFO("Target reached");
51+
return BT::NodeStatus::SUCCESS;
52+
}

src/actions/movebase_client.h

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#pragma once
2+
3+
#include <ros/ros.h>
4+
#include <move_base_msgs/MoveBaseAction.h>
5+
#include <actionlib/client/simple_action_client.h>
6+
#include <behaviortree_cpp/action_node.h>
7+
#include <tf/transform_datatypes.h>
8+
9+
10+
// Custom type
11+
struct Pose2D
12+
{
13+
double x, y, theta;
14+
};
15+
16+
17+
namespace BT
18+
{
19+
template <> inline
20+
Pose2D convertFromString(StringView key)
21+
{
22+
// three real numbers separated by semicolons
23+
auto parts = BT::splitString(key, ';');
24+
if (parts.size() != 3)
25+
{
26+
throw BT::RuntimeError("invalid input)");
27+
}
28+
else
29+
{
30+
Pose2D output;
31+
output.x = convertFromString<double>(parts[0]);
32+
output.y = convertFromString<double>(parts[1]);
33+
output.theta = convertFromString<double>(parts[2]);
34+
return output;
35+
}
36+
}
37+
} // end namespace BT
38+
39+
//----------------------------------------------------------------
40+
41+
class MoveBase : public BT::AsyncActionNode
42+
{
43+
public:
44+
45+
MoveBase(const std::string& name, const BT::NodeConfiguration& config)
46+
: BT::AsyncActionNode(name, config),
47+
_client("move_base", true)
48+
{
49+
}
50+
51+
// It is mandatory to define this static method.
52+
static BT::PortsList providedPorts()
53+
{
54+
return{ BT::InputPort<Pose2D>("goal") };
55+
}
56+
57+
virtual BT::NodeStatus tick() override;
58+
59+
virtual void halt() override
60+
{
61+
_aborted = true;
62+
}
63+
64+
private:
65+
typedef actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> MoveBaseClient;
66+
MoveBaseClient _client;
67+
bool _aborted;
68+
};
69+
70+

0 commit comments

Comments
 (0)