Skip to content

The Robot Server Protocol

Reinhard Budde edited this page May 22, 2024 · 15 revisions

Introduction

Robot refers in his text to both robots (as the ev3) and embedded systems (as calliope). After the user created a program and compiled it, it must be transferred to the robot. The lab supports a lot of transfer methods:

  • if the robot can be mounted as a USB device and can be seen as a storage device, i.e. it supports the USB mass storage class (e.g. calliopev3), the hex-file can be returned by the server as a file and using the ''save as''-dialog of the browser it can be transferred to the robot.

  • if the robot can be mounted as a USB device and supports WEBUSB, i.e. follows guidelines as described for instance in how WEBUSB works (e.g. calliopev3), the hex file can be returned by the server as a file and using WEBUSB capabilities of a browser, it can be transferred directly to the robot. https only!

  • if the robot can be mounted as a USB device and the two techniques mentioned above are not appropriate, the ''openroberta connector'' can be installed locally and run. The connector connects to both the robot and the lab server and handles the hex-file transfer (e.g. arduinos). To achieve this, a token generated by the openroberta connector must be presented by the user to the lab to achieve the connection.

  • if the robot supports WLAN, it can connect directly to the openroberta lab. This is the best way to communicate, but only a few robots supports this (e.g. ev3, TXT4). The robot-lab-communication is based on a simple protocol. This protocol is described in this text.

Overview about the protocol

The protocol itself is intended to be generic for many robots. If you have suggestions for improvements in this area, feel free to contact me, so we can discuss it.

To not require any "push"- technology from the robot side, the protocol is based on long polling rfc6202).

First the robot has to identify itself. This is done once. We call this the identify command. After identification the robot sends one request after the other to the server (we call this a push command). The server returns a response:

  • after a period of time (say 5 seconds) with a ''repeat'' notification, that nothing has happened at server side. In this case the robot should issue the same push command again. The robot knows, that the server is alive (at least for the last seconds).
  • if a hex-file to be transferred to the robot is made available by the user, the server returns a ''download'' notification. This instructs the robot, to download the hex-file and execute it.

This keeps the whole system responsive, without demanding too many resources on server side.

The request from the robot can be either http or https using the POST method. To make information easy to process, the data is encoded as an JSONObject. A hex-file is transferred as octet-stream.

The identify command as issued by the robot

  • REST endpoint is /rest/pushcmd, method is POST

  • the payload is a JSONObject consisting of the required fields (with an example value):

{
  "cmd":"register",
  "token":"AMKAQM23"
}

Some optional fields are described in a section of its own. Usually they are not used by the robot. The payload of the server respone is a JSONObject described in a section of its own.

The identify command must be the first command issued by the robot. The robot must generate a token. The token consists of 8 numbers 0-9 and characters a-z. This token must be presented to the user by the robot. When the identify-command hits the server, the server will put the token into a wait list. Later the user may write this token into the form activated when the menu entry ''verbinden''/''connect'' is clicked. As a result, the client and the robot are "linked together" on server side by using the token as a unique identifier.

If the user doesn't supply the token for a given period (about 5 minutes), the token expires.

The identification of the robot is successful, if the server returns the payload {"response":"ok","cmd":"repeat"}. In this case the robot should issue an endless sequence of push commands.

The push command as issued by the robot

  • REST endpoint is /rest/pushcmd, method is POST

  • the payload is a JSONObject consisting of the required field (with an example value):

{
  "cmd":"push",
  "token":"AMKAQM23"
}

Some optional fields are described in a section of its own. Usually they are not used by the robot. The payload of the server respone is a JSONObject described in a section of its own.

When the push commands hits the server, the server knows, whether the user has generated a program to be uploaded to the robot or not.

  • if nothing is to do, the server returns a response with a JSNObject. It will be {"response":"ok","cmd":"repeat"}. Now the next push command from the robot is expected after some time (say 5 seconds).
  • if a program is to execute, the server returns a response with a JSNObject. It will be {"response":"ok","cmd":"download"}. Now a download command from the robot is expected.

The download command as issued by the robot

  • REST endpoint is /rest/download, method is POST

  • the payload is a JSONObject consisting of the required field (with an example value):

{
  "cmd":"download",
  "token":"AMKAQM23"
}

Some optional fields are described in a section of its own. Usually they are not used by the robot.

The payload of the server respone is a application/octet-stream and consists of the bytes of the hex-file. The file name is set in the header field "Filename". The robot will execute the hex-file. If the programm terminates sometimes in the future, the robot issues the next push command.

The payload of a server response to the identify and push commands issued by the robot

The payload is a JSONObject consisting of the fields

{
  "response":"<<response>>",
  "cmd":"<<command>>"
}
  • <> is either "ok" or "error"
  • <> is either "repeat", "abort" or "download" with the obvious meaning. The commands "update" and "configuration" are not described here.

The (seldom used) optional fields of the JSONObject, that can be supplied by the robot

The optional fields (with an example value) are:

{
  "nepoexitvalue":"0",
  "firmwarename":"lejos",
  "firmwareversion":"0.9.1-beta",
  "robot":"ev3",
  "macaddr":"74-DA-38-28-9F-A6",
  "brickname":"myev3",
  "battery":"8.4",
  "menuversion":"1.3.0"
}

The ''nepoexitvalue'' is the most interesting field. The robot can use it to communicate whether the execution of a previously transferred program was successful (''0'') or not (value not equal ''0''). Values are:

  • 0: the program executed fine
  • 1: class loading error (lejos ev3)
  • 2: program execution error (NAO python)
  • ...
  • 143: program was killed from the ui This field is not mandatory for the registration but can be added later after a nepo program was executed. How to react on different exit codes must be programmed in the javascript client (e. g. popup for the user with a message).

Notes

While running a hex-file on the robot, there is no communication (push requests) between the robot and the server. This is ok, because the server considers the robot as "running the program" for a long time, until another push request arrives.

The push requests tell the server, that the robot is alive and connected to Open Roberta Lab. If a push request was answered by the server, but the no push command arrives for some time interval (about 10 sec), the robot is considered as offline/disconnected by the server. In case of heavy lagspikes in the network, it can occur, that the robot loses the connection to Open Roberta Lab and must be reconnected by a new identify command and a new token.

Updating firmware (not in use anymore, could be activated again if needed)

As development continues, most likely there are library and system updates for the robot. Because reinstalling the firmware (on a micro SD-card for example) is time consuming and not trivial, Open Roberta Lab is able to provide the necessary files as a download for the robot system. The version number of the robot is compared to the version number from the server everytime a new robot is connected to Open Roberta Lab by a token and before running a program. If the firmware needs to be updated, the server answers the push request with an "update" command. This issues the robot to download files from the/rest/update/ endpoint. At this point, the robot is not considered connected to Open Roberta Lab. To download the files, a request with method GET is used. The filename is available in the header field "Filename" of the response.

Usually, to take benefit of the new files, the robot system has to reboot or it has to restart some parts of the system (for example the menu on the EV3). After that, the robot is able to register with Open Roberta Lab again.

Sensor logging (not in use anymore)

This has been de-activated because it can create a huge load on the server. It should not be re-activated. It should be revised if used in the future. It is ev3-centric.

A robot can send sensor data either to a websocket or as a fallback to a special rest address. The sensor messages look like this:

{
  "token":"AMKAQM23",
  "1-<sensor-name>":"<value>",
  "2-<sensor-name>":"<value>",
  "A-<motor-name>":"<value>"
}

The fields starting with numbers are sensors, the fields starting with letters are motor positions for motors that can report them.

Clone this wiki locally