FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Fix logical NOT for string-backed boolean values by fallenmi · Pull Request #1191 · BehaviorTree/BehaviorTree.CPP · GitHub

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .cpp  (1) .hpp  (1) All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
12 changes: 12 additions & 0 deletions include/behaviortree_cpp/scripting/operators.hpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,18 @@ struct ExprUnaryArithmetic : ExprBase
}
else if(rhs_v.isString())
{
if(op == logical_not)
{
const auto str = rhs_v.cast<std::string>();
if(str == "true" || str == "True" || str == "TRUE" || str == "1")
{
return Any(0.0);
}
if(str == "false" || str == "False" || str == "FALSE" || str == "0")
{
return Any(1.0);
}
}
throw RuntimeError("Invalid operator for std::string");
}
throw RuntimeError("ExprUnaryArithmetic: undefined");
Expand Down
78 changes: 78 additions & 0 deletions tests/gtest_subtree.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1012,3 +1012,81 @@ TEST(SubTree, LiteralNumericPortsPreserveType)
const auto status = tree.tickWhileRunning();
ASSERT_EQ(status, NodeStatus::SUCCESS);
}

// Regression test: logical NOT should accept literal boolean values passed to
// subtrees without changing their string representation in the blackboard.
TEST(SubTree, LiteralBooleanPortsSupportLogicalNot)
{
// clang-format off
static const char* xml_text = R"(
<root BTCPP_format="4" main_tree_to_execute="MainTree">

<BehaviorTree ID="MainTree">
<SubTree ID="CheckBooleans" enabled="true" disabled="false"
enabled_upper="TRUE" disabled_title="False"
enabled_numeric="{enabled_numeric}"
disabled_numeric="{disabled_numeric}" />
</BehaviorTree>

<BehaviorTree ID="CheckBooleans">
<Sequence>
<AlwaysSuccess _skipIf="!enabled" />
<ScriptCondition code="!disabled" />
<ScriptCondition code="!!enabled_upper" />
<ScriptCondition code="!disabled_title" />
<ScriptCondition code="!!enabled_numeric" />
<ScriptCondition code="!disabled_numeric" />
</Sequence>
</BehaviorTree>

<TreeNodesModel>
<SubTree ID="CheckBooleans">
<input_port name="enabled" type="bool" />
<input_port name="disabled" type="bool" />
<input_port name="enabled_upper" type="bool" />
<input_port name="disabled_title" type="bool" />
<input_port name="enabled_numeric" type="bool" />
<input_port name="disabled_numeric" type="bool" />
</SubTree>
</TreeNodesModel>

</root>
)";
// clang-format on

BehaviorTreeFactory factory;
auto tree = factory.createTreeFromText(xml_text);
tree.rootBlackboard()->set("enabled_numeric", std::string("1"));
tree.rootBlackboard()->set("disabled_numeric", std::string("0"));

ASSERT_EQ(tree.tickWhileRunning(), NodeStatus::SUCCESS);
ASSERT_EQ(tree.subtrees[1]->blackboard->get<std::string>("enabled"), "true");
ASSERT_EQ(tree.subtrees[1]->blackboard->get<std::string>("disabled"), "false");
ASSERT_EQ(tree.subtrees[1]->blackboard->get<std::string>("enabled_upper"), "TRUE");
ASSERT_EQ(tree.subtrees[1]->blackboard->get<std::string>("disabled_title"), "False");
}

TEST(SubTree, LiteralNonBooleanPortsRejectLogicalNot)
{
// clang-format off
static const char* xml_text = R"(
<root BTCPP_format="4" main_tree_to_execute="MainTree">

<BehaviorTree ID="MainTree">
<SubTree ID="CheckValue" value="1not_bool" />
</BehaviorTree>

<BehaviorTree ID="CheckValue">
<ScriptCondition code="!value" />
</BehaviorTree>

</root>
)";
// clang-format on

BehaviorTreeFactory factory;
auto tree = factory.createTreeFromText(xml_text);

ASSERT_THROW((void)tree.tickWhileRunning(), RuntimeError);
ASSERT_EQ(tree.subtrees[1]->blackboard->get<std::string>("value"), "1not_bool");
}
Loading

Back | FazBrowse Home | New Git URL