From dccd23430e5c061f2cae87d1f4c7689044be5fba Mon Sep 17 00:00:00 2001 From: artivis Date: Wed, 11 Sep 2019 17:00:11 -0400 Subject: [PATCH 01/22] add node idl design doc Signed-off-by: artivis --- .../ros2_node_idl/interface_declaration.xml | 45 +++++ articles/ros2_node_idl/package.xml | 9 + articles/ros_node_idl.md | 154 ++++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 articles/ros2_node_idl/interface_declaration.xml create mode 100644 articles/ros2_node_idl/package.xml create mode 100644 articles/ros_node_idl.md diff --git a/articles/ros2_node_idl/interface_declaration.xml b/articles/ros2_node_idl/interface_declaration.xml new file mode 100644 index 000000000..8d6bb0f20 --- /dev/null +++ b/articles/ros2_node_idl/interface_declaration.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + +``` + + +```xml + + + + + chatter + + + + + + + + clock + + + /foo/bar + + + example_service + + + example_action + + + diff --git a/articles/ros2_node_idl/package.xml b/articles/ros2_node_idl/package.xml new file mode 100644 index 000000000..daa18cd83 --- /dev/null +++ b/articles/ros2_node_idl/package.xml @@ -0,0 +1,9 @@ + + foo + + + + + + + diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md new file mode 100644 index 000000000..6769b2a95 --- /dev/null +++ b/articles/ros_node_idl.md @@ -0,0 +1,154 @@ +--- +layout: default +title: ROS 2 Interface Description Language +permalink: articles/ros2_node_interface_declarations.html +abstract: + This article specifies the ROS 2 Interface Description Language, a simple and standardized manner to export the complete interface (action/message/parameter/service) of node(s) in a package. +author: > + [Kyle Fazzari](https://github.com/kyrofa), + [Jérémie Deray](https://github.com/artivis) + +published: true +categories: Security +--- + +{:toc} + + +# {{ page.title }} + +
+{{ page.abstract }} +
+ +Original Author: {{ page.author }} + + +## Background + +Every ROS 2 node has an associated interface that describes how it communicates with other nodes, as well as how it is to be configured. This interface is defined in code, and consists of: + +- Actions +- Parameters +- Services +- Topics + +That interface is obviously very valuable on different levels and from different perspectives. While it is usually readily available to a developer looking at the code, it cannot be automatically extracted. The main barrier to this is the lack of introspection in C++. It therefore calls for the creation of a standardized way to explicitly define and export this information. + +This article defines a high-level abstraction allowing upstream packages to specify the communication requirements of the nodes in the package, such that final user, be it a developer or a static analysis tool, can benefit from it. The Interface Description Language specified in the next section is meant to be distributed alongside its associated package. This is true for the package source and also for the generated release. + +### Initial motivation + +Thanks to [DDS-Security][dds_security] and [SROS2][sros2_design], security is at the heart of ROS 2. DDS enforces access control using a signed permissions document for each domain participant (see the [DDS-Security spec][dds_security], section 9.4). In SROS 2, that permissions document is generated from a ROS-specific [XML][xml_wiki] policy file that may include the permissions for one or many nodes. + +Currently policy files can be created in one of two ways: +- Written by hand. +- A snapshot of the live ROS 2 graph can be taken and written into a policy that covers its current state via `ros2 security generate_policy`. + +While the first option is obviously very tedious and error-prone, the second only partially alleviates the burden due to the fact that it cannot fully cover the dynamic nature of a ROS 2 graph and all of its interactions. More problematic than these issues, though, is that both options put the onus of security squarely on the shoulders of end users. + +This introduces two problems: + +- While developers will be able to define the set of rules securing their own ROS 2 nodes, the nodes developed in-house are often outnumbered by upstream components when it comes to the entire node graph, and the developers are typically not experts in every component being used. Without that expertise, the entire node graph cannot be properly locked down. +- Consider a complex and popular upstream component, perhaps parts of the navigation stack. **Every end user** of this component must duplicate the effort of attempting to properly lock it down. + +While initially being approached from a ROS 2 Security perspective, the abstraction level of the Interface Description Language allows for the developments of other functionalities and tools. Such developments are briefly speculated in the last section of this article. + +## Package interface declaration + +How do upstream packages specify their interface requirements? Through a high-level description of all the actions, parameters, services and topics, provided or required, by each node within the package. + +On the model of the [`pluginlib` export mechanism][rep149_export], the package interface is defined in a separate [XML][xml_wiki] file and exported from the package manifest `package.xml`. This scheme avoids polluting the package manifest and allows for dispatching the interface definition of several nodes to several files. + +This article standardizes the Interface Description Language XML format hereafter. The following example illustrates it, + +``` xml +{% include_relative ros2_node_idl/interface_declaration.xml %} +``` + +Once an interface description file being defined, it is exported from the package manifest as shown in the following example, + +``` xml +{% include_relative ros2_node_idl/package.xml %} +``` + +### Schema + +This section is a description of a ROS 2 Interface Description Language schema. Relying on XML syntax, it is expressed in terms of XML tags. + +#### `interface` + +The introduction of the `interface` tag within the `export` tag of the package manifest raises a small difficulty with regards to the [REP-149][rep149_export]. +The REP specifies, + +“To avoid potential collisions, an export tag should have the same name as the package which is meant to process it. The content of that tag is up to the package to define and use.” + +Considering the high level abstraction of the Interface Description Language, the `interface` tag is not meant for a specific package but rather declares intrinsic properties for anyone to process it. However, the keyword is likely solidly descriptive enough to either be accepted as falling under [REP-149][rep149_export] or else to motivate an amendment of the REP. + +#### `node` + +Encapsulate a sequence of interfaces. It is specific to a unique node instance as determined by its associated attributes. + +Attributes: +- **name** The name of the node +- **ns** The namespace of the node + +#### `action` + +Attributes: +- **name** The name of the action +- **type** The type of the action + - Valid values are any ROS action types as defined in +- **server** Whether or not the node provides an action server for the action + - Valid values are “true” or “false” +- **client** Whether or not the node provides a client for the action + - Valid values are “true” or “false” + +#### `message` + +Attributes: +- **name** The name of the topic +- **type** The type of the message + - Valid values are any ROS message types as defined in +- **publisher** Whether or not the node publishes on the topic + - Valid values are “true” or “false” +- **subscription** Whether or not the node subscribes to the topic + - Valid values are “true” or “false” + +#### `parameter` + +Attributes: +- **name** The name of the parameter +- **type** The type of the parameter + - Valid values are any ROS parameter types as defined in + +#### `service` + +Attributes: +- **name** The name of the service +- **type** The type of the service + - Valid values are any ROS service types as defined in +- **server** Whether or not the node provides a server for the service + - Valid values are “true” or “false” +- **client** Whether or not the node provides a client for the service + - Valid values are “true” or “false” + +## Fostering new use cases + +While being initiated from a ROS 2 Security stance, the Interface Description Language fosters other use cases and tools briefly speculated here, + +- Interface static analysis (launch file validation, remapping assertion etc) + - e.g. "You're remapping from a topic that isn't being published!" + - e.g. Facilitate the understanding of system-wide access control +- Auto generation of a node skeleton code + - e.g. `$ ros2 pkg create --from-interface interface_declaration.xml` generate a fully functional node given an interface +- Interface documentation auto generation + - e.g. To be published in ROS 2 wiki, maintaining it up-to-date and guaranteeing the consistency between the actual interface and its documentation +- System-wide interface-based design using graphical tools +- End-user permissions validation + - e.g. Think smartphone apps permissions upon installation + +[dds_security]: https://www.omg.org/spec/DDS-SECURITY/1.1/PDF +[sros2_design]: /articles/ros2_dds_security.html +[xml_wiki]: https://en.wikipedia.org/wiki/xml +[rep149_export]: http://www.ros.org/reps/rep-0149.html#export From e8e0247183237489a40a0d2ccdfaa58b77381dd6 Mon Sep 17 00:00:00 2001 From: artivis Date: Mon, 25 Nov 2019 09:31:41 -0500 Subject: [PATCH 02/22] update node idl design doc Signed-off-by: artivis --- .../ros2_node_idl/interface_declaration.xml | 44 +--- articles/ros2_node_idl/package.xml | 7 +- articles/ros_node_idl.md | 195 ++++++++++-------- 3 files changed, 123 insertions(+), 123 deletions(-) diff --git a/articles/ros2_node_idl/interface_declaration.xml b/articles/ros2_node_idl/interface_declaration.xml index 8d6bb0f20..dbecc855f 100644 --- a/articles/ros2_node_idl/interface_declaration.xml +++ b/articles/ros2_node_idl/interface_declaration.xml @@ -1,45 +1,15 @@ - - - +```xml + + - + - - + - - + - + ``` - - -```xml - - - - - chatter - - - - - - - - clock - - - /foo/bar - - - example_service - - - example_action - - - diff --git a/articles/ros2_node_idl/package.xml b/articles/ros2_node_idl/package.xml index daa18cd83..ecff5431c 100644 --- a/articles/ros2_node_idl/package.xml +++ b/articles/ros2_node_idl/package.xml @@ -1,9 +1,10 @@ +```xml - foo + example-package - + - +``` diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index 6769b2a95..cfcb2c91f 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -1,12 +1,12 @@ --- layout: default -title: ROS 2 Interface Description Language -permalink: articles/ros2_node_interface_declarations.html +title: ROS 2 Interface Definition Language +permalink: articles/ros2_node_interface_definition_language.html abstract: - This article specifies the ROS 2 Interface Description Language, a simple and standardized manner to export the complete interface (action/message/parameter/service) of node(s) in a package. + This article specifies the ROS 2 Interface Definition Language, a simple and standardized manner to export the complete interface (action/message/parameter/service) of node(s) in a package. author: > - [Kyle Fazzari](https://github.com/kyrofa), - [Jérémie Deray](https://github.com/artivis) + [Jérémie Deray](https://github.com/artivis), + [Kyle Fazzari](https://github.com/kyrofa) published: true categories: Security @@ -26,129 +26,158 @@ Original Author: {{ page.author }} ## Background -Every ROS 2 node has an associated interface that describes how it communicates with other nodes, as well as how it is to be configured. This interface is defined in code, and consists of: +Every ROS 2 node has an associated interface that describes how it communicates with other nodes, as well as how it is to be configured. +This interface is defined in code, and consists of: -- Actions -- Parameters -- Services -- Topics +- Actions (server or client) +- Parameters +- Services (server or client) +- Topics (publisher or subscriber) -That interface is obviously very valuable on different levels and from different perspectives. While it is usually readily available to a developer looking at the code, it cannot be automatically extracted. The main barrier to this is the lack of introspection in C++. It therefore calls for the creation of a standardized way to explicitly define and export this information. +The information contained within that interface is obviously very valuable on different levels and from different perspectives. +While it is usually readily available to a developer looking at the code, it cannot reliably be automatically extracted. +It therefore calls for the creation of a standardized way to explicitly define and export this information. -This article defines a high-level abstraction allowing upstream packages to specify the communication requirements of the nodes in the package, such that final user, be it a developer or a static analysis tool, can benefit from it. The Interface Description Language specified in the next section is meant to be distributed alongside its associated package. This is true for the package source and also for the generated release. +This article defines a high-level abstraction allowing upstream packages to specify the communication requirements of the nodes in the package, such that the final user, be it a developer or a static analysis tool, can benefit from it. +The Interface Definition Language (IDL) specified in the next section is meant to be distributed alongside its associated package. +This is true for the package source and also for the generated release. Whether the interface is declared or not is up to the package author and should not prevent the correct execution of any system pre-existing the IDL. +Similarly, the declared interface may be only partial and allow for the full use of pre-existing systems and the use of dependent systems on the parts covered by the partial interface. -### Initial motivation +## Motivation -Thanks to [DDS-Security][dds_security] and [SROS2][sros2_design], security is at the heart of ROS 2. DDS enforces access control using a signed permissions document for each domain participant (see the [DDS-Security spec][dds_security], section 9.4). In SROS 2, that permissions document is generated from a ROS-specific [XML][xml_wiki] policy file that may include the permissions for one or many nodes. +While initially being approached from a ROS 2 Security perspective, the abstraction level of the IDL allows for the developments of other functionalities and tools. + +### Security motivation + +Thanks to [DDS-Security][dds_security] and [SROS 2][sros2_design], security is at the heart of ROS 2. +DDS enforces access control using a signed permissions document for each domain participant (see the [DDS-Security spec][dds_security], section 9.4). +In SROS 2, that permissions document is generated from a ROS-specific [XML][xml_wiki] policy file that may include the permissions for one or many nodes. Currently policy files can be created in one of two ways: -- Written by hand. -- A snapshot of the live ROS 2 graph can be taken and written into a policy that covers its current state via `ros2 security generate_policy`. +- Written by hand. +- A snapshot of the live ROS 2 graph can be taken and written into a policy that covers its current state via `ros2 security generate_policy`. + +While the first option is obviously very tedious and error-prone, the second only partially alleviates the burden due to the fact that it cannot fully cover the dynamic nature of a ROS 2 graph and all of its interactions. +More problematic than these issues, though, is that both options put the onus of security squarely on the shoulders of end users. This introduces two problems: -While the first option is obviously very tedious and error-prone, the second only partially alleviates the burden due to the fact that it cannot fully cover the dynamic nature of a ROS 2 graph and all of its interactions. More problematic than these issues, though, is that both options put the onus of security squarely on the shoulders of end users. +While developers will be able to define the set of rules securing their own ROS 2 nodes, the nodes developed in-house are often outnumbered by upstream components when it comes to the entire node graph, and the developers are typically not experts in every component being used. +Without that expertise, the entire node graph cannot be properly locked down. +Consider a complex and popular upstream component, perhaps parts of the navigation stack. **Every end user** of this component must duplicate the effort of attempting to properly lock it down. -This introduces two problems: +If ROS 2 provided a way for upstream package authors to specify the interface required by the nodes in their package, and if the tools to generate security policies from that interface existed, neither of these problems would exist. (**TODO**: link to upcoming design doc about using node IDL in ROS 2 security) -- While developers will be able to define the set of rules securing their own ROS 2 nodes, the nodes developed in-house are often outnumbered by upstream components when it comes to the entire node graph, and the developers are typically not experts in every component being used. Without that expertise, the entire node graph cannot be properly locked down. -- Consider a complex and popular upstream component, perhaps parts of the navigation stack. **Every end user** of this component must duplicate the effort of attempting to properly lock it down. +### Other motivations -While initially being approached from a ROS 2 Security perspective, the abstraction level of the Interface Description Language allows for the developments of other functionalities and tools. Such developments are briefly speculated in the last section of this article. +Outside of security, there are several fascinating possibilities unlocked by having such an interface. +For example, consider how this could impact [ROS 2 launch] [launch_ros]. It would be able to statically (i.e. before running anything) determine if parameter names or remappings are incorrect, among other similar sanity checks. +Another example of the usefulness of having a static interface is the ability to create graphical tools for putting a ROS system together. +Yet another example would be an additional feature in `ros2 pkg create` that would allow a developer to hand it an IDL and have it generate scaffolding for a node with that interface. -## Package interface declaration +These examples are only a subset of use-cases made possible by such an interface. +It's clear that this is useful well beyond security. -How do upstream packages specify their interface requirements? Through a high-level description of all the actions, parameters, services and topics, provided or required, by each node within the package. +## Package interface -On the model of the [`pluginlib` export mechanism][rep149_export], the package interface is defined in a separate [XML][xml_wiki] file and exported from the package manifest `package.xml`. This scheme avoids polluting the package manifest and allows for dispatching the interface definition of several nodes to several files. +How do upstream packages specify their interface requirements? +Through a high-level description of all the actions, parameters, services and topics, provided or required, by each node within the package. -This article standardizes the Interface Description Language XML format hereafter. The following example illustrates it, +The package interface is defined in a separate [XML][xml_wiki] file and exported from the `package.xml` using [REP 149's export mechanism][rep149_export], thereby avoiding pollution of the package manifest. +The interface may cover only a subset of nodes in a package, as long as the nodes that _are_ covered are done so completely. -``` xml -{% include_relative ros2_node_idl/interface_declaration.xml %} -``` +Here is an example IDL for a package containing two nodes: -Once an interface description file being defined, it is exported from the package manifest as shown in the following example, +{%include_relative ros2_node_interface_declaration/interface_declaration.xml} -``` xml -{% include_relative ros2_node_idl/package.xml %} -``` +Once an IDL file is written, it is exported from the package manifest: -### Schema +{%include_relative ros2_node_interface_declaration/package.xml} -This section is a description of a ROS 2 Interface Description Language schema. Relying on XML syntax, it is expressed in terms of XML tags. +### Schema for `package.xml`'s export tag #### `interface` -The introduction of the `interface` tag within the `export` tag of the package manifest raises a small difficulty with regards to the [REP-149][rep149_export]. -The REP specifies, +This is how the package exports its defined IDL for other tools to consume. -“To avoid potential collisions, an export tag should have the same name as the package which is meant to process it. The content of that tag is up to the package to define and use.” +Attributes: -Considering the high level abstraction of the Interface Description Language, the `interface` tag is not meant for a specific package but rather declares intrinsic properties for anyone to process it. However, the keyword is likely solidly descriptive enough to either be accepted as falling under [REP-149][rep149_export] or else to motivate an amendment of the REP. +**path**: Path to XML file containing IDL -#### `node` +Note that the introduction of the `interface` tag within the `export` tag of the package manifest raises a small difficulty with regards to the [REP 149][rep149_export]. +The REP specifies: + +> To avoid potential collisions, an export tag should have the same name as the package which is meant to process it. The content of that tag is up to the package to define and use. -Encapsulate a sequence of interfaces. It is specific to a unique node instance as determined by its associated attributes. +Considering the high level abstraction of the IDL, the `interface` tag is not meant for a specific package but rather declares intrinsic properties for anyone to process it. +However, the keyword is likely solidly descriptive enough to either be accepted as falling under [REP 149][rep149_export] or else to motivate an amendment of the REP. + +### IDL Schema + +#### `interface` + +This tag contains the package interface, made up of a collection of node interfaces. +Root tag of the IDL file. There must be only one tag per IDL file. Attributes: -- **name** The name of the node -- **ns** The namespace of the node +- **version**: version of schema in use, allowing for future revisions. -#### `action` +#### `node` + +Encapsulate a sequence of ROS entity interfaces. +It is specific to a node as determined by its associated attributes. Attributes: -- **name** The name of the action -- **type** The type of the action - - Valid values are any ROS action types as defined in -- **server** Whether or not the node provides an action server for the action - - Valid values are “true” or “false” -- **client** Whether or not the node provides a client for the action - - Valid values are “true” or “false” +- **name**: The base name of the node. -#### `message` +#### `action` + +Define the interface for a given action. Attributes: -- **name** The name of the topic -- **type** The type of the message - - Valid values are any ROS message types as defined in -- **publisher** Whether or not the node publishes on the topic - - Valid values are “true” or “false” -- **subscription** Whether or not the node subscribes to the topic - - Valid values are “true” or “false” +- **name**: The name of the action. +- **type**: The type of the action. +Valid values are any ROS action types. +- **server**: Whether or not the node provides an action server for the action. +Valid values are "true" or "false". Defaults to "false". +- **client**: Whether or not the node provides a client for the action. +Valid values are "true" or "false". Defaults to "false". #### `parameter` +Define the interface for a given parameter. + Attributes: -- **name** The name of the parameter -- **type** The type of the parameter - - Valid values are any ROS parameter types as defined in +- **name**: The name of the parameter. +- **type**: The type of the parameter. +Valid values are any ROS parameter types. #### `service` +Define the interface for a given service. + +Attributes: +- **name**: The name of the service. +- **type**: The type of the service. +Valid values are any ROS service types. +- **server**: Whether or not the node provides a server for the service. +Valid values are "true" or "false". Defaults to "false". +- **client**: Whether or not the node provides a client for the service. +Valid values are "true" or "false". Defaults to "false". + +#### `topic` + +Define the interface for a given topic. + Attributes: -- **name** The name of the service -- **type** The type of the service - - Valid values are any ROS service types as defined in -- **server** Whether or not the node provides a server for the service - - Valid values are “true” or “false” -- **client** Whether or not the node provides a client for the service - - Valid values are “true” or “false” - -## Fostering new use cases - -While being initiated from a ROS 2 Security stance, the Interface Description Language fosters other use cases and tools briefly speculated here, - -- Interface static analysis (launch file validation, remapping assertion etc) - - e.g. "You're remapping from a topic that isn't being published!" - - e.g. Facilitate the understanding of system-wide access control -- Auto generation of a node skeleton code - - e.g. `$ ros2 pkg create --from-interface interface_declaration.xml` generate a fully functional node given an interface -- Interface documentation auto generation - - e.g. To be published in ROS 2 wiki, maintaining it up-to-date and guaranteeing the consistency between the actual interface and its documentation -- System-wide interface-based design using graphical tools -- End-user permissions validation - - e.g. Think smartphone apps permissions upon installation +- **name**: The name of the topic. +- **type**: The type of the message. +Valid values are any ROS message types. +- **publisher**: Whether or not the node publishes on the topic. +Valid values are "true" or "false". Defaults to "false". +- **subscription**: Whether or not the node subscribes to the topic. +Valid values are "true" or "false". Defaults to "false". [dds_security]: https://www.omg.org/spec/DDS-SECURITY/1.1/PDF [sros2_design]: /articles/ros2_dds_security.html +[launch_ros]: https://github.com/ros2/launch_ros [xml_wiki]: https://en.wikipedia.org/wiki/xml [rep149_export]: http://www.ros.org/reps/rep-0149.html#export From b8cc64ac421947512c6bd1bc9c3f1eebb75323a1 Mon Sep 17 00:00:00 2001 From: artivis Date: Mon, 25 Nov 2019 10:17:49 -0500 Subject: [PATCH 03/22] update title and category to avoid confusion with idl Signed-off-by: artivis --- articles/ros_node_idl.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index cfcb2c91f..954553bd2 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -1,15 +1,14 @@ --- layout: default -title: ROS 2 Interface Definition Language +title: ROS 2 Node Interface Definition Language permalink: articles/ros2_node_interface_definition_language.html abstract: This article specifies the ROS 2 Interface Definition Language, a simple and standardized manner to export the complete interface (action/message/parameter/service) of node(s) in a package. author: > [Jérémie Deray](https://github.com/artivis), [Kyle Fazzari](https://github.com/kyrofa) - published: true -categories: Security +categories: Interfaces --- {:toc} From 3c8028c9df96ce0dece4c6814ea14538cd821e6b Mon Sep 17 00:00:00 2001 From: artivis Date: Mon, 25 Nov 2019 10:17:58 -0500 Subject: [PATCH 04/22] fix relative links Signed-off-by: artivis --- articles/ros_node_idl.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index 954553bd2..3e92c50f2 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -85,11 +85,11 @@ The interface may cover only a subset of nodes in a package, as long as the node Here is an example IDL for a package containing two nodes: -{%include_relative ros2_node_interface_declaration/interface_declaration.xml} +{% include_relative ros2_node_idl/interface_declaration.xml %} Once an IDL file is written, it is exported from the package manifest: -{%include_relative ros2_node_interface_declaration/package.xml} +{% include_relative ros2_node_idl/package.xml %} ### Schema for `package.xml`'s export tag From f8ebe300209e05b9756a77f45a1e1cbfa01dffb0 Mon Sep 17 00:00:00 2001 From: artivis Date: Mon, 25 Nov 2019 10:28:12 -0500 Subject: [PATCH 05/22] clean up todo Signed-off-by: artivis --- articles/ros_node_idl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index 3e92c50f2..5168d5e96 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -63,7 +63,7 @@ While developers will be able to define the set of rules securing their own ROS Without that expertise, the entire node graph cannot be properly locked down. Consider a complex and popular upstream component, perhaps parts of the navigation stack. **Every end user** of this component must duplicate the effort of attempting to properly lock it down. -If ROS 2 provided a way for upstream package authors to specify the interface required by the nodes in their package, and if the tools to generate security policies from that interface existed, neither of these problems would exist. (**TODO**: link to upcoming design doc about using node IDL in ROS 2 security) +If ROS 2 provided a way for upstream package authors to specify the interface required by the nodes in their package, and if the tools to generate security policies from that interface existed, neither of these problems would exist. ### Other motivations From ee4ee96362b49a966813809d13db6c1fc6be4cfc Mon Sep 17 00:00:00 2001 From: Jeremie Deray Date: Mon, 25 Nov 2019 13:56:20 -0500 Subject: [PATCH 06/22] missed line break Co-Authored-By: Jacob Perron --- articles/ros_node_idl.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index 5168d5e96..cdb4ff3ec 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -68,7 +68,8 @@ If ROS 2 provided a way for upstream package authors to specify the interface re ### Other motivations Outside of security, there are several fascinating possibilities unlocked by having such an interface. -For example, consider how this could impact [ROS 2 launch] [launch_ros]. It would be able to statically (i.e. before running anything) determine if parameter names or remappings are incorrect, among other similar sanity checks. +For example, consider how this could impact [ROS 2 launch][launch_ros]. +It would be able to statically (i.e. before running anything) determine if parameter names or remappings are incorrect, among other similar sanity checks. Another example of the usefulness of having a static interface is the ability to create graphical tools for putting a ROS system together. Yet another example would be an additional feature in `ros2 pkg create` that would allow a developer to hand it an IDL and have it generate scaffolding for a node with that interface. From 80ff88bc53cc4e7a16c2678e5cd5338ba0ff23c1 Mon Sep 17 00:00:00 2001 From: Jeremie Deray Date: Mon, 25 Nov 2019 14:08:28 -0500 Subject: [PATCH 07/22] Fix interface_declaration.xml Co-Authored-By: Jacob Perron --- articles/ros2_node_idl/interface_declaration.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/ros2_node_idl/interface_declaration.xml b/articles/ros2_node_idl/interface_declaration.xml index dbecc855f..72c7be2fd 100644 --- a/articles/ros2_node_idl/interface_declaration.xml +++ b/articles/ros2_node_idl/interface_declaration.xml @@ -2,7 +2,7 @@ - + From fce235c7089729742aab4b51a534c98ab2d65d7f Mon Sep 17 00:00:00 2001 From: Jeremie Deray Date: Mon, 25 Nov 2019 14:08:41 -0500 Subject: [PATCH 08/22] Fix interface_declaration.xml Co-Authored-By: Jacob Perron --- articles/ros2_node_idl/interface_declaration.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/ros2_node_idl/interface_declaration.xml b/articles/ros2_node_idl/interface_declaration.xml index 72c7be2fd..56a0c43e9 100644 --- a/articles/ros2_node_idl/interface_declaration.xml +++ b/articles/ros2_node_idl/interface_declaration.xml @@ -7,7 +7,7 @@ - + From 45d49193dff0fd9645f18cbaeb3e60eba17a6cff Mon Sep 17 00:00:00 2001 From: Jeremie Deray Date: Mon, 25 Nov 2019 14:10:47 -0500 Subject: [PATCH 09/22] missed line break Co-Authored-By: Jacob Perron --- articles/ros_node_idl.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index cdb4ff3ec..200563ef9 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -57,7 +57,8 @@ Currently policy files can be created in one of two ways: - A snapshot of the live ROS 2 graph can be taken and written into a policy that covers its current state via `ros2 security generate_policy`. While the first option is obviously very tedious and error-prone, the second only partially alleviates the burden due to the fact that it cannot fully cover the dynamic nature of a ROS 2 graph and all of its interactions. -More problematic than these issues, though, is that both options put the onus of security squarely on the shoulders of end users. This introduces two problems: +More problematic than these issues, though, is that both options put the onus of security squarely on the shoulders of end users. +This introduces two problems: While developers will be able to define the set of rules securing their own ROS 2 nodes, the nodes developed in-house are often outnumbered by upstream components when it comes to the entire node graph, and the developers are typically not experts in every component being used. Without that expertise, the entire node graph cannot be properly locked down. From 99a3e7c6e12832075cc9000b39737ca35d59258b Mon Sep 17 00:00:00 2001 From: Jeremie Deray Date: Mon, 25 Nov 2019 14:15:06 -0500 Subject: [PATCH 10/22] missed line break Co-Authored-By: Jacob Perron --- articles/ros_node_idl.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index 200563ef9..20c6aa734 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -62,7 +62,8 @@ This introduces two problems: While developers will be able to define the set of rules securing their own ROS 2 nodes, the nodes developed in-house are often outnumbered by upstream components when it comes to the entire node graph, and the developers are typically not experts in every component being used. Without that expertise, the entire node graph cannot be properly locked down. -Consider a complex and popular upstream component, perhaps parts of the navigation stack. **Every end user** of this component must duplicate the effort of attempting to properly lock it down. +Consider a complex and popular upstream component, perhaps parts of the navigation stack. +**Every end user** of this component must duplicate the effort of attempting to properly lock it down. If ROS 2 provided a way for upstream package authors to specify the interface required by the nodes in their package, and if the tools to generate security policies from that interface existed, neither of these problems would exist. From ed7aedbf5e07944b88d52f17f2f02dec4a987b3c Mon Sep 17 00:00:00 2001 From: artivis Date: Mon, 25 Nov 2019 14:27:01 -0500 Subject: [PATCH 11/22] missed line break Signed-off-by: artivis --- articles/ros_node_idl.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index 20c6aa734..2eebf2061 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -39,7 +39,8 @@ It therefore calls for the creation of a standardized way to explicitly define a This article defines a high-level abstraction allowing upstream packages to specify the communication requirements of the nodes in the package, such that the final user, be it a developer or a static analysis tool, can benefit from it. The Interface Definition Language (IDL) specified in the next section is meant to be distributed alongside its associated package. -This is true for the package source and also for the generated release. Whether the interface is declared or not is up to the package author and should not prevent the correct execution of any system pre-existing the IDL. +This is true for the package source and also for the generated release. +Whether the interface is declared or not is up to the package author and should not prevent the correct execution of any system pre-existing the IDL. Similarly, the declared interface may be only partial and allow for the full use of pre-existing systems and the use of dependent systems on the parts covered by the partial interface. ## Motivation From 78f4d27323835008eea6fa9c45ec7553acb97aa3 Mon Sep 17 00:00:00 2001 From: artivis Date: Mon, 25 Nov 2019 14:37:43 -0500 Subject: [PATCH 12/22] rephrase interface tag description Signed-off-by: artivis --- articles/ros_node_idl.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index 2eebf2061..bcf203923 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -117,8 +117,8 @@ However, the keyword is likely solidly descriptive enough to either be accepted #### `interface` -This tag contains the package interface, made up of a collection of node interfaces. -Root tag of the IDL file. There must be only one tag per IDL file. +Root tag of the IDL file, it is made up of a collection of node interfaces. +There must be only one tag per IDL file. Attributes: - **version**: version of schema in use, allowing for future revisions. From 23aeab0e9c113066822610f18548059ff1cbcbb7 Mon Sep 17 00:00:00 2001 From: artivis Date: Mon, 25 Nov 2019 14:38:18 -0500 Subject: [PATCH 13/22] rephrase distri idl file Signed-off-by: artivis --- articles/ros_node_idl.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index bcf203923..d8f268f62 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -38,8 +38,7 @@ While it is usually readily available to a developer looking at the code, it can It therefore calls for the creation of a standardized way to explicitly define and export this information. This article defines a high-level abstraction allowing upstream packages to specify the communication requirements of the nodes in the package, such that the final user, be it a developer or a static analysis tool, can benefit from it. -The Interface Definition Language (IDL) specified in the next section is meant to be distributed alongside its associated package. -This is true for the package source and also for the generated release. +The Interface Definition Language (IDL) specified in the next section is meant to be distributed alongside its associated package, be it in the source code or a generated release packaging format (e.g. debian). Whether the interface is declared or not is up to the package author and should not prevent the correct execution of any system pre-existing the IDL. Similarly, the declared interface may be only partial and allow for the full use of pre-existing systems and the use of dependent systems on the parts covered by the partial interface. From 3fb7ab5d414adbde0a771bf231bc3ef3eaf89e88 Mon Sep 17 00:00:00 2001 From: artivis Date: Mon, 25 Nov 2019 16:06:44 -0500 Subject: [PATCH 14/22] explicit per-node idl file Signed-off-by: artivis --- articles/ros_node_idl.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index d8f268f62..8accd7cb1 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -94,6 +94,8 @@ Once an IDL file is written, it is exported from the package manifest: {% include_relative ros2_node_idl/package.xml %} +Note that several IDL files can be exported, allowing for writing an IDL file per node. + ### Schema for `package.xml`'s export tag #### `interface` From c97a7a982475b125eb9aa3e0fa735c629ca5b863 Mon Sep 17 00:00:00 2001 From: Kyle Fazzari Date: Thu, 5 Dec 2019 14:25:14 -0800 Subject: [PATCH 15/22] Add "challenges" section Signed-off-by: Kyle Fazzari --- articles/ros_node_idl.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index 8accd7cb1..ddffeb059 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -78,6 +78,24 @@ Yet another example would be an additional feature in `ros2 pkg create` that wou These examples are only a subset of use-cases made possible by such an interface. It's clear that this is useful well beyond security. +## Challenges to overcome + +This proposal has a number of potential upsides, but it also has some downsides worthy of discussion. + +### This is only really useful if it gains significant adoption in upstream packages + +It's true that, if not all of the packages in one's system have adopted this, its gains are incomplete. +However, it's still useful even if only a subset of the packages adopt it (e.g. one's own packages), which means even without signifant upstream adoption it will still be useful to individuals or organizations. +Upstream packages that haven't adopted this simply won't benefit from it. +Also, its usefulness hopefully outweighs the work required to implement it upstream, and it's certainly something that can be contributed by community members given that the interface would be reviewed by the experts in the package. + +### Declared and actual interface can get out of sync + +This is certainly a concern: an out-of-date interface is debatably less useful than having no interface at all. +There are a number of possibilities that will help with this issue. +One possibility is to more tightly couple the declared and actual interface by creating a library that consumes the declared interface and creates the corresponding ROS entities. +Another is the fact that, as soon as the node is running, RCL itself (or another `ros2` command) can verify that the actual interface properly corresponds to the declared interface, and can act appropriately. + ## Package interface How do upstream packages specify their interface requirements? From da63aa62fabb216e04cd3bec6d35f54c33559e7f Mon Sep 17 00:00:00 2001 From: artivis Date: Mon, 9 Dec 2019 14:56:30 -0500 Subject: [PATCH 16/22] add qos settings --- articles/ros_node_idl.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index ddffeb059..b9b90ea73 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -162,6 +162,8 @@ Valid values are any ROS action types. Valid values are "true" or "false". Defaults to "false". - **client**: Whether or not the node provides a client for the action. Valid values are "true" or "false". Defaults to "false". +- **qos**: The Quality of Service setting for the action. +Defaults to [rcl_action_qos_profile_status_default][rcl_action_qos_profile_status_default_link] #### `parameter` @@ -184,6 +186,8 @@ Valid values are any ROS service types. Valid values are "true" or "false". Defaults to "false". - **client**: Whether or not the node provides a client for the service. Valid values are "true" or "false". Defaults to "false". +- **qos**: The Quality of Service setting for the service. +Defaults to [rmw_qos_profile_services_default][rmw_qos_profile_services_default_link] #### `topic` @@ -197,9 +201,14 @@ Valid values are any ROS message types. Valid values are "true" or "false". Defaults to "false". - **subscription**: Whether or not the node subscribes to the topic. Valid values are "true" or "false". Defaults to "false". +- **qos**: The Quality of Service setting for the topic. +Defaults to [rmw_qos_profile_default][rmw_qos_profile_default_link] [dds_security]: https://www.omg.org/spec/DDS-SECURITY/1.1/PDF [sros2_design]: /articles/ros2_dds_security.html [launch_ros]: https://github.com/ros2/launch_ros [xml_wiki]: https://en.wikipedia.org/wiki/xml [rep149_export]: http://www.ros.org/reps/rep-0149.html#export +[rcl_action_qos_profile_status_default_link]: https://github.com/ros2/rcl/blob/master/rcl_action/include/rcl_action/default_qos.h +[rmw_qos_profile_services_default_link]: https://github.com/ros2/rmw/blob/master/rmw/include/rmw/qos_profiles.h#L64 +[rmw_qos_profile_default_link]: https://github.com/ros2/rmw/blob/master/rmw/include/rmw/qos_profiles.h#L51 From 19b9738e0491f97ff3c14a01701eebee7b484f92 Mon Sep 17 00:00:00 2001 From: artivis Date: Thu, 19 Dec 2019 11:56:52 -0500 Subject: [PATCH 17/22] update qos as a sub-tag --- .../ros2_node_idl/interface_declaration.xml | 12 +++++++- articles/ros_node_idl.md | 29 +++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/articles/ros2_node_idl/interface_declaration.xml b/articles/ros2_node_idl/interface_declaration.xml index 56a0c43e9..8a904898a 100644 --- a/articles/ros2_node_idl/interface_declaration.xml +++ b/articles/ros2_node_idl/interface_declaration.xml @@ -7,7 +7,17 @@ - + + + diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index b9b90ea73..3cff608fe 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -162,7 +162,9 @@ Valid values are any ROS action types. Valid values are "true" or "false". Defaults to "false". - **client**: Whether or not the node provides a client for the action. Valid values are "true" or "false". Defaults to "false". -- **qos**: The Quality of Service setting for the action. + +Sub-tag: +- **qos**: The Quality of Service setting for the action - see the [qos tag](####qos). Defaults to [rcl_action_qos_profile_status_default][rcl_action_qos_profile_status_default_link] #### `parameter` @@ -186,7 +188,9 @@ Valid values are any ROS service types. Valid values are "true" or "false". Defaults to "false". - **client**: Whether or not the node provides a client for the service. Valid values are "true" or "false". Defaults to "false". -- **qos**: The Quality of Service setting for the service. + +Sub-tag: +- **qos**: The Quality of Service setting for the service - see the [qos tag](####qos). Defaults to [rmw_qos_profile_services_default][rmw_qos_profile_services_default_link] #### `topic` @@ -201,9 +205,27 @@ Valid values are any ROS message types. Valid values are "true" or "false". Defaults to "false". - **subscription**: Whether or not the node subscribes to the topic. Valid values are "true" or "false". Defaults to "false". -- **qos**: The Quality of Service setting for the topic. + +Sub-tag: +- **qos**: The Quality of Service setting for the topic - see the [qos tag](####qos). Defaults to [rmw_qos_profile_default][rmw_qos_profile_default_link] +#### `qos` + +Define the quality of service. It reflects the qos parameters of the [rmw_qos_profile_t][rmw_qos_profile_t] structure. +This tag is a sub-element of either an action, a service or a topic. + +Attributes: +- **history**: The size of the message queue. +- **reliability**: The reliability QoS policy setting. +- **durability**: The durability QoS policy setting. +- **deadline**: The period at which messages are expected to be sent/received. +- **lifespan**: The age at which messages are considered expired and no longer valid. +- **liveliness**: Liveliness QoS policy setting. +- **liveliness_lease_duration**: The time within which the RMW node or publisher must show that it is alive. +- **avoid_ros_namespace_conventions**: If true, any ROS specific namespacing conventions will be circumvented. + + [dds_security]: https://www.omg.org/spec/DDS-SECURITY/1.1/PDF [sros2_design]: /articles/ros2_dds_security.html [launch_ros]: https://github.com/ros2/launch_ros @@ -212,3 +234,4 @@ Defaults to [rmw_qos_profile_default][rmw_qos_profile_default_link] [rcl_action_qos_profile_status_default_link]: https://github.com/ros2/rcl/blob/master/rcl_action/include/rcl_action/default_qos.h [rmw_qos_profile_services_default_link]: https://github.com/ros2/rmw/blob/master/rmw/include/rmw/qos_profiles.h#L64 [rmw_qos_profile_default_link]: https://github.com/ros2/rmw/blob/master/rmw/include/rmw/qos_profiles.h#L51 +[rmw_qos_profile_t]: https://github.com/ros2/rmw/blob/master/rmw/include/rmw/types.h#L299 From 2da495a25f4d1e86b8044d6bdf14d2417a98ab33 Mon Sep 17 00:00:00 2001 From: artivis Date: Mon, 6 Jan 2020 15:53:18 -0500 Subject: [PATCH 18/22] typo Signed-off-by: artivis --- articles/ros_node_idl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index 3cff608fe..4abf2a97d 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -85,7 +85,7 @@ This proposal has a number of potential upsides, but it also has some downsides ### This is only really useful if it gains significant adoption in upstream packages It's true that, if not all of the packages in one's system have adopted this, its gains are incomplete. -However, it's still useful even if only a subset of the packages adopt it (e.g. one's own packages), which means even without signifant upstream adoption it will still be useful to individuals or organizations. +However, it's still useful even if only a subset of the packages adopt it (e.g. one's own packages), which means even without significant upstream adoption it will still be useful to individuals or organizations. Upstream packages that haven't adopted this simply won't benefit from it. Also, its usefulness hopefully outweighs the work required to implement it upstream, and it's certainly something that can be contributed by community members given that the interface would be reviewed by the experts in the package. From ef5018b583659f44bea503763d30b0c19a3818ef Mon Sep 17 00:00:00 2001 From: Jeremie Deray Date: Mon, 6 Jan 2020 17:31:30 -0500 Subject: [PATCH 19/22] flesh a little more other motiv Fleshing a little more the 'Other motivations' section --- articles/ros_node_idl.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/articles/ros_node_idl.md b/articles/ros_node_idl.md index 4abf2a97d..f79ad1213 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros_node_idl.md @@ -70,8 +70,20 @@ If ROS 2 provided a way for upstream package authors to specify the interface re ### Other motivations Outside of security, there are several fascinating possibilities unlocked by having such an interface. + For example, consider how this could impact [ROS 2 launch][launch_ros]. -It would be able to statically (i.e. before running anything) determine if parameter names or remappings are incorrect, among other similar sanity checks. +Benefiting from the declared interface(s), it would be able to execute many kind of static assertions (i.e. at launch-time, before running anything) upon the whole system to be launched. +Such assertions could include: +- Check for duplicates. +- Check for multiple publishers on a single topic. +- Check for message type mismatch. +- Check for qos mismatch. +- Check for orphan connections (e.g. a listener is connected to a topic with no publisher). +- Determine if remappings are incorrect. +- Determine if parameter names are incorrect. + +These assertions results would then be summarized in a logging file for later debugging. + Another example of the usefulness of having a static interface is the ability to create graphical tools for putting a ROS system together. Yet another example would be an additional feature in `ros2 pkg create` that would allow a developer to hand it an IDL and have it generate scaffolding for a node with that interface. From 364262376f1afdd17608e7f3a5fa0ddafdc127f9 Mon Sep 17 00:00:00 2001 From: Jeremie Deray Date: Tue, 28 Jan 2020 12:16:45 -0500 Subject: [PATCH 20/22] Fix typo --- articles/ros2_node_idl/interface_declaration.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/articles/ros2_node_idl/interface_declaration.xml b/articles/ros2_node_idl/interface_declaration.xml index 8a904898a..d2bf57934 100644 --- a/articles/ros2_node_idl/interface_declaration.xml +++ b/articles/ros2_node_idl/interface_declaration.xml @@ -19,7 +19,7 @@ avoid_ros_namespace_conventions="false" /> - + ``` From 83a47153322d9ada861d7681b57d10ecba086b37 Mon Sep 17 00:00:00 2001 From: Ted Kern Date: Thu, 9 Jul 2020 09:19:48 -0700 Subject: [PATCH 21/22] change Node IDL to NoDL, update specification and usage instructions based on implementation Signed-off-by: Ted Kern --- .../ros2_node_idl/interface_declaration.xml | 25 ---- articles/ros2_node_idl/package.xml | 10 -- articles/{ros_node_idl.md => ros2_nodl.md} | 108 ++++++++---------- articles/ros2_nodl/interface_declaration.xml | 16 +++ 4 files changed, 66 insertions(+), 93 deletions(-) delete mode 100644 articles/ros2_node_idl/interface_declaration.xml delete mode 100644 articles/ros2_node_idl/package.xml rename articles/{ros_node_idl.md => ros2_nodl.md} (67%) create mode 100644 articles/ros2_nodl/interface_declaration.xml diff --git a/articles/ros2_node_idl/interface_declaration.xml b/articles/ros2_node_idl/interface_declaration.xml deleted file mode 100644 index d2bf57934..000000000 --- a/articles/ros2_node_idl/interface_declaration.xml +++ /dev/null @@ -1,25 +0,0 @@ -```xml - - - - - - - - - - - - - - - -``` diff --git a/articles/ros2_node_idl/package.xml b/articles/ros2_node_idl/package.xml deleted file mode 100644 index ecff5431c..000000000 --- a/articles/ros2_node_idl/package.xml +++ /dev/null @@ -1,10 +0,0 @@ -```xml - - example-package - - - - - - -``` diff --git a/articles/ros_node_idl.md b/articles/ros2_nodl.md similarity index 67% rename from articles/ros_node_idl.md rename to articles/ros2_nodl.md index f79ad1213..75495f492 100644 --- a/articles/ros_node_idl.md +++ b/articles/ros2_nodl.md @@ -1,12 +1,13 @@ --- layout: default -title: ROS 2 Node Interface Definition Language -permalink: articles/ros2_node_interface_definition_language.html +title: ROS 2 Node Definition Language +permalink: articles/ros2_node_definition_language.html abstract: - This article specifies the ROS 2 Interface Definition Language, a simple and standardized manner to export the complete interface (action/message/parameter/service) of node(s) in a package. + This article specifies the ROS 2 Node Definition Language, a simple and standardized manner to export the complete interface (action/message/parameter/service) of node(s) in a package. author: > [Jérémie Deray](https://github.com/artivis), [Kyle Fazzari](https://github.com/kyrofa) + [Ted Kern](https://github.com/arnatious) published: true categories: Interfaces --- @@ -38,13 +39,13 @@ While it is usually readily available to a developer looking at the code, it can It therefore calls for the creation of a standardized way to explicitly define and export this information. This article defines a high-level abstraction allowing upstream packages to specify the communication requirements of the nodes in the package, such that the final user, be it a developer or a static analysis tool, can benefit from it. -The Interface Definition Language (IDL) specified in the next section is meant to be distributed alongside its associated package, be it in the source code or a generated release packaging format (e.g. debian). -Whether the interface is declared or not is up to the package author and should not prevent the correct execution of any system pre-existing the IDL. +The Node Definition Language (NoDL) specified in the next section is meant to be distributed alongside its associated package, be it in the source code or a generated release packaging format (e.g. debian). +Whether the interface is declared or not is up to the package author and should not prevent the correct execution of any system pre-existing the NoDL. Similarly, the declared interface may be only partial and allow for the full use of pre-existing systems and the use of dependent systems on the parts covered by the partial interface. ## Motivation -While initially being approached from a ROS 2 Security perspective, the abstraction level of the IDL allows for the developments of other functionalities and tools. +While initially being approached from a ROS 2 Security perspective, the abstraction level of the NoDL allows for the developments of other functionalities and tools. ### Security motivation @@ -85,7 +86,7 @@ Such assertions could include: These assertions results would then be summarized in a logging file for later debugging. Another example of the usefulness of having a static interface is the ability to create graphical tools for putting a ROS system together. -Yet another example would be an additional feature in `ros2 pkg create` that would allow a developer to hand it an IDL and have it generate scaffolding for a node with that interface. +Yet another example would be an additional feature in `ros2 pkg create` that would allow a developer to hand it a NoDL and have it generate scaffolding for a node with that interface. These examples are only a subset of use-cases made possible by such an interface. It's clear that this is useful well beyond security. @@ -113,43 +114,63 @@ Another is the fact that, as soon as the node is running, RCL itself (or another How do upstream packages specify their interface requirements? Through a high-level description of all the actions, parameters, services and topics, provided or required, by each node within the package. -The package interface is defined in a separate [XML][xml_wiki] file and exported from the `package.xml` using [REP 149's export mechanism][rep149_export], thereby avoiding pollution of the package manifest. +The package interface is defined in a separate [XML][xml_wiki] file with suffix `.nodl.xml`. +This XML file is exported to the [ament index][ament_index], either manually in the case of python projects or with a helper CMake macro. The interface may cover only a subset of nodes in a package, as long as the nodes that _are_ covered are done so completely. -Here is an example IDL for a package containing two nodes: +Here is an example NoDL for a package containing two nodes: -{% include_relative ros2_node_idl/interface_declaration.xml %} +{% include_relative ros2_nodl/interface_declaration.xml %} -Once an IDL file is written, it is exported from the package manifest: +Once an NoDL file is written, it is exported from either `CMakeLists.txt` or `setup.py` (more details below). +Note that several NoDL files can be exported, allowing for writing one NoDL file per node if desired. -{% include_relative ros2_node_idl/package.xml %} +### Exporting a NoDL to the Ament Index -Note that several IDL files can be exported, allowing for writing an IDL file per node. +Per the design philosophy of the [ament index][ament_index], files will be installed in two locations. +In the case of a package named `Foo`, the NoDL file `foo.nodl.xml` should be placed in the package share directory, `share/foo/foo.nodl.xml`. +A corresponding marker file, `share/ament_index/nodl_desc/foo`, should be created. +It is either empty or contains the relative path to the `foo.nodl.xml` file. -### Schema for `package.xml`'s export tag +#### CMake Macro -#### `interface` +For packages using ament_cmake, the package `ament_nodl` provides the macro `nodl_export_node_description_file` which performs the export described in [Exporting a NoDL to the Ament Index](#exporting-a-nodl-to-the-ament-index). -This is how the package exports its defined IDL for other tools to consume. +For a package `Foo`, containing `foo.nodl.xml`, the following lines are added to `CMakeLists.txt`: -Attributes: +```cmake +find_package(ament_nodl REQUIRED) +nodl_export_node_description_file(foo.nodl.xml) +``` -**path**: Path to XML file containing IDL +#### setup.py -Note that the introduction of the `interface` tag within the `export` tag of the package manifest raises a small difficulty with regards to the [REP 149][rep149_export]. -The REP specifies: +In the case of setup.py, placement of the NoDL file and marker in the index must be done manually alongside the placement of the package's marker in the ament index. +One can re-use the same empty marker file placed in the package index. +An example `data_files` argument to `setuptools.setup()` in `setup.py` follows: -> To avoid potential collisions, an export tag should have the same name as the package which is meant to process it. The content of that tag is up to the package to define and use. +```python + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/ament_index/resource_index/nodl_desc', + ['resource/' + package_name]), + ('share/' + package_name, + ['package.xml', package_name + '.nodl.xml']), + ], +``` -Considering the high level abstraction of the IDL, the `interface` tag is not meant for a specific package but rather declares intrinsic properties for anyone to process it. -However, the keyword is likely solidly descriptive enough to either be accepted as falling under [REP 149][rep149_export] or else to motivate an amendment of the REP. +### NoDL Schema -### IDL Schema +An `.xsd` xml schema is provided alongside the NoDL implementation. +This can be used to programmatically validate the NoDL's `.xml` document. +There are some semantics that cannot be expressed in this schema, so the the `.xsd` is not authoritative. +Rather, it is a heuristic, and the [NoDL reference implementation][nodl-reference] can reject a document that does not conform to other requirements. #### `interface` -Root tag of the IDL file, it is made up of a collection of node interfaces. -There must be only one tag per IDL file. +Root tag of the NoDL file, it is made up of a collection of node interfaces. +There must be only one tag per NoDL file. Attributes: - **version**: version of schema in use, allowing for future revisions. @@ -161,6 +182,7 @@ It is specific to a node as determined by its associated attributes. Attributes: - **name**: The base name of the node. +- **executable**: The name of the generated executable that contains the node. #### `action` @@ -175,10 +197,6 @@ Valid values are "true" or "false". Defaults to "false". - **client**: Whether or not the node provides a client for the action. Valid values are "true" or "false". Defaults to "false". -Sub-tag: -- **qos**: The Quality of Service setting for the action - see the [qos tag](####qos). -Defaults to [rcl_action_qos_profile_status_default][rcl_action_qos_profile_status_default_link] - #### `parameter` Define the interface for a given parameter. @@ -201,10 +219,6 @@ Valid values are "true" or "false". Defaults to "false". - **client**: Whether or not the node provides a client for the service. Valid values are "true" or "false". Defaults to "false". -Sub-tag: -- **qos**: The Quality of Service setting for the service - see the [qos tag](####qos). -Defaults to [rmw_qos_profile_services_default][rmw_qos_profile_services_default_link] - #### `topic` Define the interface for a given topic. @@ -218,32 +232,10 @@ Valid values are "true" or "false". Defaults to "false". - **subscription**: Whether or not the node subscribes to the topic. Valid values are "true" or "false". Defaults to "false". -Sub-tag: -- **qos**: The Quality of Service setting for the topic - see the [qos tag](####qos). -Defaults to [rmw_qos_profile_default][rmw_qos_profile_default_link] - -#### `qos` - -Define the quality of service. It reflects the qos parameters of the [rmw_qos_profile_t][rmw_qos_profile_t] structure. -This tag is a sub-element of either an action, a service or a topic. - -Attributes: -- **history**: The size of the message queue. -- **reliability**: The reliability QoS policy setting. -- **durability**: The durability QoS policy setting. -- **deadline**: The period at which messages are expected to be sent/received. -- **lifespan**: The age at which messages are considered expired and no longer valid. -- **liveliness**: Liveliness QoS policy setting. -- **liveliness_lease_duration**: The time within which the RMW node or publisher must show that it is alive. -- **avoid_ros_namespace_conventions**: If true, any ROS specific namespacing conventions will be circumvented. - [dds_security]: https://www.omg.org/spec/DDS-SECURITY/1.1/PDF [sros2_design]: /articles/ros2_dds_security.html [launch_ros]: https://github.com/ros2/launch_ros [xml_wiki]: https://en.wikipedia.org/wiki/xml -[rep149_export]: http://www.ros.org/reps/rep-0149.html#export -[rcl_action_qos_profile_status_default_link]: https://github.com/ros2/rcl/blob/master/rcl_action/include/rcl_action/default_qos.h -[rmw_qos_profile_services_default_link]: https://github.com/ros2/rmw/blob/master/rmw/include/rmw/qos_profiles.h#L64 -[rmw_qos_profile_default_link]: https://github.com/ros2/rmw/blob/master/rmw/include/rmw/qos_profiles.h#L51 -[rmw_qos_profile_t]: https://github.com/ros2/rmw/blob/master/rmw/include/rmw/types.h#L299 +[ament_index]: https://github.com/ament/ament_cmake/blob/master/ament_cmake_core/doc/resource_index.md#integration-with-other-systems +[nodl_reference]: https://github.com/ubuntu-robotics/nodl diff --git a/articles/ros2_nodl/interface_declaration.xml b/articles/ros2_nodl/interface_declaration.xml new file mode 100644 index 000000000..b0302b8cd --- /dev/null +++ b/articles/ros2_nodl/interface_declaration.xml @@ -0,0 +1,16 @@ +```xml + + + + + + + + + + + + + + +``` From 2a50c4495cb61286e110d3886047b41175d621b6 Mon Sep 17 00:00:00 2001 From: Ted Kern Date: Fri, 21 Aug 2020 11:48:54 -0700 Subject: [PATCH 22/22] add mention of role to nodl article (#4) --- articles/ros2_nodl.md | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/articles/ros2_nodl.md b/articles/ros2_nodl.md index 75495f492..10b07a030 100644 --- a/articles/ros2_nodl.md +++ b/articles/ros2_nodl.md @@ -192,10 +192,8 @@ Attributes: - **name**: The name of the action. - **type**: The type of the action. Valid values are any ROS action types. -- **server**: Whether or not the node provides an action server for the action. -Valid values are "true" or "false". Defaults to "false". -- **client**: Whether or not the node provides a client for the action. -Valid values are "true" or "false". Defaults to "false". +- **role**: The type of communication the node performs with this action. +Valid values are "server", "client", or "both". #### `parameter` @@ -214,10 +212,8 @@ Attributes: - **name**: The name of the service. - **type**: The type of the service. Valid values are any ROS service types. -- **server**: Whether or not the node provides a server for the service. -Valid values are "true" or "false". Defaults to "false". -- **client**: Whether or not the node provides a client for the service. -Valid values are "true" or "false". Defaults to "false". +- **role**: The type of communication the node performs with this service. +Valid values are "server", "client", or "both". #### `topic` @@ -227,10 +223,8 @@ Attributes: - **name**: The name of the topic. - **type**: The type of the message. Valid values are any ROS message types. -- **publisher**: Whether or not the node publishes on the topic. -Valid values are "true" or "false". Defaults to "false". -- **subscription**: Whether or not the node subscribes to the topic. -Valid values are "true" or "false". Defaults to "false". +- **role**: The type of communication the node performs on this topic. +Valid values are "publisher", "subscription", or "both". [dds_security]: https://www.omg.org/spec/DDS-SECURITY/1.1/PDF