Go to the documentation of this file.00001 #ifndef BT_FLATBUFFER_HELPER_H
00002 #define BT_FLATBUFFER_HELPER_H
00003
00004 #include "behaviortree_cpp/bt_factory.h"
00005 #include "BT_logger_generated.h"
00006
00007 namespace BT
00008 {
00009
00010 typedef std::array<uint8_t, 12> SerializedTransition;
00011
00012 inline Serialization::NodeType convertToFlatbuffers(BT::NodeType type)
00013 {
00014 switch (type)
00015 {
00016 case BT::NodeType::ACTION:
00017 return Serialization::NodeType::ACTION;
00018 case BT::NodeType::DECORATOR:
00019 return Serialization::NodeType::DECORATOR;
00020 case BT::NodeType::CONTROL:
00021 return Serialization::NodeType::CONTROL;
00022 case BT::NodeType::CONDITION:
00023 return Serialization::NodeType::CONDITION;
00024 case BT::NodeType::SUBTREE:
00025 return Serialization::NodeType::SUBTREE;
00026 case BT::NodeType::UNDEFINED:
00027 return Serialization::NodeType::UNDEFINED;
00028 }
00029 return Serialization::NodeType::UNDEFINED;
00030 }
00031
00032 inline Serialization::NodeStatus convertToFlatbuffers(BT::NodeStatus type)
00033 {
00034 switch (type)
00035 {
00036 case BT::NodeStatus::IDLE:
00037 return Serialization::NodeStatus::IDLE;
00038 case BT::NodeStatus::SUCCESS:
00039 return Serialization::NodeStatus::SUCCESS;
00040 case BT::NodeStatus::RUNNING:
00041 return Serialization::NodeStatus::RUNNING;
00042 case BT::NodeStatus::FAILURE:
00043 return Serialization::NodeStatus::FAILURE;
00044 }
00045 return Serialization::NodeStatus::IDLE;
00046 }
00047
00048 inline Serialization::PortDirection convertToFlatbuffers(BT::PortDirection direction)
00049 {
00050 switch (direction)
00051 {
00052 case BT::PortDirection::INPUT :
00053 return Serialization::PortDirection::INPUT;
00054 case BT::PortDirection::OUTPUT:
00055 return Serialization::PortDirection::OUTPUT;
00056 case BT::PortDirection::INOUT:
00057 return Serialization::PortDirection::INOUT;
00058 }
00059 return Serialization::PortDirection::INOUT;
00060 }
00061
00062 inline void CreateFlatbuffersBehaviorTree(flatbuffers::FlatBufferBuilder& builder,
00063 const BT::Tree& tree)
00064 {
00065 std::vector<flatbuffers::Offset<Serialization::TreeNode>> fb_nodes;
00066
00067 applyRecursiveVisitor(tree.root_node, [&](BT::TreeNode* node)
00068 {
00069 std::vector<uint16_t> children_uid;
00070 if (auto control = dynamic_cast<BT::ControlNode*>(node))
00071 {
00072 children_uid.reserve(control->children().size());
00073 for (const auto& child : control->children())
00074 {
00075 children_uid.push_back(child->UID());
00076 }
00077 }
00078 else if (auto decorator = dynamic_cast<BT::DecoratorNode*>(node))
00079 {
00080 const auto& child = decorator->child();
00081 children_uid.push_back(child->UID());
00082 }
00083
00084 std::vector<flatbuffers::Offset<Serialization::PortConfig>> ports;
00085 for (const auto& it : node->config().input_ports)
00086 {
00087 ports.push_back(Serialization::CreatePortConfigDirect(
00088 builder, it.first.c_str(), it.second.c_str()));
00089 }
00090 for (const auto& it : node->config().output_ports)
00091 {
00092 ports.push_back(Serialization::CreatePortConfigDirect(
00093 builder, it.first.c_str(), it.second.c_str()));
00094 }
00095
00096 auto tn = Serialization::CreateTreeNode(
00097 builder,
00098 node->UID(),
00099 builder.CreateVector(children_uid),
00100 convertToFlatbuffers(node->status()),
00101 builder.CreateString(node->name().c_str()),
00102 builder.CreateString(node->registrationName().c_str()),
00103 builder.CreateVector(ports));
00104
00105 fb_nodes.push_back(tn);
00106 });
00107
00108 std::vector<flatbuffers::Offset<Serialization::NodeModel>> node_models;
00109
00110 for (const auto& node_it: tree.manifests)
00111 {
00112 const auto& manifest = node_it.second;
00113 std::vector<flatbuffers::Offset<Serialization::PortModel>> port_models;
00114
00115 for (const auto& port_it: manifest.ports)
00116 {
00117 const auto& port_name = port_it.first;
00118 const auto& port = port_it.second;
00119 auto port_model = Serialization::CreatePortModel(
00120 builder,
00121 builder.CreateString( port_name.c_str() ),
00122 convertToFlatbuffers( port.direction() ),
00123 builder.CreateString( demangle(port.type()).c_str() ),
00124 builder.CreateString( port.description().c_str() )
00125 );
00126 port_models.push_back(port_model);
00127 }
00128
00129 auto node_model = Serialization::CreateNodeModel(
00130 builder,
00131 builder.CreateString(manifest.registration_ID.c_str()),
00132 convertToFlatbuffers(manifest.type),
00133 builder.CreateVector(port_models) );
00134
00135 node_models.push_back(node_model);
00136 }
00137
00138 auto behavior_tree = Serialization::CreateBehaviorTree(builder, tree.root_node->UID(),
00139 builder.CreateVector(fb_nodes),
00140 builder.CreateVector(node_models));
00141
00142 builder.Finish(behavior_tree);
00143 }
00144
00148 inline SerializedTransition SerializeTransition(uint16_t UID,
00149 Duration timestamp,
00150 NodeStatus prev_status,
00151 NodeStatus status)
00152 {
00153 using namespace std::chrono;
00154 SerializedTransition buffer;
00155 int64_t usec = duration_cast<microseconds>(timestamp).count();
00156 int64_t t_sec = usec / 1000000;
00157 int64_t t_usec = usec % 1000000;
00158
00159 flatbuffers::WriteScalar(&buffer[0], t_sec);
00160 flatbuffers::WriteScalar(&buffer[4], t_usec);
00161 flatbuffers::WriteScalar(&buffer[8], UID);
00162
00163 flatbuffers::WriteScalar(&buffer[10], static_cast<int8_t>(convertToFlatbuffers(prev_status)));
00164 flatbuffers::WriteScalar(&buffer[11], static_cast<int8_t>(convertToFlatbuffers(status)));
00165
00166 return buffer;
00167 }
00168
00169 }
00170
00171 #endif // BT_FLATBUFFER_HELPER_H