AutoAPMS
Resilient Robot Mission Management
Loading...
Searching...
No Matches
tree_document.hpp
1// Copyright 2024 Robin Müller
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#include <tinyxml2.h>
18
19#include <functional>
20#include <string>
21#include <type_traits>
22#include <vector>
23
24#include "auto_apms_behavior_tree_core/node/node_manifest.hpp"
25#include "auto_apms_behavior_tree_core/node/node_registration_loader.hpp"
26#include "auto_apms_behavior_tree_core/node/node_registration_options.hpp"
27#include "auto_apms_behavior_tree_core/tree/script.hpp"
28#include "behaviortree_cpp/bt_factory.h"
29#include "behaviortree_cpp/tree_node.h"
30#include "rclcpp/rclcpp.hpp"
31
33{
34class SubTree;
35}
36
38{
39
40class TreeResource;
41class NodeModelType;
42
137class TreeDocument : private tinyxml2::XMLDocument
138{
139 using XMLElement = tinyxml2::XMLElement;
140
141 inline static const std::string LOGGER_NAME = "tree_document";
142
143public:
144 static inline const char BTCPP_FORMAT_ATTRIBUTE_NAME[] = "BTCPP_format";
145 static inline const char BTCPP_FORMAT_DEFAULT_VERSION[] = "4";
146 static inline const char ROOT_ELEMENT_NAME[] = "root";
147 static inline const char ROOT_TREE_ATTRIBUTE_NAME[] = "main_tree_to_execute";
148 static inline const char TREE_ELEMENT_NAME[] = "BehaviorTree";
149 static inline const char SUBTREE_ELEMENT_NAME[] = "SubTree";
150 static inline const char TREE_NAME_ATTRIBUTE_NAME[] = "ID";
151 static inline const char TREE_NODE_MODEL_ELEMENT_NAME[] = "TreeNodesModel";
152 static inline const char NODE_INSTANCE_NAME_ATTRIBUTE_NAME[] = "name";
153
158 {
160 std::string port_name;
162 std::string port_type;
164 std::string port_default;
168 std::string port_description;
170 BT::PortDirection port_direction;
171 };
172
177 {
179 BT::NodeType type;
181 std::vector<NodePortInfo> port_infos;
182 };
183
185 using NodeModelMap = std::map<std::string, NodeModel>;
186
187 class TreeElement;
188
202 {
203 public:
205 using PortValues = std::map<std::string, std::string>;
207 using DeepApplyCallback = std::function<bool(NodeElement &)>;
209 using ConstDeepApplyCallback = std::function<bool(const NodeElement &)>;
210
211 protected:
217 explicit NodeElement(TreeDocument * doc_ptr, XMLElement * ele_ptr);
218
219 public:
224 NodeElement(const NodeElement & ele) = default;
225
237 NodeElement & operator=(const NodeElement & other);
238
247 bool operator==(const NodeElement & other) const;
248
249 bool operator!=(const NodeElement & other) const;
250
265 NodeElement insertNode(const std::string & name, const NodeElement * before_this = nullptr);
266
281 const std::string & name, const NodeRegistrationOptions & registration_options,
282 const NodeElement * before_this = nullptr);
283
297 template <class T>
298 typename std::enable_if_t<std::is_base_of_v<NodeModelType, T> && !std::is_same_v<model::SubTree, T>, T> insertNode(
299 const NodeElement * before_this = nullptr);
300
316 template <class SubTreeT>
317 typename std::enable_if_t<std::is_same_v<model::SubTree, SubTreeT>, model::SubTree> insertNode(
318 const std::string & tree_name, const NodeElement * before_this = nullptr);
319
338 template <class SubTreeT>
339 typename std::enable_if_t<std::is_same_v<model::SubTree, SubTreeT>, model::SubTree> insertNode(
340 const TreeElement & tree, const NodeElement * before_this = nullptr);
341
354 model::SubTree insertSubTreeNode(const std::string & tree_name, const NodeElement * before_this = nullptr);
355
371 model::SubTree insertSubTreeNode(const TreeElement & tree, const NodeElement * before_this = nullptr);
372
388 NodeElement insertTree(const TreeElement & tree, const NodeElement * before_this = nullptr);
389
408 const TreeDocument & doc, const std::string & tree_name, const NodeElement * before_this = nullptr);
409
428 NodeElement insertTreeFromDocument(const TreeDocument & doc, const NodeElement * before_this = nullptr);
429
450 const std::string & tree_str, const std::string & tree_name, const NodeElement * before_this = nullptr);
451
471 NodeElement insertTreeFromString(const std::string & tree_str, const NodeElement * before_this = nullptr);
472
493 const std::string & path, const std::string & tree_name, const NodeElement * before_this = nullptr);
494
514 NodeElement insertTreeFromFile(const std::string & path, const NodeElement * before_this = nullptr);
515
543 const TreeResource & resource, const std::string & tree_name, const NodeElement * before_this = nullptr);
544
571 NodeElement insertTreeFromResource(const TreeResource & resource, const NodeElement * before_this = nullptr);
572
577 bool hasChildren() const;
578
579 // clang-format off
597 NodeElement getFirstNode(const std::string & registration_name = "", const std::string & instance_name = "") const;
598
617 template <class T>
618 typename std::enable_if_t<std::is_base_of_v<NodeModelType, T>, T> getFirstNode(
619 const std::string & instance_name = "") const;
620
638 NodeElement & removeFirstChild(const std::string & registration_name = "", const std::string & instance_name = "");
639
658 template <class T>
659 typename std::enable_if_t<std::is_base_of_v<NodeModelType, T>, NodeElement &> removeFirstChild(
660 const std::string & instance_name = "");
661 // clang-format on
662
668
673 const std::vector<std::string> & getPortNames() const;
674
680 PortValues getPorts() const;
681
693 NodeElement & setPorts(const PortValues & port_values);
694
700
711 NodeElement & setConditionalScript(BT::PreCond type, const Script & script);
712
719 NodeElement & setConditionalScript(BT::PostCond type, const Script & script);
720
726 virtual NodeElement & setName(const std::string & instance_name);
727
732 virtual std::string getRegistrationName() const;
733
738 virtual std::string getName() const;
739
744 std::string getFullyQualifiedName() const;
745
754 const TreeDocument & getParentDocument() const;
755
773 const std::vector<NodeElement> deepApplyConst(ConstDeepApplyCallback apply_callback) const;
774
790 std::vector<NodeElement> deepApply(DeepApplyCallback apply_callback);
791
792 private:
793 NodeElement insertBeforeImpl(const NodeElement * before_this, XMLElement * add_this);
794
795 static void deepApplyImpl(
796 const NodeElement & parent, ConstDeepApplyCallback apply_callback, std::vector<NodeElement> & vec);
797
798 static void deepApplyImpl(NodeElement & parent, DeepApplyCallback apply_callback, std::vector<NodeElement> & vec);
799
800 protected:
804 tinyxml2::XMLElement * ele_ptr_;
805
806 private:
807 std::vector<std::string> port_names_;
808 PortValues port_default_values_;
809 };
810
820 {
821 friend class TreeDocument;
822
823 protected:
829 explicit TreeElement(TreeDocument * doc_ptr, XMLElement * ele_ptr);
830
831 public:
836 TreeElement(const TreeElement & ele) = default;
837
847 TreeElement & operator=(const TreeElement & other);
848
854 TreeElement & setName(const std::string & tree_name) override;
855
860 std::string getName() const override;
861
870
882
888 BT::Result verify() const;
889
897 std::string writeToString() const;
898
903 TreeElement & removeFirstChild(const std::string & registration_name = "", const std::string & instance_name = "");
904
909 template <class T>
910 typename std::enable_if_t<std::is_base_of_v<NodeModelType, T>, TreeElement &> removeFirstChild(
911 const std::string & instance_name = "");
912
918
919 /* Not supported methods for TreeElement instances */
920
921 const std::vector<std::string> & getPortNames() = delete;
922 PortValues getPorts() = delete;
923 NodeElement & setPorts() = delete;
924 NodeElement & resetPorts() = delete;
925 NodeElement & setConditionalScript() = delete;
926 };
927
939 const std::string & format_version = BTCPP_FORMAT_DEFAULT_VERSION,
940 NodeRegistrationLoader::SharedPtr tree_node_loader = NodeRegistrationLoader::make_shared());
941
942 TreeDocument(const TreeDocument & other) = delete;
943
944 virtual ~TreeDocument() = default;
945
969 TreeDocument & mergeTreeDocument(const XMLDocument & other, bool adopt_root_tree = false);
970
990 TreeDocument & mergeTreeDocument(const TreeDocument & other, bool adopt_root_tree = false);
991
1015 TreeDocument & mergeString(const std::string & tree_str, bool adopt_root_tree = false);
1016
1041 TreeDocument & mergeFile(const std::string & path, bool adopt_root_tree = false);
1042
1069 TreeDocument & mergeResource(const TreeResource & resource, bool adopt_root_tree = false);
1070
1087 TreeDocument & mergeTree(const TreeElement & tree, bool make_root_tree = false);
1088
1096 TreeElement newTree(const std::string & tree_name);
1097
1111 TreeElement newTree(const TreeElement & other_tree);
1112
1130 TreeElement newTreeFromDocument(const TreeDocument & other, const std::string & tree_name = "");
1131
1149 TreeElement newTreeFromString(const std::string & tree_str, const std::string & tree_name = "");
1150
1168 TreeElement newTreeFromFile(const std::string & path, const std::string & tree_name = "");
1169
1193 TreeElement newTreeFromResource(const TreeResource & resource, const std::string & tree_name = "");
1194
1200 bool hasTreeName(const std::string & tree_name) const;
1201
1209 TreeElement getTree(const std::string & tree_name);
1210
1218 TreeDocument & setRootTreeName(const std::string & tree_name);
1219
1224 bool hasRootTreeName() const;
1225
1232 std::string getRootTreeName() const;
1233
1241
1255 TreeDocument & removeTree(const std::string & tree_name);
1256
1269 TreeDocument & removeTree(const TreeElement & tree);
1270
1275 std::vector<std::string> getAllTreeNames() const;
1276
1287 virtual TreeDocument & registerNodes(const NodeManifest & tree_node_manifest, bool override = false);
1288
1295 std::set<std::string> getRegisteredNodeNames(bool include_native = true) const;
1296
1305
1314 TreeDocument & addNodeModel(bool include_native = false);
1315
1321 static NodeModelMap getNodeModel(tinyxml2::XMLDocument & doc);
1322
1329 NodeModelMap getNodeModel(bool include_native = false) const;
1330
1336 BT::Result verify() const;
1337
1342 std::string writeToString() const;
1343
1348 void writeToFile(const std::string & path) const;
1349
1354 TreeDocument & reset();
1355
1356private:
1357 template <typename ReturnT, typename DocumentT>
1358 static ReturnT getXMLElementForTreeWithNameImpl(DocumentT & doc, const std::string & tree_name);
1359
1360 const XMLElement * getXMLElementForTreeWithName(const std::string & tree_name) const;
1361
1362 XMLElement * getXMLElementForTreeWithName(const std::string & tree_name);
1363
1364 const std::map<std::string, std::string> all_node_classes_package_map_;
1365 const std::set<std::string> native_node_names_;
1366 std::string format_version_;
1367 NodeRegistrationLoader::SharedPtr tree_node_loader_ptr_;
1368 NodeManifest registered_nodes_manifest_;
1369
1370protected:
1371 BT::BehaviorTreeFactory factory_;
1372 rclcpp::Logger logger_;
1373 rclcpp::Node::WeakPtr ros_node_wptr_;
1374 rclcpp::CallbackGroup::WeakPtr tree_node_waitables_callback_group_wptr_;
1375 rclcpp::executors::SingleThreadedExecutor::WeakPtr tree_node_waitables_executor_wptr_;
1376 bool only_non_ros_nodes_ = false;
1377};
1378
1379// #####################################################################################################################
1380// ################################ DEFINITIONS ##############################################
1381// #####################################################################################################################
1382
1384template <typename T, typename = void>
1385struct has_static_method_registrationOptions : std::false_type
1386{
1387};
1388
1389template <typename T>
1390struct has_static_method_registrationOptions<
1391 T, typename std::enable_if_t<std::is_same_v<decltype(T::registrationOptions()), NodeRegistrationOptions>>>
1392: std::true_type
1393{
1394};
1396
1397template <class T>
1398inline typename std::enable_if_t<std::is_base_of_v<NodeModelType, T> && !std::is_same_v<model::SubTree, T>, T>
1400{
1401 // Determine if overload for automatically trying to register the node can be used. Models for native nodes don't
1402 // implement the required static method, thus the other overload must be used.
1403 if constexpr (has_static_method_registrationOptions<T>::value) {
1404 NodeElement ele = insertNode(T::name(), T::registrationOptions(), before_this);
1405 return T(ele.doc_ptr_, ele.ele_ptr_);
1406 } else {
1407 NodeElement ele = insertNode(T::name(), before_this);
1408 return T(ele.doc_ptr_, ele.ele_ptr_);
1409 }
1410}
1411
1412template <class T>
1413inline typename std::enable_if_t<std::is_same_v<model::SubTree, T>, model::SubTree>
1414TreeDocument::NodeElement::insertNode(const std::string & tree_name, const NodeElement * before_this)
1415{
1416 return insertSubTreeNode(tree_name, before_this);
1417}
1418
1419template <class T>
1420inline typename std::enable_if_t<std::is_same_v<model::SubTree, T>, model::SubTree>
1421TreeDocument::NodeElement::insertNode(const TreeElement & tree, const NodeElement * before_this)
1422{
1423 return insertSubTreeNode(tree, before_this);
1424}
1425
1426template <class T>
1427inline typename std::enable_if_t<std::is_base_of_v<NodeModelType, T>, T> core::TreeDocument::NodeElement::getFirstNode(
1428 const std::string & instance_name) const
1429{
1430 const NodeElement ele = getFirstNode(T::name(), instance_name);
1431 return T(ele.doc_ptr_, ele.ele_ptr_);
1432}
1433
1434template <class T>
1435inline typename std::enable_if_t<std::is_base_of_v<NodeModelType, T>, TreeDocument::NodeElement &>
1436core::TreeDocument::NodeElement::removeFirstChild(const std::string & instance_name)
1437{
1438 return removeFirstChild(T::name(), instance_name);
1439}
1440
1441template <class T>
1442inline typename std::enable_if_t<std::is_base_of_v<NodeModelType, T>, TreeDocument::TreeElement &>
1443TreeDocument::TreeElement::removeFirstChild(const std::string & instance_name)
1444{
1445 NodeElement::removeFirstChild<T>(instance_name);
1446 return *this;
1447}
1448
1449} // namespace auto_apms_behavior_tree::core
Data structure for information about which behavior tree node plugin to load and how to configure the...
Abstract base for all automatically generated behavior tree node model classes to be used in interact...
Class that encapsulates behavior tree script expressions.
Definition script.hpp:30
Handle for a single node of a TreeDocument.
const TreeDocument & getParentDocument() const
Get a const view of this node's parent tree document.
NodeElement insertTreeFromResource(const TreeResource &resource, const std::string &tree_name, const NodeElement *before_this=nullptr)
Concatenate a tree from one of the installed package's behavior tree resources and add its first chil...
const std::vector< std::string > & getPortNames() const
Get the names of the data ports implemented by the node represented by this element.
virtual std::string getRegistrationName() const
Get the name of this node given during registration representing its dynamic type.
std::function< bool(const NodeElement &)> ConstDeepApplyCallback
Callback invoked for every node found under another node. It cannot modify the current node.
NodeElement & resetPorts()
Delete all currently specified port values and reset with the defaults.
NodeElement(const NodeElement &ele)=default
Copy constructor for a node element.
std::function< bool(NodeElement &)> DeepApplyCallback
Callback invoked for every node found under another node. It may modify the current node.
NodeElement & removeFirstChild(const std::string &registration_name="", const std::string &instance_name="")
Recursively visit this node's children in execution order and remove the first node with a particular...
NodeElement & setPorts(const PortValues &port_values)
Populate the the node's data ports.
std::enable_if_t< std::is_base_of_v< NodeModelType, T >, T > getFirstNode(const std::string &instance_name="") const
Recursively visit this node's children in execution order and get the first node with a particular in...
std::enable_if_t< std::is_same_v< model::SubTree, SubTreeT >, model::SubTree > insertNode(const TreeElement &tree, const NodeElement *before_this=nullptr)
Add a subtree node for a specific tree element to the children of this node.
virtual NodeElement & setName(const std::string &instance_name)
Assign a name for this specific node instance.
NodeElement getFirstNode(const std::string &registration_name="", const std::string &instance_name="") const
Recursively visit this node's children in execution order and get the first node with a particular re...
NodeElement(TreeDocument *doc_ptr, XMLElement *ele_ptr)
Protected constructor intended for internal use only.
std::map< std::string, std::string > PortValues
Mapping of port names and its respective value encoded as string.
const std::vector< NodeElement > deepApplyConst(ConstDeepApplyCallback apply_callback) const
Recursively apply a callback to this node's children.
TreeDocument * doc_ptr_
Pointer to the tree document that created the tree this node belongs to.
virtual std::string getName() const
Get the name of this node given to this specific instance by the developer.
PortValues getPorts() const
Assemble the values given to each data port implemented by this node.
NodeElement & setConditionalScript(BT::PreCond type, const Script &script)
Specify a script that is evaluated before this node is ticked.
NodeElement insertTreeFromString(const std::string &tree_str, const std::string &tree_name, const NodeElement *before_this=nullptr)
Concatenate a tree from a document created from a string and add its first child node to the children...
tinyxml2::XMLElement * ele_ptr_
Pointer to the corresponding XMLElement of the base document.
NodeElement insertTree(const TreeElement &tree, const NodeElement *before_this=nullptr)
Concatenate a tree and add its first child node to the children of this node.
std::string getFullyQualifiedName() const
Create a string that uniquely identifies this node considering its registration and its instance name...
NodeElement insertTreeFromDocument(const TreeDocument &doc, const std::string &tree_name, const NodeElement *before_this=nullptr)
Concatenate a tree from a document and add its first child node to the children of this node.
model::SubTree insertSubTreeNode(const std::string &tree_name, const NodeElement *before_this=nullptr)
Add a subtree node for a specific tree element to the children of this node.
bool hasChildren() const
Determine whether any children have been given to this node.
std::enable_if_t< std::is_same_v< model::SubTree, SubTreeT >, model::SubTree > insertNode(const std::string &tree_name, const NodeElement *before_this=nullptr)
Add a subtree node for a specific tree element to the children of this node.
bool operator==(const NodeElement &other) const
Determine if two node elements refer to the same node.
NodeElement insertNode(const std::string &name, const NodeElement *before_this=nullptr)
Add a new node to the children of this node.
NodeElement insertTreeFromFile(const std::string &path, const std::string &tree_name, const NodeElement *before_this=nullptr)
Concatenate a tree from a document created from a file and add its first child node to the children o...
std::enable_if_t< std::is_base_of_v< NodeModelType, T >, NodeElement & > removeFirstChild(const std::string &instance_name="")
Recursively visit this node's children in execution order and remove the first node with a particular...
NodeElement & removeChildren()
Recursively remove all children of this node element.
NodeElement & operator=(const NodeElement &other)
Replace this node with another.
std::vector< NodeElement > deepApply(DeepApplyCallback apply_callback)
Recursively apply a callback to this node's children.
Handle for a single behavior tree of a TreeDocument.
TreeElement(TreeDocument *doc_ptr, XMLElement *ele_ptr)
Protected constructor intended to be used only by certain factory methods of TreeDocument.
std::string getName() const override
Get the name of the behavior tree.
BT::Result verify() const
Verify that this behavior tree is structured correctly and can be created successfully.
NodeManifest getRequiredNodeManifest() const
Assemble the node manifest that is required for successfully creating an instance of this tree.
TreeElement & makeRoot()
Set this behavior tree as the root tree of the parent document.
TreeElement & removeFirstChild(const std::string &registration_name="", const std::string &instance_name="")
TreeElement & operator=(const TreeElement &other)
Replace the behavior tree represented by this element with another.
std::enable_if_t< std::is_base_of_v< NodeModelType, T >, TreeElement & > removeFirstChild(const std::string &instance_name="")
TreeElement & setName(const std::string &tree_name) override
Set the name of the behavior tree.
std::string writeToString() const
Write this behavior tree to an XML encoded in a string.
TreeElement(const TreeElement &ele)=default
Copy constructor for a tree element.
TreeElement getRootTree()
Get the corresponding behavior tree element for the root tree of this document.
TreeDocument & mergeResource(const TreeResource &resource, bool adopt_root_tree=false)
Merge the behavior trees from one of the installed package's behavior tree resources.
std::string getRootTreeName() const
Get the name of this document's root tree.
TreeDocument & mergeTreeDocument(const XMLDocument &other, bool adopt_root_tree=false)
Merge another tree document with this one.
TreeDocument & mergeString(const std::string &tree_str, bool adopt_root_tree=false)
Create a tree document from a string and merge it with this one.
TreeElement newTreeFromDocument(const TreeDocument &other, const std::string &tree_name="")
Create a new behavior tree inside this document with the content of one found inside another tree doc...
void writeToFile(const std::string &path) const
Write the XML of this tree document to a file.
TreeElement newTreeFromFile(const std::string &path, const std::string &tree_name="")
Create a new behavior tree inside this document with the content of one found inside the XML file.
BT::Result verify() const
Verify that all behavior trees of this document are structured correctly and can be created successfu...
NodeManifest getRequiredNodeManifest() const
Assemble the node manifest that is required for successfully creating an instance of any of the docum...
std::map< std::string, NodeModel > NodeModelMap
Mapping of node registration names and their implementation details.
std::set< std::string > getRegisteredNodeNames(bool include_native=true) const
Get the names of all nodes that are known to this document.
TreeElement newTreeFromString(const std::string &tree_str, const std::string &tree_name="")
Create a new behavior tree inside this document with the content of one found inside the XML string.
TreeElement newTreeFromResource(const TreeResource &resource, const std::string &tree_name="")
Create a new behavior tree inside this document with the content of one the trees found inside a part...
TreeDocument & reset()
Clear this document and reset it to its initial state.
TreeElement getTree(const std::string &tree_name)
Get the corresponding behavior tree element for a tree inside this document.
TreeDocument & addNodeModel(bool include_native=false)
Add an behavior tree node model element to the document.
virtual TreeDocument & registerNodes(const NodeManifest &tree_node_manifest, bool override=false)
Load behavior tree node plugins and register them with the internal behavior tree factory.
TreeDocument & setRootTreeName(const std::string &tree_name)
Define the root tree of this document.
bool hasTreeName(const std::string &tree_name) const
Determine if this document specifies a behavior tree with a particular name.
static NodeModelMap getNodeModel(tinyxml2::XMLDocument &doc)
Convert a behavior tree node model document to the corresponding data structure.
TreeDocument & mergeFile(const std::string &path, bool adopt_root_tree=false)
Create a tree document from a file and merge it with this one.
std::vector< std::string > getAllTreeNames() const
Get the names of all behavior trees inside this document.
TreeDocument & mergeTree(const TreeElement &tree, bool make_root_tree=false)
Merge an existing behavior tree with this tree document.
std::string writeToString() const
Write the XML of this tree document to a string.
bool hasRootTreeName() const
Determine if this document specifies which of its trees is the root tree.
TreeDocument & removeTree(const std::string &tree_name)
Remove a particular behavior tree from this document.
TreeDocument(const std::string &format_version=BTCPP_FORMAT_DEFAULT_VERSION, NodeRegistrationLoader::SharedPtr tree_node_loader=NodeRegistrationLoader::make_shared())
Create a an empty tree document.
TreeElement newTree(const std::string &tree_name)
Create a new behavior tree inside this document.
Class containing behavior tree resource data.
Subtree behavior tree node model.
Core API for AutoAPMS's behavior tree implementation.
Definition builder.hpp:30
Models for all available behavior tree nodes.
Parameters for loading and registering a behavior tree node class from a shared library using e....
Data structure encapsulating the information of all ports implemented by a behavior tree node.
BT::NodeType type
Abstract type of the node.
std::vector< NodePortInfo > port_infos
Vector of implementation details for each data port.
Implementation details of a single data port.
std::string port_default
Default value of the port encoded as string.
bool port_has_default
Flag whether the port implements a default value or not.
BT::PortDirection port_direction
Direction of the port.
std::string port_type
String representation of the C++ type given to the port.