Skip to content

Use Case 02: Waterfall

Waterfall is a educative use case with a simple concept and easy to reproduce. It was first deployed in the LocalSEA testbed of CEA List, then its components was dockerized using Docker to be able to test in other environments.


Description

Given a waterfall consisted of multiple stairs. When pouring the water into a stair, the water will go down stair-by-stair until the final one. The use case mimic the mechanism of the waterfall. Figure 1 illustrates this concept.

download
Figure 1. Illustration of the waterfall concept

There are five software components using five network protocols: CANopen, Modbus TCP, OPC UA FX, ROS 2, and EtherNet/IP Class 1, represent five stairs of the waterfall. When a trigger send a message to a stair, it will trigger its lower stair by sending a message to this lower one. For example, when the stair OPC UA FX is triggered, it will trigger the stair ROS 2; then, the stair ROS 2 will trigger the stair EtherNet/IP.

Deployment Instructions

Figure 2 shows the topology of the waterfall use case. There are seven components: the NPB, five components for five stair applications using the five protocols, and a component running as the trigger. The trigger and the five stairs connect to the NPB. All components are containerized into Docker images. To ease the deployment, the Docker images for both amd64 and arm64 are prepared in ROS6GBridge UC02 kit.

download
Figure 2. Topology of the waterfall use case

Note: The official version of this use case supports only four lastest stairs. The CAN Open stair will be put as a bonus.

This use case requires at least two devices, for example, one computer (amd64) and one Raspberry Pi (arm64). While the first device runs NPB and the trigger, the second runs the stairs. Figure 3 illustrates the AAS information model that is used to generate bridge NPB.

download
Figure 3. The AAS information model of bridge NPB

The four basic steps are as follows.

Step 1: Download and Load Docker files

User can download the ROS6GBridge UC02 kit, then extract it using the command:

$ unzip UC02_kit.zip

User need to copy all arm64 files (file with arm in name) to the device using architecture arm64. The other files are for amd64.

Each device needs to load its corresponding docker images. In this example, the computer load NPB and Trigger docker images:

$ docker load -i npb_brx_img.tar.gz
$ docker load -i pourer_mtcp_img.tar.gz

and the Raspberry Pi loads the docker images of stairs:

$ docker load -i stair_mtcp_img_arm.tar.gz
$ docker load -i stair_uafx_img_arm.tar.gz
$ docker load -i stair_ros2_img_arm.tar.gz
$ docker load -i stair_eip_img_arm.tar.gz

Step 2: Run Docker for stairs

Each stair may need a specific configuration to run properly.

a. Modbus TCP stair

Modbus TCP stair requires the address of NPB bridge as input. For example, the address of NPB bridge is 192.168.56.11. Run the following command:

$ docker run -it --net=host --rm stair_mtcp:0.2.arm /app 192.168.56.11

The expected successful output is Server MODBUSTCP: port 502 showing that the Modbus TCP stair is listening at port 502.

b. OPC UA FX stair

OPC UA FX stair requires the network interface that connect to the bridge as input. For example, the network interface is eth0. Run the following command:

$ docker run -it --net=host --cap-add=NET_ADMIN --rm stair_uafx:0.2.arm /app eth0

The expected successful output is Server OPC UA FX: port 4801 showing that the OPC UA FX stair is listening at port 4801.

c. ROS2 stair

ROS2 stair requires some input parameters. Run the following command:

$ docker run -it --net=host --rm stair_ros2:0.2.arm /bin/bash -c "export ROS_DOMAIN_ID=0 && source /opt/ros/humble/setup.bash && source /workspace/install/setup.bash && ros2 run stair led_waterfall"

The expected successful output is Server ROS2: ROS_DOMAIN_ID=0.

d. EtherNet/IP stair

EtherNet/IP stair requires the network interface that connect to the bridge as input. For example, the network interface is eth0. Run the following command:

$ docker run -it --net=host --rm stair_eip:0.2.arm /app eth0

The expected successful output is Server EtherNet/IP: port 2222 showing that the EtherNet/IP stair is listening at port 2222.

Step 3: Run NPB Docker

Users need to create a configuration file application.properties which is the input for the NPB Docker. In this example, the address of the Raspberry Pi is 192.168.56.13 and the network interface for the connection with it is eth0. The content of the file is as follows.

