-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
146 lines (112 loc) · 4.68 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <iostream>
#include "geometry_msgs/msg/pose_stamped.hpp"
#include "behaviortree_cpp/behavior_tree.h"
#include "behaviortree_cpp/bt_factory.h"
#include <string>
#include <functional>
#include <filesystem>
using namespace BT;
// SyncActionNode (synchronous action) with an input port.
class CreateAnyPoseStampedVector : public SyncActionNode {
public:
// If your Node has ports, you must use this constructor signature
CreateAnyPoseStampedVector(const std::string &name, const NodeConfig &config) : SyncActionNode(name, config) {}
// It is mandatory to define this STATIC method.
static PortsList providedPorts() {
return {OutputPort<std::vector<BT::Any>>("pose_stamped_vector", "{vector}",
"this is a BT::Any object on the blackboard")};
}
// Override the virtual function tick()
NodeStatus tick() override {
auto pose1 = geometry_msgs::msg::PoseStamped();
pose1.pose.position.x = 2;
auto pose2 = geometry_msgs::msg::PoseStamped();
pose2.pose.position.x = 3;
std::vector<BT::Any> out = {BT::Any(pose1), BT::Any(pose2)};
setOutput("pose_stamped_vector", out);
return NodeStatus::SUCCESS;
}
};
class ForEachAny : public DecoratorNode {
public:
ForEachAny(const std::string &name, const BT::NodeConfiguration &config) : BT::DecoratorNode(name, config) { }
// It is mandatory to define this STATIC method.
static PortsList providedPorts() {
return {InputPort<std::vector<BT::Any>>(kPortIDInput, "{any_vec}", "Input BT::Any vector to loop over"),
OutputPort<BT::Any>(kPortIDOutput, "{any_val}")};
}
NodeStatus tick() {
const auto input_vector = getInput<std::vector<BT::Any>>(kPortIDInput);
if (!input_vector.has_value()) {
std::cout << input_vector.error() << std::endl;
return BT::NodeStatus::FAILURE;
}
setStatus(BT::NodeStatus::RUNNING);
if (current_index_ < input_vector.value().size()) {
setOutput<BT::Any>(kPortIDOutput, input_vector.value().at(current_index_));
const BT::NodeStatus child_state = child_node_->executeTick();
switch (child_state) {
case BT::NodeStatus::SUCCESS: {
current_index_++;
haltChild();
return BT::NodeStatus::RUNNING;
}
case BT::NodeStatus::FAILURE: {
current_index_ = 0;
haltChild();
return (BT::NodeStatus::FAILURE);
}
case BT::NodeStatus::RUNNING: {
return BT::NodeStatus::RUNNING;
}
default: {
throw BT::LogicError("A child node must never return IDLE");
}
}
}
current_index_ = 0;
return BT::NodeStatus::SUCCESS;
}
void halt() {
current_index_ = 0;
DecoratorNode::halt();
}
static constexpr auto kPortIDInput = "vector_in";
static constexpr auto kPortIDOutput = "out";
std::size_t current_index_{ 0 };
};
// SyncActionNode (synchronous action) with an input port.
class AnyToPoseStamped : public SyncActionNode {
public:
// If your Node has ports, you must use this constructor signature
AnyToPoseStamped(const std::string &name, const NodeConfig &config) : SyncActionNode(name, config) {}
// It is mandatory to define this STATIC method.
static PortsList providedPorts() {
return {InputPort<geometry_msgs::msg::PoseStamped>("input", "{any_val}", "this is a BT::Any object on the blackboard")};
}
// Override the virtual function tick()
NodeStatus tick() override {
Expected<geometry_msgs::msg::PoseStamped> msg = getInput<geometry_msgs::msg::PoseStamped>("input");
// Check if expected is valid. If not, throw its error
if (!msg) {
throw BT::RuntimeError("missing required input [message]: ", msg.error());
}
// auto any_msg = config().blackboard->getAnyLocked(msg.value());
// auto pose_msg = any_msg->cast<geometry_msgs::msg::PoseStamped>();
// use the method value() to extract the valid message.
// std::cout << "Pose name on blackboard is: " << msg.value() << std::endl;
std::cout << "pose.position.x: " << msg.value().pose.position.x << std::endl;
return NodeStatus::SUCCESS;
}
};
int main() {
BehaviorTreeFactory factory;
BT::NodeConfiguration config_;
config_.blackboard = BT::Blackboard::create();
factory.registerNodeType<CreateAnyPoseStampedVector>("CreateAnyPoseStampedVector");
factory.registerNodeType<ForEachAny>("ForEachAny");
factory.registerNodeType<AnyToPoseStamped>("AnyToPoseStamped");
auto tree = factory.createTreeFromFile("./my_tree.xml", config_.blackboard);
tree.tickWhileRunning();
return 0;
}