HOW-TO: How to use custom convertFromString in Node loaded as Plugin
LUGGGI opened this issue · 3 comments
Hello,
I have a Node that uses a custom type. I've created the template specialization for convertFromString for that type.
When I use the Node directly, meaning registering it in the same file with factory.registerNodeType, everything works and the type gets converted.
But when I use the Node as a plugin I get the error that the specialization is not found:
You didn't implement the template specialization of convertFromString for this type: geometry_msgs::msg::Point_<std::allocator<void> >
I tried adding the template specialization to the file where I load the plugins, but that didn't work (I already thought it wouldn't work, but didn't have any other ideas.
Does anyone know how to do this? I would really appreciate it.
I think that I know how to solve this and why it may happen. Can you create an example?
Hey! I have the same issue.
I have a plugin that uses a std::vector<bool> port:
using BT::NodeStatus;
using BT::SyncActionNode;
namespace BT {
template <>
[[nodiscard]] auto convertFromString<std::vector<bool>>(StringView str) -> std::vector<bool> {
// We expect bools separated by semicolons
auto parts = splitString(str, ';');
std::vector<bool> output;
for (auto part : parts) {
output.push_back(convertFromString<bool>(part));
}
return output;
}
} // namespace BT
template <typename T>
class MyNode : public SyncActionNode {
public:
MyNode(const std::string& name, const BT::NodeConfig& config) : SyncActionNode(name, config) {}
static auto providedPorts() -> BT::PortsList {
return {
BT::InputPort<T>("input"),
};
}
auto tick() -> NodeStatus override {
const auto input = getInput<T>("input").value();
}
};
BT_REGISTER_NODES(factory) {
factory.registerNodeType<MyNode<bool>>("MyNodeBool");
factory.registerNodeType<MyNode<std::vector<bool>>>("MyNodeBoolArray");
}I tried
- putting also my class declaration/definition into the
BTnamespace or - moving the
convertFromStringspecialization into a header file and including it both in the plugin and my tree-execution executable
yet still it always complains with
You (maybe indirectly) called BT::convertFromString() for type [std::vector<bool, std::allocator<bool> >], but I can't find the template specialization.
Behavior Tree exception:The port with name "input" and value "true;false" can not be converted to std::vector<bool, std::allocator<bool> >
My tree XML is as simple as
<root BTCPP_format="4">
<BehaviorTree ID="TestMyNodeBoolArray">
<MyNodeBoolArray input="true;false" />
</BehaviorTree>
</root>Any ideas how to solve or what else to try?
I've encountered this issue when I was trying to convert an input port string into a vector of "Vector3". Anyways, the issue (I eventually found out) was that this was because I had another convertFromString() template specialization that calls the Vector3 convertFromString() function. Apparently, I needed to include the Vector3 convertFromString() function in that one. It's especially tricky since this doesn't give any compile time errors.
Not 100% sure if this is related, but I have a working implementation here using BehaviorTree.ROS2 (if that helps anyone else).