app.name=npb_brxfpga
app.version=v1.0
app.sdn.agent.interface=eth0
app.sdn.agent.endpoint=ws://192.168.56.11:8080
ros2.interface=eth0
ros2.domain.id=0
modbustcp.interface=eth0
modbustcp.endpoint=modbus-tcp://192.168.56.13:502
ethernetip.interface=eth0
ethernetip.endpoint=eip-tcp://192.168.56.13:44818
ethernetip.data.endpoint=eip-udp://192.168.56.13:2222
ethernetip.to.connection.point=100
ethernetip.to.elements.range=32
ethernetip.ot.connection.point=150
ethernetip.ot.elements.range=32
uafx.interface=eth0
uafx.multicast.endpoint=udp://224.0.0.1:4801

Run NPB bridge using the following command:

cat application.properties | docker run -i --rm --net=host --cap-add=NET_ADMIN npb_brx:0.4 bash -c "tee application.properties && java -jar app.jar"

The expected successful output is =========== BRx ON with errors displayed on the prompt.

Step 4: Trigger a stair

A stair can be triggered using Pourer Docker. The trigger needs three inputs which are:
- Address of the bridge: in this example, it is 192.168.56.11.
- Unit identifier of the stair: 41 (Modbus TCP), 96 (OPC UA FX), 31 (ROS2), or 60(EtherNet/IP).
- Value: 0 (false) or 1 (true).

Figure 4 shows the result after triggering the stair Modbus TCP with the following command:

$ docker run -it --net=host --rm pourer_mtcp:0.1 /app 192.168.56.11 41 1

download
Figure 4. Output when triggering stair Modbus TCP

Note: All stairs will be triggered once except stair EtherNet/IP which will be loop. The loop of this last stair can only be stopped by triggering it with the value False.

(Bonus) CANOpen SDO

CANOpen is a protocol for CAN bus. Thus, it does not work with Ethernet natively. To test a CAN bus communication, there are two solutions. First, it requires a module to convert from one socket type to CAN bus. For example, it is MCP2515 CAN Controller in the case of Raspberry Pi. Second, it is possible to use a software tunnel running in the two ends of the communication. In both cases, users must raise the vcan interface with the following commands:

$ sudo modprobe vcan
$ sudo ip link add dev vcan0 type vcan
$ sudo ip link set vcan0 mtu 16
$ sudo ip link set up vcan0

The following is content of tunnel.py running on the computer.

#!/usr/bin/python3

import can, socket, json
import threading
import signal
import os

def signal_handler(sig, frame):
  os._exit(0)

signal.signal(signal.SIGINT,signal_handler)

bus = can.interface.Bus(channel='vcan0', interface='socketcan')
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

SRC_PORT = 8811
SRC_ADDR = "0.0.0.0"
DES_PORT = 8813
DES_ADDR = "192.168.56.13"

def forward_data():
  while True:
    msg = bus.recv()
    data = json.dumps({'arbitration_id': msg.arbitration_id,
      'data': list(msg.data),'is_extended_id': msg.is_extended_id}).encode()
    sock.sendto(data, (DES_ADDR, DES_PORT))

thread = threading.Thread(target=forward_data)
thread.start()

sock.bind((SRC_ADDR, SRC_PORT))
while True:
  data, _ = sock.recvfrom(1024)
  msg_data = json.loads(data.decode())
  msg = can.Message(
    arbitration_id=msg_data['arbitration_id'],
    data=msg_data['data'],
    is_extended_id=msg_data['is_extended_id']
  )
  bus.send(msg)

Note: For the tunnel.py running on Raspberry Pi, it is necessary to change the values of SRC_PORT, DES_PORT, and DES_ADDR.

After establishing the CAN over Ethernet channel, the CAN data communication is ready. The CANOpen implemented in this test follows the simpliest CANOpen Service Data Object (SDO) mapping. Figure 5 illustrates the new AAS information model of bridge NPB including CANOpen. In detail, a new interface canopen and a new routing node brx_70_1_1 are added.

download
Figure 5. The AAS information model of bridge NPB with CANOpen

To ease the deployment, an amd64 Docker image for the bridge and a arm64 Docker image for stair CANOpen are prepared in ROS6GBridge UC02-b kit . Users can reuse other components to test with these two extensions. Figure 6 shows the result when triggering the stair CANOpen. with the following command:

$docker run -it --net=host --rm pourer_mtcp:0.1 /app 192.168.56.11 70 1

download
Figure 6. Output when triggering stair CANOpen

Note: This test requires fundamentally two stairs CANOpen and ModbusTCP.