Skip to content

Commit f5f71f0

Browse files
author
Ted Kern
authored
Arnatious/nodl (#3)
change Node IDL to NoDL, update specification and usage instructions based on implementation Signed-off-by: Ted Kern <[email protected]>
1 parent 3642623 commit f5f71f0

File tree

4 files changed

+66
-93
lines changed

4 files changed

+66
-93
lines changed

articles/ros2_node_idl/interface_declaration.xml

Lines changed: 0 additions & 25 deletions
This file was deleted.

articles/ros2_node_idl/package.xml

Lines changed: 0 additions & 10 deletions
This file was deleted.

articles/ros_node_idl.md renamed to articles/ros2_nodl.md

Lines changed: 50 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
---
22
layout: default
3-
title: ROS 2 Node Interface Definition Language
4-
permalink: articles/ros2_node_interface_definition_language.html
3+
title: ROS 2 Node Definition Language
4+
permalink: articles/ros2_node_definition_language.html
55
abstract:
6-
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.
6+
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.
77
author: >
88
[Jérémie Deray](https://github.com/artivis),
99
[Kyle Fazzari](https://github.com/kyrofa)
10+
[Ted Kern](https://github.com/arnatious)
1011
published: true
1112
categories: Interfaces
1213
---
@@ -38,13 +39,13 @@ While it is usually readily available to a developer looking at the code, it can
3839
It therefore calls for the creation of a standardized way to explicitly define and export this information.
3940

4041
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.
41-
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).
42-
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.
42+
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).
43+
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.
4344
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.
4445

4546
## Motivation
4647

47-
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.
48+
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.
4849

4950
### Security motivation
5051

@@ -85,7 +86,7 @@ Such assertions could include:
8586
These assertions results would then be summarized in a logging file for later debugging.
8687

8788
Another example of the usefulness of having a static interface is the ability to create graphical tools for putting a ROS system together.
88-
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.
89+
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.
8990

9091
These examples are only a subset of use-cases made possible by such an interface.
9192
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
113114
How do upstream packages specify their interface requirements?
114115
Through a high-level description of all the actions, parameters, services and topics, provided or required, by each node within the package.
115116

116-
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.
117+
The package interface is defined in a separate [XML][xml_wiki] file with suffix `.nodl.xml`.
118+
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.
117119
The interface may cover only a subset of nodes in a package, as long as the nodes that _are_ covered are done so completely.
118120

119-
Here is an example IDL for a package containing two nodes:
121+
Here is an example NoDL for a package containing two nodes:
120122

121-
{% include_relative ros2_node_idl/interface_declaration.xml %}
123+
{% include_relative ros2_nodl/interface_declaration.xml %}
122124

123-
Once an IDL file is written, it is exported from the package manifest:
125+
Once an NoDL file is written, it is exported from either `CMakeLists.txt` or `setup.py` (more details below).
126+
Note that several NoDL files can be exported, allowing for writing one NoDL file per node if desired.
124127

125-
{% include_relative ros2_node_idl/package.xml %}
128+
### Exporting a NoDL to the Ament Index
126129

127-
Note that several IDL files can be exported, allowing for writing an IDL file per node.
130+
Per the design philosophy of the [ament index][ament_index], files will be installed in two locations.
131+
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`.
132+
A corresponding marker file, `share/ament_index/nodl_desc/foo`, should be created.
133+
It is either empty or contains the relative path to the `foo.nodl.xml` file.
128134

129-
### Schema for `package.xml`'s export tag
135+
#### CMake Macro
130136

131-
#### `interface`
137+
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).
132138

133-
This is how the package exports its defined IDL for other tools to consume.
139+
For a package `Foo`, containing `foo.nodl.xml`, the following lines are added to `CMakeLists.txt`:
134140

135-
Attributes:
141+
```cmake
142+
find_package(ament_nodl REQUIRED)
143+
nodl_export_node_description_file(foo.nodl.xml)
144+
```
136145

137-
**path**: Path to XML file containing IDL
146+
#### setup.py
138147

139-
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].
140-
The REP specifies:
148+
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.
149+
One can re-use the same empty marker file placed in the package index.
150+
An example `data_files` argument to `setuptools.setup()` in `setup.py` follows:
141151

142-
> 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.
152+
```python
153+
data_files=[
154+
('share/ament_index/resource_index/packages',
155+
['resource/' + package_name]),
156+
('share/ament_index/resource_index/nodl_desc',
157+
['resource/' + package_name]),
158+
('share/' + package_name,
159+
['package.xml', package_name + '.nodl.xml']),
160+
],
161+
```
143162

144-
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.
145-
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.
163+
### NoDL Schema
146164

147-
### IDL Schema
165+
An `.xsd` xml schema is provided alongside the NoDL implementation.
166+
This can be used to programmatically validate the NoDL's `.xml` document.
167+
There are some semantics that cannot be expressed in this schema, so the the `.xsd` is not authoritative.
168+
Rather, it is a heuristic, and the [NoDL reference implementation][nodl-reference] can reject a document that does not conform to other requirements.
148169

149170
#### `interface`
150171

151-
Root tag of the IDL file, it is made up of a collection of node interfaces.
152-
There must be only one tag per IDL file.
172+
Root tag of the NoDL file, it is made up of a collection of node interfaces.
173+
There must be only one tag per NoDL file.
153174

154175
Attributes:
155176
- **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.
161182

162183
Attributes:
163184
- **name**: The base name of the node.
185+
- **executable**: The name of the generated executable that contains the node.
164186

165187
#### `action`
166188

@@ -175,10 +197,6 @@ Valid values are "true" or "false". Defaults to "false".
175197
- **client**: Whether or not the node provides a client for the action.
176198
Valid values are "true" or "false". Defaults to "false".
177199

178-
Sub-tag:
179-
- **qos**: The Quality of Service setting for the action - see the [qos tag](####qos).
180-
Defaults to [rcl_action_qos_profile_status_default][rcl_action_qos_profile_status_default_link]
181-
182200
#### `parameter`
183201

184202
Define the interface for a given parameter.
@@ -201,10 +219,6 @@ Valid values are "true" or "false". Defaults to "false".
201219
- **client**: Whether or not the node provides a client for the service.
202220
Valid values are "true" or "false". Defaults to "false".
203221

204-
Sub-tag:
205-
- **qos**: The Quality of Service setting for the service - see the [qos tag](####qos).
206-
Defaults to [rmw_qos_profile_services_default][rmw_qos_profile_services_default_link]
207-
208222
#### `topic`
209223

210224
Define the interface for a given topic.
@@ -218,32 +232,10 @@ Valid values are "true" or "false". Defaults to "false".
218232
- **subscription**: Whether or not the node subscribes to the topic.
219233
Valid values are "true" or "false". Defaults to "false".
220234

221-
Sub-tag:
222-
- **qos**: The Quality of Service setting for the topic - see the [qos tag](####qos).
223-
Defaults to [rmw_qos_profile_default][rmw_qos_profile_default_link]
224-
225-
#### `qos`
226-
227-
Define the quality of service. It reflects the qos parameters of the [rmw_qos_profile_t][rmw_qos_profile_t] structure.
228-
This tag is a sub-element of either an action, a service or a topic.
229-
230-
Attributes:
231-
- **history**: The size of the message queue.
232-
- **reliability**: The reliability QoS policy setting.
233-
- **durability**: The durability QoS policy setting.
234-
- **deadline**: The period at which messages are expected to be sent/received.
235-
- **lifespan**: The age at which messages are considered expired and no longer valid.
236-
- **liveliness**: Liveliness QoS policy setting.
237-
- **liveliness_lease_duration**: The time within which the RMW node or publisher must show that it is alive.
238-
- **avoid_ros_namespace_conventions**: If true, any ROS specific namespacing conventions will be circumvented.
239-
240235

241236
[dds_security]: https://www.omg.org/spec/DDS-SECURITY/1.1/PDF
242237
[sros2_design]: /articles/ros2_dds_security.html
243238
[launch_ros]: https://github.com/ros2/launch_ros
244239
[xml_wiki]: https://en.wikipedia.org/wiki/xml
245-
[rep149_export]: http://www.ros.org/reps/rep-0149.html#export
246-
[rcl_action_qos_profile_status_default_link]: https://github.com/ros2/rcl/blob/master/rcl_action/include/rcl_action/default_qos.h
247-
[rmw_qos_profile_services_default_link]: https://github.com/ros2/rmw/blob/master/rmw/include/rmw/qos_profiles.h#L64
248-
[rmw_qos_profile_default_link]: https://github.com/ros2/rmw/blob/master/rmw/include/rmw/qos_profiles.h#L51
249-
[rmw_qos_profile_t]: https://github.com/ros2/rmw/blob/master/rmw/include/rmw/types.h#L299
240+
[ament_index]: https://github.com/ament/ament_cmake/blob/master/ament_cmake_core/doc/resource_index.md#integration-with-other-systems
241+
[nodl_reference]: https://github.com/ubuntu-robotics/nodl
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
```xml
2+
<interface version="1">
3+
<node name="node_1" executable="first">
4+
<parameter name="verbose" type="bool" />
5+
<topic name="chatter" type="std_msgs/msg/String" role="publisher" />
6+
</node>
7+
8+
<node name="node_2" executable="second">
9+
<parameter name="rate" type="int" />
10+
<topic name="/foo/bar" type="std_msgs/msg/String" role="subscription" />
11+
<service name="/example_service" type="std_srvs/srv/Empty" role="client" />
12+
<service name="/example_service_2" type="std_srvs/srv/Empty" role="server" />
13+
<action name="/example_action" type="example_interfaces/action/Fibonacci" role="both" />
14+
</node>
15+
</interface>
16+
```

0 commit comments

Comments
 (0)