Go to the documentation of this file. 1 #include <gtest/gtest.h>
14 std::cout <<
"ctor" << std::endl;
21 if(!getInput(
"in_port_A", val_A))
25 if(!getInput(
"in_port_B", val_B))
30 if(val_A == 42 && val_B == 66)
39 return { BT::InputPort<int>(
"in_port_A", 42,
"magic_number"),
40 BT::InputPort<int>(
"in_port_B") };
44 TEST(PortTest, WrongNodeConfig)
51 ASSERT_ANY_THROW(node.
tick());
54 TEST(PortTest, DefaultPorts)
56 std::string xml_txt = R
"(
57 <root BTCPP_format="4" >
58 <BehaviorTree ID="MainTree">
59 <NodeWithPorts in_port_B="66" />
70 TEST(PortTest, MissingPort)
72 std::string xml_txt = R
"(
73 <root BTCPP_format="4" >
74 <BehaviorTree ID="MainTree">
82 ASSERT_ANY_THROW(tree.tickWhileRunning());
87 std::string xml_txt = R
"(
88 <root BTCPP_format="4" >
89 <BehaviorTree ID="MainTree">
90 <NodeWithPorts da_port="66" />
102 std::string xml_txt = R
"(
103 <root BTCPP_format="4" >
104 <BehaviorTree ID="MainTree" _description="this is my tree" >
106 <NodeWithPorts name="first" in_port_B="66" _description="this is my action" />
107 <SubTree ID="mySubTree" name="second" _description="this is a subtree"/>
111 <BehaviorTree ID="mySubTree" _description="this is a subtree" >
112 <NodeWithPorts name="third" in_port_B="99" />
126 status = tree.tickWhileRunning();
148 if(getInput(
"int_port", val_A) && getInput(
"any_port", val_B))
157 return { BT::InputPort<int>(
"int_port"), BT::InputPort<MyType>(
"any_port") };
175 return { BT::OutputPort<int>(
"int_port"), BT::OutputPort<MyType>(
"any_port") };
181 std::string xml_txt = R
"(
182 <root BTCPP_format="4" >
183 <BehaviorTree ID="MainTree">
185 <NodeInPorts int_port="{ip}" any_port="{ap}" />
186 <NodeOutPorts int_port="{ip}" any_port="{ap}" />
216 return { BT::InputPort<std::string>(
"name") };
230 std::vector<double>* states)
236 getInput(
"states", *states_);
242 return { BT::InputPort<std::vector<double>>(
"states") };
249 TEST(PortTest, SubtreeStringInput_Issue489)
251 std::string xml_txt = R
"(
252 <root BTCPP_format="4" >
253 <BehaviorTree ID="Main">
254 <SubTree ID="Subtree_A" states="3;7"/>
257 <BehaviorTree ID="Subtree_A">
258 <ActionVectorDoubleIn states="{states}"/>
262 std::vector<double> states;
273 ASSERT_EQ(2, states.size());
274 ASSERT_EQ(3, states[0]);
275 ASSERT_EQ(7, states[1]);
282 std::vector<std::string>* states)
288 getInput(
"states", *states_);
294 return { BT::InputPort<std::vector<std::string>>(
"states") };
301 TEST(PortTest, SubtreeStringInput_StringVector)
303 std::string xml_txt = R
"(
304 <root BTCPP_format="4" >
305 <BehaviorTree ID="Main">
306 <ActionVectorStringIn states="hello;world;with spaces"/>
310 std::vector<std::string> states;
321 ASSERT_EQ(3, states.size());
322 ASSERT_EQ(
"hello", states[0]);
323 ASSERT_EQ(
"world", states[1]);
324 ASSERT_EQ(
"with spaces", states[2]);
333 return x == other.
x && y == other.
y;
337 return !(*
this == other);
346 str.remove_prefix(5);
347 return convertFromJSON<Point2D>(str);
350 if(parts.size() != 2)
354 int x = convertFromString<int>(parts[0]);
355 int y = convertFromString<int>(parts[1]);
360 [[nodiscard]] std::string BT::toStr<Point2D>(
const Point2D& point)
367 add_field(
"x", &point.x);
368 add_field(
"y", &point.y);
380 const int answer = getInput<int>(
"answer").value();
386 const std::string greet = getInput<std::string>(
"greeting").value();
392 const Point2D point = getInput<Point2D>(
"pos").value();
393 if(point.
x != 1 || point.
y != 2)
403 return { BT::InputPort<int>(
"answer", 42,
"the answer"),
404 BT::InputPort<std::string>(
"greeting",
"hello",
"be polite"),
405 BT::InputPort<Point2D>(
"pos",
Point2D{ 1, 2 },
"where") };
411 std::string xml_txt = R
"(
412 <root BTCPP_format="4" >
421 auto status = tree.tickOnce();
434 auto res_str = getInput<std::string>(
"val_str");
436 auto res_int = getInput<BT::Any>(
"val_int");
439 auto res_real_A = getInput<double>(
"val_real");
441 auto res_real_B = getInput<BT::Any>(
"val_real");
443 bool expected = res_str.value() ==
"hello" && res_int->cast<
int>() == 42 &&
444 res_real_A.value() == 3.14 && res_real_B->cast<
double>() == 3.14;
451 return { BT::InputPort<BT::Any>(
"val_str"), BT::InputPort<BT::Any>(
"val_int"),
452 BT::InputPort<double>(
"val_real") };
465 setOutput(
"val_str",
BT::Any(1.0));
466 setOutput(
"val_str",
BT::Any(1));
467 setOutput(
"val_str",
BT::Any(
"hello"));
469 setOutput(
"val_int", 42);
470 setOutput(
"val_real", 3.14);
476 return { BT::OutputPort<BT::Any>(
"val_str"), BT::OutputPort<int>(
"val_int"),
477 BT::OutputPort<BT::Any>(
"val_real") };
483 std::string xml_txt = R
"(
484 <root BTCPP_format="4" >
487 <SetAny val_str="{val_str}" val_int="{val_int}" val_real="{val_real}"/>
488 <GetAny val_str="{val_str}" val_int="{val_int}" val_real="{val_real}"/>
497 auto status = tree.tickOnce();
510 Point2D pointA, pointB, pointC, pointD, pointE, input;
512 if(!getInput(
"pointA", pointA) || pointA !=
Point2D{ 1, 2 })
514 throw std::runtime_error(
"failed pointA");
516 if(!getInput(
"pointB", pointB) || pointB !=
Point2D{ 3, 4 })
518 throw std::runtime_error(
"failed pointB");
520 if(!getInput(
"pointC", pointC) || pointC !=
Point2D{ 5, 6 })
522 throw std::runtime_error(
"failed pointC");
524 if(!getInput(
"pointD", pointD) || pointD !=
Point2D{ 7, 8 })
526 throw std::runtime_error(
"failed pointD");
528 if(!getInput(
"pointE", pointE) || pointE !=
Point2D{ 9, 10 })
530 throw std::runtime_error(
"failed pointE");
532 if(!getInput(
"input", input) || input !=
Point2D{ -1, -2 })
534 throw std::runtime_error(
"failed input");
541 return { BT::InputPort<Point2D>(
"input",
"no default value"),
542 BT::InputPort<Point2D>(
"pointA",
Point2D{ 1, 2 },
"default value is [1,2]"),
543 BT::InputPort<Point2D>(
"pointB",
"{point}",
544 "default value inside blackboard {point}"),
545 BT::InputPort<Point2D>(
"pointC",
"5,6",
"default value is [5,6]"),
546 BT::InputPort<Point2D>(
"pointD",
"{=}",
547 "default value inside blackboard {pointD}"),
548 BT::InputPort<Point2D>(
"pointE", R
"(json:{"x":9,"y":10})",
549 "default value is [9,10]") };
553 TEST(PortTest, DefaultInputPoint2D)
555 std::string xml_txt = R
"(
556 <root BTCPP_format="4" >
558 <NodeWithDefaultPoints input="-1,-2"/>
566 auto tree = factory.createTreeFromText(xml_txt);
568 tree.subtrees.front()->blackboard->set<
Point2D>(
"point",
Point2D{ 3, 4 });
569 tree.subtrees.front()->blackboard->set<
Point2D>(
"pointD",
Point2D{ 7, 8 });
572 ASSERT_NO_THROW(status = tree.tickOnce());
587 std::string input, msgA, msgB, msgC;
588 if(!getInput(
"input", input) || input !=
"from XML")
590 throw std::runtime_error(
"failed input");
592 if(!getInput(
"msgA", msgA) || msgA !=
"hello")
594 throw std::runtime_error(
"failed msgA");
596 if(!getInput(
"msgB", msgB) || msgB !=
"ciao")
598 throw std::runtime_error(
"failed msgB");
600 if(!getInput(
"msgC", msgC) || msgC !=
"hola")
602 throw std::runtime_error(
"failed msgC");
609 return { BT::InputPort<std::string>(
"input",
"no default"),
610 BT::InputPort<std::string>(
"msgA",
"hello",
"default value is 'hello'"),
611 BT::InputPort<std::string>(
"msgB",
"{msg}",
612 "default value inside blackboard {msg}"),
613 BT::InputPort<std::string>(
"msgC",
"{=}",
614 "default value inside blackboard {msgC}") };
618 TEST(PortTest, DefaultInputStrings)
620 std::string xml_txt = R
"(
621 <root BTCPP_format="4" >
623 <NodeWithDefaultStrings input="from XML"/>
631 tree.subtrees.front()->blackboard->set<std::string>(
"msg",
"ciao");
632 tree.subtrees.front()->blackboard->set<std::string>(
"msgC",
"hola");
635 ASSERT_NO_THROW(status = tree.tickOnce());
662 return { BT::InputPort<std::shared_ptr<TestStruct>>(
"input",
nullptr,
663 "default value is nullptr") };
667 TEST(PortTest, Default_Issues_767)
677 auto p =
InputPort<std::shared_ptr<Point2D>>(
"ptr_A",
nullptr,
"default nullptr"));
678 ASSERT_NO_THROW(
auto p =
InputPort<std::shared_ptr<std::string>>(
"ptr_B",
nullptr,
682 TEST(PortTest, DefaultWronglyOverriden)
687 std::string xml_txt_wrong = R
"(
688 <root BTCPP_format="4" >
690 <NodeWithDefaultNullptr input=""/>
694 std::string xml_txt_correct = R"(
695 <root BTCPP_format="4" >
697 <NodeWithDefaultNullptr/>
static PortsList providedPorts()
NodeStatus tick() override
Method to be implemented by the user.
static PortsList providedPorts()
NodeStatus tick() override
Method to be implemented by the user.
NodeStatus tick() override
Method to be implemented by the user.
NodeStatus tick() override
Method to be implemented by the user.
Tree createTree(const std::string &tree_name, Blackboard::Ptr blackboard=Blackboard::create())
NodeOutPorts(const std::string &name, const NodeConfig &config)
NodeStatus tick() override
Method to be implemented by the user.
std::string_view StringView
std::pair< std::string, PortInfo > InputPort(StringView name, StringView description={})
NodeStatus tick() override
Method to be implemented by the user.
PortsRemapping input_ports
TEST(PortTest, WrongNodeConfig)
GetAny(const std::string &name, const NodeConfig &config)
std::vector< double > * states_
static PortsList providedPorts()
static PortsList providedPorts()
NodeWithDefaultPoints(const std::string &name, const NodeConfig &config)
NodeStatus tick() override
Method to be implemented by the user.
std::vector< std::string > * states_
NodeStatus tickWhileRunning(std::chrono::milliseconds sleep_time=std::chrono::milliseconds(10))
NodeStatus tick() override
Method to be implemented by the user.
std::unordered_map< std::string, PortInfo > PortsList
static PortsList providedPorts()
SetAny(const std::string &name, const NodeConfig &config)
NodeStatus tick() override
Method to be implemented by the user.
static PortsList providedPorts()
NodeWithDefaultNullptr(const std::string &name, const NodeConfig &config)
void registerNodeType(const std::string &ID, const PortsList &ports, ExtraArgs... args)
Tree createTreeFromText(const std::string &text, Blackboard::Ptr blackboard=Blackboard::create())
createTreeFromText will parse the XML directly from string. The XML needs to contain either a single ...
ActionVectorStringIn(const std::string &name, const NodeConfig &config, std::vector< std::string > *states)
static PortsList providedPorts()
static PortsList providedPorts()
NodeInPorts(const std::string &name, const NodeConfig &config)
NodeWithDefaultStrings(const std::string &name, const NodeConfig &config)
std::vector< StringView > splitString(const StringView &strToSplit, char delimeter)
static JsonExporter & get()
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
The BehaviorTreeFactory is used to create instances of a TreeNode at run-time.
NodeStatus tick() override
Method to be implemented by the user.
NodeStatus tick() override
Method to be implemented by the user.
NodeWithPorts(const std::string &name, const NodeConfig &config)
static PortsList providedPorts()
bool StartWith(StringView str, StringView prefix)
IllegalPorts(const std::string &name, const NodeConfig &config)
void registerBehaviorTreeFromText(const std::string &xml_text)
static PortsList providedPorts()
BT_JSON_CONVERTER(Point2D, point)
static PortsList providedPorts()
NodeStatus tick() override
Method to be implemented by the user.
ActionVectorDoubleIn(const std::string &name, const NodeConfig &config, std::vector< double > *states)
bool operator==(const Point2D &other) const
bool operator!=(const Point2D &other) const
DefaultTestAction(const std::string &name, const NodeConfig &config)
static PortsList providedPorts()
The SyncActionNode is an ActionNode that explicitly prevents the status RUNNING and doesn't require a...
std::string writeTreeNodesModelXML(const BehaviorTreeFactory &factory, bool include_builtin=false)
writeTreeNodesModelXML generates an XMl that contains the manifests in the <TreeNodesModel>
constexpr auto p
Parses the production.