Skip to content

Commit

Permalink
Merge pull request #905 from Fingerling42/master
Browse files Browse the repository at this point in the history
Added ROS 2 articles + updated artilce about launching collator
  • Loading branch information
zirreal authored Oct 17, 2024
2 parents a5edf5f + 86bb400 commit ff5e165
Show file tree
Hide file tree
Showing 10 changed files with 546 additions and 167 deletions.
17 changes: 15 additions & 2 deletions src/_data/sidebar_docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@
"url": "/docs/how-to-build-collator-node"
},
{
"title": "How to launch the Robonomics collator",
"title": "Launch of Robonomics Collator",
"url": "/docs/how-to-launch-the-robonomics-collator"
},
{
Expand All @@ -273,5 +273,18 @@
"url": "/docs/contributing"
}
]
},
{
"title": "Robotics and ROS 2",
"children": [
{
"title": "About Robonomics ROS 2 Wrapper",
"url": "/docs/ros2-about-wrapper"
},
{
"title": "Launch Robot from Cloud",
"url": "/docs/ros2-launch-robot-cloud"
}
]
}
]
]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
366 changes: 203 additions & 163 deletions src/docs/how-to-launch-the-robonomics-collator.md

Large diffs are not rendered by default.

78 changes: 78 additions & 0 deletions src/docs/ros2-about-wrapper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
title: About Robonomics ROS 2 Wrapper
contributors: [Fingerling42]
tools:
- Ubuntu 22.04.4
https://releases.ubuntu.com/jammy/
- ROS 2 Humble
https://docs.ros.org/en/humble/Installation.html
- IPFS Kubo 0.26.0
https://docs.ipfs.tech/install/command-line/
- Python 3.10.12
https://www.python.org/downloads/
---

**In this article, you will learn about the Robonomics ROS 2 Wrapper package, which allows you to use all the features of the Robonomics parachain for any ROS 2 compatible robot.**

