A collection of Node-RED nodes for connecting with ROS2.
npm install node-red-ros2-plugin
This project is part of DIH^2. The main goal is provide Node-RED interoperability with
ROS2 and FIWARE. The plugin introduces in the
Node-RED palette new nodes dealing with:
In order to transmit information it is necessary to precisely define the composition of the data delivered.
Node-RED approach is based on JSON which is versatile and user friendly
but cannot be used to interoperate with industrial protocols that require language-independent type Description.
In order to provide this interoperability ROS2 introduced IDL. Which is
a data type and interfaces descriptive language customary in industrial applications.
The new nodes make both: IDL type descriptions and well known ROS2 types available.
Publisher and Subscriber nodes are provided to directly access its ROS2
counterparts.
Different topics and QoS can be selected. Also a global configuration node allows to select the ROS domain to enforce.
The Context Broker doesn't provide a Publisher-Subscriber
interface (works more like a database) but a translation can be easily performed if:
- Entities are understood as topics.
- Creating or setting an entry is understood as publishing.
- Notification callbacks on an entity are understood as subscribtion callbacks.
- Background
- Install
- Usage
+ ROS2 nodes usage
+ ROS2 Examples
+ FIWARE nodes usage
+ FIWARE Examples
The interoperability between the plugin and the ROS2 and FIWARE Broker environments is achieved using WebSocket
bridges to them. This was the natural choice given that Node-RED relies on WebSocket for front-end/back-end
communication.
These bridges are generated using Integration-Service an
eProsima open-source tool.
Using Integration-Service directly from the plugin was possible, but it was considered a better choice to create another
Node.js library (is-web-api, to abstract the bridge operation. This way:
+ The plugin can rely on any other bridge technology.
+ Development is simplified by enforcing separation of concerns.
+ Any other Node.js project (besides the plugin) can profit from the bridge library.
A Dockerfile is provided to exemplify the set up on an argument provided ROS2 distro.
Some of the following installation steps can be skipped if the target system already fulfils some of the requirements:
1. ROS2 installation. Follow the official ROS2 installation guide
for the distro of choice. The Dockerfile is based on a ROS2 image, so this is not exemplified.
1. Install Node.js. The usual OS package managers (like apt on Ubuntu or winget/chocolatey on windows) provide it.
An exhaustive list is available here.
Some package managers constrain the user to a specific version of Node.js. The Node.js site
hints on how to install specific versions.
For example, in apt is possible to add via location configuration file a new remote repository where all Node.js
versions are available. This is the strategy that the Dockerfile uses:
``bash`
$ curl -sL https://deb.nodesource.com/setup_14.x -o nodesource_setup.sh
$ chmod +x nodesource_setup.sh && sudo sh -c ./nodesource_setup.sh
$ sudo apt-get install -y nodejs
npm
1. Install Node-RED. Follow the official Node-RED installation guide.
The Dockerfile favors the easiest procedure which relies on (default Node.js package manager) which is
available after Node.js installation step:
`bash`
$ npm install -g node-red
1. Install Integration-Service. Follow the Integration-Service installation manual.
This is exemplified in the Dockerfile, basically it is build from sources downloaded from github. Dependencies
associated with the build and bridge environments are required:
`bash
$ apt-get update
$ apt-get install -y libyaml-cpp-dev libboost-program-options-dev libwebsocketpp-dev \
libboost-system-dev libboost-dev libssl-dev libcurlpp-dev \
libasio-dev libcurl4-openssl-dev git
$ mkdir -p /is_ws/src && cd "$_"
$ git clone https://github.com/eProsima/Integration-Service.git is
$ git clone https://github.com/eProsima/WebSocket-SH.git
$ git clone https://github.com/eProsima/ROS2-SH.git
$ git clone https://github.com/eProsima/FIWARE-SH.git
$ . /opt/ros/humble/setup.sh # customize the ROS2 distro: foxy, galactic, humble ...
$ colcon build --cmake-args -DIS_ROS2_SH_MODE=DYNAMIC --install-base /opt/is
`
Note that it uses the ROS2 build tool: colcon
As ROS2 it is necessary to source and
overlay.
In order to simplify sourcing /opt/is was chosen as deployment dir. The overlay can be then sourced as:
`bash`
$ . /opt/is/setup.bash
It will automatically load the ROS2 overlay too. After the overlay is sourced it must be possible to access the
integration-service help as:
`bash`
$ integration-service --help
Once all the dependencies are available we can deploy the plugin via npm:
+ From npm repo:
`bash`
$ npm install -g node-red-ros2-plugin
npm
+ From sources. allows direct deployment from github repo:
`bash`
$ npm install -g https://github.com/eProsima/node-red-ros2-plugin
Or, as in the Dockerfile, from a local sources directory. The docker favors this approach to allow tampering with the
sources.
`bash
$ git clone https://github.com/eProsima/node-red-ros2-plugin.git plugin_sources
$ npm install -g ./plugin_sources
`
In order to test the plugin there are two options: follow the installation steps above or run the
test container provided here.
The main concepts associated with Node-RED operation are explained here.
The plugin nodes are displayed on the Node-RED palette as shown in the image. From there, they can be dragged into the
workspace.
The palette is the pane on the left where all available nodes are classified by sections. Plugin ones appear under ROS2FIWARE
and (figure's red frame). The worksplace is the central pane where different flows are associated to the upper tabs.
> _Note:_ the text that labels the node, changes from palette to workspace, and may change depending on the node
configuration.
In order the publish or subscribe data we need first to specify the associated type. The plugin provides two options:
#### Choosing a predefined ROS2 type
![]() | This node represents a specific ROS2 Builtin Type. Once in the workspace, its set up dialog can be opened by doble clicking over it. |
![]() | The dialog provides a Package drop-down control where all ROS2 msg packages are listed. Once a package is selected the Message drop-down control allows selection of a package specific message. In this example the package selected is geometry_msgs. From this package the Point message is selected. | ![]() | Once the dialog set up is saved, the node label changes to highligh the selected type in a package/message pattern. |
#### Defining a new type via IDL
![]() | This node represents a type defined by means of an IDL. IDL is a language that allows unambiguous specification of the interfaces that may be used to define the data types. |
![]() | The dialog provides an edit box where the desired IDL can be introduced Note that in order to use the type in ROS2 it must follow several conventions:
By default a dummy message that follows the above guidelines is provided. | ![]() | Once the dialog set up is saved, the node label changes to highligh the selected type in a package/message pattern. |
#### Injecting a type instance into the pipeline
Node-RED pipelines start in source nodes. The most popular one is the inject
node which requires the user to manually defined each field
associated to the type. In order to simplify this a specific node is introduced:

This node mimics the inject node behaviour but automatically populates the input dialog with the fields associated with
any type node linked to it. For example, if we wire together a ROS Inject and a ROS Type or IDL Type nodes as
shown in the figure:
![]() | ![]() |
![]() | ![]() |
The associated dialogs are populated with the linked type fields and types.
In order to interact with a ROS2 environment we must specify the same domain id
in use for that environment.
The domain id is a number in the range [0, 166] that provides isolation for ROS2 nodes.
It defaults to 0 and its main advantage is reduce the incomming traffic for each ROS2 node, discharging them and
speeding things up.
Another key concepts in the ROS2 environment are:
- topic
one. A topic is a text string ROS2 nodes use to notify all other nodes in which data they are interested.
When a ROS2 node wants to send or receive data it must specify:
+ Which type is the data they want receive. For example the geometry_msgs/Pose we introduced above./marker_pose
+ Topic associated with the data. For example , but in ROS2 topics are often decorated using/eProsima/buildings/E3g1/room/F2h3/marker/4Rg1/pose
namespaces to simplify identification, as in .
- Quality of Service (QoS). Those are
policies that allow fine tunning of the communication between nodes. For example:
+ History QoS allows to discard messages if only the most recent one is meaningful for our purposes.
+ Reliable QoS enforces message reception by resending it until the receiver acknowledges it.
+ Durability QoS assures messages published before the receiver node creation would be delivered.
> _Note:_ ROS2 nodes can only communicate if their respective QoS are compatible. Information on QoS compatibility
is available here.
#### ROS2 configuration node
A Node-RED config node is provided to set up the domain ID,
which is a global selection:
> _Note:_ The ROS2 default domain value is 0
#### ROS2 Publisher
![]() | This node represents a ROS2 publisher. It is able to publish messages on a specific topic with specific QoS |
![]() | The dialog provides controls to configure:
|
#### ROS2 Subscriber
![]() | This node represents a ROS2 subscriber. It is able to subscribe on a specific topic and receive all messages published for it. |
![]() | The dialog provides controls to configure:
|
#### ROS2 Basic Publication Example
Let's show how to use a custom type.
1. Launch docker compose as explained here.
1. Create and wire the following nodes:
+ An IDL Type node. Open the associated dialog and introduce the following idl:
`c`
module custom_msgs {
module msg {
struct Message {
string text;
uint64 value;
};
};
};
ROS Publisher
+ A node. Open the associated dialog and set up the publisher:
Topic
: hope
Domain
: 42
+ A ROS Inject node. Open the associated dialog and fill in the fields:
text
: Hello World!
value
: 42
1. Deploy the flow pressing the corresponding button. Once deployed, the custom type has been registered in the ROS2 distro.
1. Let's launch a subscriber from the
ROS2 cli.
`bash`
$ docker exec -ti --env ROS_DOMAIN_ID=42 docker-visual-ros-1 /ros_entrypoint.sh ros2 topic echo /hope custom_msgs/msg/Message
1. Now click on the inject node button within the editor and see how the terminal receives the data.
> _Note:_ In the example the ROS2 domain value selected is 42, different from the default value of 0.
#### ROS2 Basic Subscription Example
In this case, a builtin ROS2 type (geometry_msgs/Point) will be used.
1. Launch docker compose as explained here.
1. Create and wire the following nodes:
+ A ROS2 Type node. Open the associated dialog and select:
Package
: geometry_msgs
Message
: Point
+ A ROS2 Subscriber node. Open the associated dialog and set up the subscriber:
Topic
: hope
Domain
: 17
+ A debug node from the common palette section. Open the associated dialog and set it up to show the x
coordinate of the point:
Outputmsg.x
:
1. Deploy the flow pressing the corresponding button.
1. Publish a message on that topic from the ROS2 cli. In this example we launch a new container connected to the same
network using the standard ros:humble image.
`bash`
$ docker run --rm -ti --env ROS_DOMAIN_ID=17 --network docker_visualros ros:humble \
ros2 topic pub /hope geometry_msgs/msg/Point "{ x: 42, y: 0, z: 0 }"
#### ROS2 Mandatory Turtlesim Example
Turtlesim
is an ad hoc package that ROS2 provides as GUI node example.
##### Set up
Unlike the previous examples turtlesim cannot work on terminal mode. There are several ways to workaround this:
1. Run GUI application in a docker container as shown here.
1. Share the container network stack with the host.
1. Run Node-RED backend directly in your host (see installation steps).
Here we favour the second option as the most simple. This only requires:
+ A ROS2 installation in the host. Follow the official ROS2 installation guide
for the distro of choice.
+ Launch the Visual-ROS container sharing host network stack:
`bash`
node-red-ros2-plugin/docker$ docker build --build-arg ROS_DISTRO=humble -t visualros:humble .
$ docker run -ti --name turtledemo --network host --ipc host visualros:humble /node_entrypoint.sh node-red
##### Demo steps
1. Launch turtlesim on the host by doing:
`bash`
$ . /opt/ros/humble/setup.sh
$ ros2 run turtlesim turtlesim_node
A window should appear with a turtle in the middle.
1. Open a web browser on http://localhost:1880.
1. Create and wire the following nodes:
+ A ROS2 Type node. In the associated dialog set up the turtlesim pose type: geometry_msgs/Twist.ROS2 Inject
+ A couple of nodes: one to move the turtle forward and another to spin it.ROS2 Type
Wire both nodes to the . Open the associated dialogs and take into account that:linear.x = 1
- mover forward means angular.z = 1
- spin means ROS2 Publisher
+ A node. Wire it to the ROS2 Type node. Open the associated dialog and set up as:turtle/cmd_vel
- Topic the .
- Use the default ROS2 domain 0.
1. Click the Deploy button.
Now click on the inject nodes buttons within the editor and see how the turtle moves.
This json file can be imported to Node-RED in order to reproduce the flow.
The FIWARE Context Broker uses a REST API to
provide information. This interface do not exactly follows a Publisher/Subscriber model but can be adapted to do so:
- Broker entities are mapped as Publisher/Subscriber topics.
- Types are described using IDL which works as a subset of the NGSI type system.
#### FIWARE configuration node
A Node-RED config node is provided to set up the FIWARE
Context Broker IPv4 address which is a global selection.
#### FIWARE Publisher
![]() | This node represents a FIWARE publisher able to publish messages on a specific topic. |
![]() | The dialog provides controls to configure:
|
#### FIWARE Subscriber
![]() | This node represents a FIWARE subscriber. It is able to subscribe on a specific topic and receive all messages published for it. |
![]() | The dialog provides controls to configure:
|
#### FIWARE Basic Publication Example
Let's use a custom type.
1. Launch docker compose as explained here.
1. Create and wire the following nodes:
+ An IDL Type node. Open the associated dialog and introduce the following idl:
`c`
module custom_msgs {
module msg {
struct Message {
string text;
uint64 value;
};
};
};
FIWARE Publisher
+ A node. Open the associated dialog and set up the publisher:
Topic
: hope
Context Broker192.168.42.14:1026
:
Note the address and port of the Context Broker was specified in the compose.yaml file.
+ A ROS Inject node. Open the associated dialog and fill in the fields:
text
: Hello World!
value
: 42
1. Deploy the flow pressing the corresponding button.
1. Once deployed, click on the inject node button within the editor. The Context Broker should have created an entity
associated to the topic (hope) with the values provided in the inject node.
In order to check it, the FIWARE Context Broker can be directly queried using its REST API (note that in the
compose.yaml file the Context Broker port 1026 is mapped to the host machine). Open a console on the host and type:
`bash`
$ curl -G -X GET "http://localhost:1026/v2/entities" -d "type=custom_msgs::msg::Message" -d "id=hope"
It should return the following json:
`json`
[
{
"id": "hope",
"type": "custom_msgs::msg::Message",
"text": {
"type": "Text",
"value": "Hello World!",
"metadata": {}
},
"value": {
"type": "Number",
"value": 42,
"metadata": {}
}
}
]
#### FIWARE Basic Subscription Example
In this case, a builtin ROS2 type (geometry_msgs/Point) will be used.
1. Launch docker compose as explained here.
1. Create and wire the following nodes:
+ A ROS2 Type node. Open the associated dialog and select:
Package
: geometry_msgs
Message
: Point
+ A FIWARE Subscriber node. Open the associated dialog and set up the subscriber:
Topic
: position
Context Broker192.168.42.14:1026
:
+ A debug node from the common palette section. Open the associated dialog and set it up to show the x
coordinate of the point:
Outputmsg.x
:
1. Deploy the flow pressing the corresponding button.
1. Publish a message on that topic from the FIWARE REST API. Because the compose.yaml maps the FIWARE Context Broker
port to a host one (1026) is possible to reach it from the host machine.
Open a console on the host and type:
`bash`
$ curl http://localhost:1026/v2/entities -H 'Content-Type: application/json' -d @- <
"id": "position",
"type": "geometry_msgs::msg::Point",
"x": {"value": 42, "type":"Text"},
"y": {"value": 4, "type":"Text"},
"z": {"value": 2, "type":"Text"}
}
EOF
The debug pan should log an output. In order to update the entity value, further http queries should follow:
`bash``
$ curl -X PUT http://localhost:1026/v2/entities/position/attrs?type=geometry_msgs::msg::Point \
-H 'Content-Type: application/json' -d @- <
"x": {"value": 3, "type":"Text"},
"y": {"value": 2, "type":"Text"},
"z": {"value": 1, "type":"Text"}
}
EOF
*
![]()
This project (DIH² - A Pan‐European Network of Robotics DIHs for Agile Production) has received funding from the
European Union’s Horizon 2020 research and innovation programme under grant agreement No 824964