File tree Expand file tree Collapse file tree 2 files changed +76
-2
lines changed
Expand file tree Collapse file tree 2 files changed +76
-2
lines changed Original file line number Diff line number Diff line change @@ -1147,10 +1147,46 @@ void BT::XMLParser::PImpl::recursivelyCreateSubtree(
11471147 }
11481148 else
11491149 {
1150- // constant string: just set that constant value into the BB
1150+ // constant value: set it into the BB with appropriate type
11511151 // IMPORTANT: this must not be autoremapped!!!
11521152 new_bb->enableAutoRemapping (false );
1153- new_bb->set (attr_name, static_cast <std::string>(attr_value));
1153+ // Try to preserve numeric types so that Script expressions
1154+ // can perform arithmetic without type-mismatch errors.
1155+ const std::string str_value (attr_value);
1156+ bool stored = false ;
1157+ if (!str_value.empty ())
1158+ {
1159+ // Try integer first (no decimal point, no exponent notation)
1160+ if (str_value.find (' .' ) == std::string::npos &&
1161+ str_value.find (' e' ) == std::string::npos &&
1162+ str_value.find (' E' ) == std::string::npos)
1163+ {
1164+ try
1165+ {
1166+ const int64_t int_val = convertFromString<int64_t >(str_value);
1167+ new_bb->set (attr_name, int_val);
1168+ stored = true ;
1169+ }
1170+ catch (...)
1171+ {}
1172+ }
1173+ // Try double
1174+ if (!stored)
1175+ {
1176+ try
1177+ {
1178+ const double dbl_val = convertFromString<double >(str_value);
1179+ new_bb->set (attr_name, dbl_val);
1180+ stored = true ;
1181+ }
1182+ catch (...)
1183+ {}
1184+ }
1185+ }
1186+ if (!stored)
1187+ {
1188+ new_bb->set (attr_name, str_value);
1189+ }
11541190 new_bb->enableAutoRemapping (do_autoremap);
11551191 }
11561192 }
Original file line number Diff line number Diff line change @@ -974,3 +974,41 @@ TEST(SubTree, NestedDuplicateNames_ShouldFail)
974974 // Should throw RuntimeError because of duplicate SubTree names
975975 ASSERT_THROW ((void )factory.createTreeFromText (xml_text), RuntimeError);
976976}
977+
978+ // Regression test: literal numeric values passed to subtrees should preserve
979+ // their numeric type so that Script expressions can do arithmetic.
980+ TEST (SubTree, LiteralNumericPortsPreserveType)
981+ {
982+ // clang-format off
983+ static const char * xml_text = R"(
984+ <root BTCPP_format="4" main_tree_to_execute="MainTree">
985+
986+ <BehaviorTree ID="MainTree">
987+ <Sequence>
988+ <SubTree ID="DoMath" int_val="42" dbl_val="3.14" str_val="hello"
989+ remapped_val="{from_parent}" />
990+ </Sequence>
991+ </BehaviorTree>
992+
993+ <BehaviorTree ID="DoMath">
994+ <Sequence>
995+ <ScriptCondition code=" int_val + 1 == 43 " />
996+ <ScriptCondition code=" dbl_val > 3.0 " />
997+ <ScriptCondition code=" remapped_val + 1 == 101 " />
998+ </Sequence>
999+ </BehaviorTree>
1000+
1001+ </root>
1002+ )" ;
1003+ // clang-format on
1004+
1005+ BehaviorTreeFactory factory;
1006+
1007+ auto tree = factory.createTreeFromText (xml_text);
1008+
1009+ // Set the remapped parent value as an integer
1010+ tree.rootBlackboard ()->set (" from_parent" , 100 );
1011+
1012+ const auto status = tree.tickWhileRunning ();
1013+ ASSERT_EQ (status, NodeStatus::SUCCESS);
1014+ }
You can’t perform that action at this time.
0 commit comments