The idea of ​​the package is to wrapping the Robonomics parachain API provided by [robonomics-interface](https://github.com/airalab/robonomics-interface) into nodes of ROS 2. The goal is to provide ROS 2 developers with a convenient way to integrate their robots or devices with parachain features. The logic behind the integration of a robotic device is that a unique address is created for it in the Robonomics parachain, which is used to control the device or receive its telemetry.

Available features include:

* **Launch function** — launching a device to execute any command with a specified set of parameters passed as a string or a file.
* **Datalog function** — publishing device telemetry in a form of hash to parachain.
* **Usage of Robonomics subscription** — the ability to send transactions without a fee.
* **Secure file storage** — to pack and unpack data, [InterPlanetary File System](https://ipfs.tech/) is used, which allows to access files by their unique hash. For convenient usage of IPFS, [Pinata](https://www.pinata.cloud/) support included, which allows to pin IPFS files for fast downloading.
* **File encryption and decryption** — protection of files with public key encryption.

Currently, the wrapper is available in [Python implementation](https://github.com/airalab/robonomics-ros2/).

## Wrapper Architecture

Architecturally, the wrapper consists of a worker node (with the necessary topics and services) and a basic node class that can be used for your specific robots.

{% roboWikiPicture {src:"docs/robotics/robonomics-ros2-wrapper.png", alt:"ROS 2 Wrapper Architecture"} %}{% endroboWikiPicture %}

* `robonomics_ros2_pubsub` — a unique node for each robot that serve as an entrance point to Web3. It wraps the services for sending datalogs and receiving launches via Robonomics and allows files to be downloaded/uploaded to IPFS. This node is configured by a special file, which is described below. A node's affiliation with a specific robot can be specified via the ROS namespace.
* `robonomics_ros2_robot_handler` — a robot-specific node based on a basic class `basic_robonomics_handler` for coordinating pubsub and the robot. It processes launches and decides when to send datalogs for controlling the robot.

## Installing the Wrapper

To work with the wrapper you need the following software:

* Linux OS distribution (usually, Ubuntu)
* ROS 2 distribution
* IPFS node
* Python 3 (for Python implementation of the wrapper)

Please follow the installation guide available [here](https://github.com/airalab/robonomics-ros2/?tab=readme-ov-file#getting-started) and check needed versions of the software. After downloading the required components, you will need [to build](https://github.com/airalab/robonomics-ros2/?tab=readme-ov-file#installation-and-building) the wrapper as a usual ROS 2 package using the `colcon` utility.

## Configuring Connections to Web3 Cloud

Before starting wrapper, you need to set up how exactly your robot will connect to the decentralized Robonomics cloud and supporting Web3 services. To do this, you need to edit the file a configuration file called `robonomics_pubsub_params_template.yaml`, which must be unique for each launched robot that needs to access Robonomics.

The file contains the following configuration fields:

| Field | Description |
|-----------------------|------------------------------------------------------------------------------------------------------------|
| account_seed | Account seed of Robonomics parachain |
| crypto_type | Type of your account, `ED25519` or `SR25519` |
| remote_node_url | Robonomics node url, default is `wss://kusama.rpc.robonomics.network`, for local node `ws://127.0.0.1:9944`|
| rws_owner_address | An address of Robonomics subscription owner to use RWS module |
| ipfs_dir_path | A path of directory to contain IPFS files |
| ipfs_gateway | IPFS gateway to download files, e.g. `https://ipfs.io` |
| pinata_api_key | API key from [Pinata](https://www.pinata.cloud/) pinning service for IPFS |
| pinata_api_secret_key | Secret API key from [Pinata](https://www.pinata.cloud/) pinning service for IPFS |

To create an account on the Robonomics parachain, please use [the following guide](https://wiki.robonomics.network/docs/create-account-in-dapp/) on our wiki. Please pay attention to the type of account you create, as accounts with SR25519 type cannot use file encryption.

{% roboWikiNote {type: "warning", title: "Warning"}%}

The seed phrase is sensitive information that allows anyone to use your account. Make sure you don't upload a config file with it to GitHub or anywhere else.

{% endroboWikiNote %}

Pay attention to the `remote_node_url` field, as it allows you to choose how exactly to connect to the Robonomics parachain, including locally. You can deploy your local Robonomics instance for testing and development. Instructions on how to do this are available in [this article](https://wiki.robonomics.network/docs/run-dev-node/) on our wiki.

If you have a Robonomics subscription that allows you to send transactions without fees, please insert the address of the subscription owner to the `rws_owner_address` field. Don't forget that your account must be added to your subscription. Instructions on how to activate your Robonomics subscription are available in two guides: via [Robonomics dapp](https://wiki.robonomics.network/docs/sub-activate/) with user-friendly interface or via [Robonomics Substrate portal](https://wiki.robonomics.network/docs/get-subscription/).

The `ipfs_gateway` parameter allows you to specify the gateway through which IPFS files will be downloaded. These can be either [public gateways](https://ipfs.github.io/public-gateway-checker/) or specialized private ones (for example, those obtained on Pinata)
247 changes: 247 additions & 0 deletions src/docs/ros2-launch-robot-cloud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
---
title: Launch Robot from Cloud
contributors: [Fingerling42]
tools:
- Robonomics ROS 2 Wrapper 3.1.0
https://github.com/airalab/robonomics-ros2/releases
---

**In this article, you will learn how to use the Robonomics launch function in ROS 2 through various examples**

The key feature of the Robonomics parachain for sending commands to devices is the launch extrinsic. This function allows you to send a string containing a parameter (in the form of 32-byte long hex value) to a specified address within the parachain. Typically, the string represents an IPFS hash that points to a file with the necessary parameters to execute the command. You can find more details about the launch function [in this article](https://wiki.robonomics.network/docs/launch/).

In the Robonomics ROS 2 Wrapper, the launch function is implemented as a service for sending commands and as a topic for receiving commands.

## Sending Launch

The service, called `robonomics/send_launch`, looks as follow:

{% codeHelper { additionalLine: "RobonomicsROS2SendLaunch.srv"}%}

```YAML
string param # Just param string or file name with parameters that need to be uploaded to IPFS
string target_address # Address to be triggered with launch
bool is_file True # Is a launch param a file that needs to be uploaded to IPFS (default is True)?
bool encrypt_status True # Check whether the parameter file needs to be encrypted with the target address, default is True
---
string launch_hash # Hash of the launch transaction
```

{% endcodeHelper %}

The service accepts the following parameters as part of the request: a command parameter (either a simple string or the name of a file containing the command parameters), the target address in the Robonomics parachain for sending the launch, and two flags: one indicating whether the parameter is a file, and the other specifying whether the file should be encrypted (both are set to true by default). The file will be uploaded to IPFS, and its hash will be passed as the launch parameter. Therefore, the file must be placed in the directory designated for IPFS files, as specified in the configuration file for the `robonomics_ros2_pubsub` node.

By default, the file is encrypted using the public address of the launch recipient. The encryption method applied is public-key encryption based on Curve25519 elliptic curve cryptography. In the current implementation, encryption is only supported for account addresses of the ED25519 (Edwards) type (you can read more about this in [this article](http://localhost:8080/docs/create-account-in-dapp/#22-create-account)).

After sending the launch, the service returns the transaction hash.

## Receiving Launch

Receiving launches is organized in the form of a corresponding topic. Technically, the node utilizes the robonomics-interface functionality to subscribe to the state of its own address and waits for the `NewLaunch` event to appear. Once the event occurs, the node publishes a message to the `robonomics/received_launch` topic. The message format is as follows:

{% codeHelper { additionalLine: "RobonomicsROS2ReceivedLaunch.msg"}%}

```YAML
string launch_sender_address # Address of account that sent launch command
string param # String with param or name of file with parameters
```

{% endcodeHelper %}

The message fields contain the address from which the launch was sent and the parameter itself: either a simple string or the name of the file with parameters that was downloaded from IPFS and placed in the IPFS working directory. If the file was encrypted, it is decrypted during this process.


## Example with Turtlesim

Next, we will demonstrate how to use the launch function with [Turtlesim](https://docs.ros.org/en/humble/Tutorials/Beginner-CLI-Tools/Introducing-Turtlesim/Introducing-Turtlesim.html) as an example. Turtlesim is a lightweight simulator designed for learning ROS 2. You can install it using the following command:

{% codeHelper { copy: true}%}

```shell
sudo apt install ros-$ROS_DISTRO-turtlesim
```

{% endcodeHelper %}

The Robonomics ROS 2 Wrapper package includes a pre-built package called `turtlesim_robonomics`, specifically adapted for Turtlesim. This package allows you to test all the features of the wrapper. Let's give it a try and run it.

{% roboWikiNote {type: "warning", title: "Warning"}%}

Please ensure that you have sufficient balance in your account or an active subscription to perform transactions.

{% endroboWikiNote %}

1. To begin, create a configuration file for the pubsub instance of `turtlesim_robonomics` using the `config/robonomics_pubsub_params_template.yaml` template. Fill in the appropriate fields with your Robonomics credentials (account seed, crypto type, subscription owner address). Also, specify a directory for IPFS files. Once completed, rename the file, for example, `first_pubsub_params.yaml`.

2. Launch IPFS Daemon:

{% codeHelper { copy: true}%}

```shell
ipfs daemon
```

{% endcodeHelper %}

3. Run the following ROS 2 launch file. It will start all the necessary nodes: Turtlesim itself, the wrapper implementation for Turtlesim, and the Robonomics pubsub:

{% codeHelper { copy: true}%}

```shell
ros2 launch turtlesim_robonomics turtlesim_robonomics_launch.py pubsub_params_path:=./first_pubsub_params.yaml namespace:='turtlesim1'
```

{% endcodeHelper %}

You will see the simulator with the turtle, along with ROS 2 logs in the console displaying the IPFS ID, the path to the directory with IPFS files, the Robonomics address, and other relevant information.

### Launch Turtlesim from Polkadot portal

1. Turtlesim is controlled via the `/cmd_vel` topic, so you need to prepare the corresponding messages and include them in a file, which will be used as the launch parameter. For convenience, these messages are prepared in a JSON file. Create a file (e.g., `turtle_cmd_vel.json`) and paste the following:

{% codeHelper { copy: true}%}

```json
[
{
"linear": {
"x": 5.0,
"y": 0.0,
"z": 0.0
},
"angular": {
"x": 0.0,
"y": 0.0,
"z": 1.5
}
},
{
"linear": {
"x": 2.0,
"y": 0.0,
"z": 0.0
},
"angular": {
"x": 0.0,
"y": 0.0,
"z": 2.5
}
}
]
```

{% endcodeHelper %}

This JSON example will command the turtle to move twice.

2. Next, the file needs to be uploaded to IPFS. You can choose any method, but for this example, we will use IPFS Kubo. Open a terminal in the directory where the JSON file is located and upload it to IPFS:

{% codeHelper { copy: true}%}

```shell
ipfs add turtle_cmd_vel.json
```

{% endcodeHelper %}

You will receive the IPFS hash of the file. Be sure to save it for later use.

3. Before sending the launch, the IPFS hash must be converted to a 32-byte long string. This can be done using a few Python commands. Open a terminal, launch the Python 3 interpreter, and run the following commands:

{% codeHelper { copy: true}%}

```python
from robonomicsinterface.utils import ipfs_qm_hash_to_32_bytes
ipfs_qm_hash_to_32_bytes('IPFS_FILE_HASH')
```

{% endcodeHelper %}

Save the resulting string for later use.

4. Open the Robonomics [Polkadot/Substrate portal](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fkusama.rpc.robonomics.network%2F#/extrinsics) and navigate to the **Developers** -> **Extrinsics** tab. Select the extrinsic `launch` -> `launch(robot, param)`. In the `robot` field, insert the address of your robot, and in the `param` field, insert the string with the converted IPFS hash. Submit the transaction.


5. Go to the Turtlesim simulator. After successfully sending the transaction, the turtle should begin moving.


### Launch Turtlesim from ROS 2 Command Line Tools

1. Now let's try to send a launch to Turtlesim from another ROS 2 pubsub node. First, create another configuration file (e.g., `second_pubsub_params.yaml`) with different Robonomics credentials and a separate IPFS directory.

2. In a separate terminal, run a new `robonomics_ros2_pubsub` node using the new configuration file:

{% codeHelper { copy: true}%}

```shell
ros2 run robonomics_ros2_pubsub robonomics_ros2_pubsub --ros-args -r __ns:=/test -p pubsub_params_path:=./second_pubsub_params.yaml
```

{% endcodeHelper %}

3. Place the JSON file containing the commands for Turtlesim (`turtle_cmd_vel.json`) into the IPFS directory of the new pubsub.

4. Before sending the launch, let's set up monitoring to observe how `turtlesim_robonomics` receives data upon arrival. To do this, in a separate terminal, subscribe to the corresponding topic:

{% codeHelper { copy: true}%}

```shell
ros2 topic echo /turtlesim1/robonomics/received_launch
```

{% endcodeHelper %}

{% roboWikiNote {type: "warning", title: "Launch Param as String"}%}

By default, the launch handler expects an IPFS hash of a file as a parameter. If you need the pubsub to handle the parameter as a regular string, you must change the corresponding ROS 2 node parameter `launch_is_ipfs` from `True` to `False`. You can do this using the command `ros2 param set`.

{% endroboWikiNote %}

5. Now, we need to call the ROS 2 service to send the launch. In a separate terminal, use the following command:

{% codeHelper { copy: true}%}

```shell
ros2 service call /test/robonomics/send_launch robonomics_ros2_interfaces/srv/RobonomicsROS2SendLaunch {"param: 'turtle_cmd_vel.json', target_address: 'YOUR_TURTLESIM_ADDRESS'"}
```

{% endcodeHelper %}

You will see the pubsub logs displaying details of the launch submission.

6. Go to the Turtlesim simulator. After successfully sending the transaction, the turtle should start moving. Additionally, in the logs of the subscribed topic, you should see information about the received data.


### Launch Turtlesim from Another Node

1. Now, let's try creating a test node that will wait for the launch to arrive and then forward it to Turtlesim. You can use the ready-made test package `test_robot_robonomics`. Copy this package to your ROS 2 workspace.

2. Open the node file located at `test_robot_robonomics/test_robot_robonomics/test_robot_robonomics_node.py` in any text editor, and add the following code after the `__init__` function:

{% codeHelper { copy: true}%}

```python
def launch_file_subscriber_callback(self, msg) -> None:
super().launch_file_subscriber_callback(msg)

transaction_hash = self.send_launch_request(self.param, target_address='YOUR_TURTLESIM_ADDRESS', is_file=True, encrypt_status=True)

self.get_logger().info('Sent launch to the turtle with hash: %s ' % str(transaction_hash))
```
{% endcodeHelper %}

This function will first process the received launch and then use its parameter to send a new launch to Turtlesim.

3. Build the package using `colcon`, and then source its setup files.

4. Run the ROS 2 launch file of the test package with the second pubsub credentials:

{% codeHelper { copy: true}%}

```shell
ros2 launch test_robot_robonomics test_robot_robonomics_launch.py pubsub_params_path:=./second_pubsub_params.yaml namespace:='test'
```

{% endcodeHelper %}

5. Now, send a launch with the `turtle_cmd_vel.json` parameters to the test node’s address, for example, via the Polkadot/Substrate portal. Before doing this, ensure that Turtlesim is still running. The test node should receive the launch and then send a new one with the same parameters, causing the turtle in Turtlesim to start moving.
5 changes: 3 additions & 2 deletions translations/pages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,5 +143,6 @@
"test": "test",
"Robotics and ROS 2": "Robotics and ROS 2",
"About Robonomics ROS 2 Wrapper": "About Robonomics ROS 2 Wrapper",
"Launch Robot from Cloud": "Launch Robot from Cloud"
}
"Launch Robot from Cloud": "Launch Robot from Cloud",
"Launch of Robonomics Collator": "Launch of Robonomics Collator"
}

0 comments on commit ff5e165

Please sign in to comment.