-
Notifications
You must be signed in to change notification settings - Fork 122
The Robot Server Protocol
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.
The protocol itself is intended to be generic for different types of 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 on the robot, the protocol is based on http long polling rfc6202).
The robot sends a request to the server (we call it a push request), which
- will be answered after a period of time by the server with a notification, if nothing has to be done. In this case the robot should issue the same request immediately.
- at specific events, that occur server-side, e.g. a program to be transferred is available. This keeps the whole system responsive, without demanding too many resources on server side. Based on commands, that the server returns, the robot knows what to do next.
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 in an JSONObject. A hex-file is embedded in the JSONObject as binary content.
Relevant server REST interfaces:
- /rest/pushcmd (controlling the workflow of the system)
- /rest/download (the user program can be downloaded here)
- /rest/update/ (updates for libraries on the robot can be downloaded here)
We will include the version number in the rest services in the near future like this:
- /rest/<version>/pushcmd (controlling the workflow of the system)
The most important thing in this system is to identify, which robot belongs to which web client. In order to do so, we use a "token". This code consists of of random numbers 0-9 and characters a-z. This token is generated by the robot or by the helper program and is displayed to the user on a screen. The user has to enter this code on the client page, before he is able to run programs from Open Roberta Lab. The client and the robot are then "linked together" on server side by using the token as a unique identifier.
The robot and the server are using JsonObjects to exchange information. An example:
{
"firmwarename":"lejos",
"robot":"robotName",
"macaddr":"74-DA-38-28-9F-A6",
"cmd":"register",
"firmwareversion":"0.9.0-beta",
"token":"AMKAQM23",
"brickname":"EV3",
"battery":"8.4",
"menuversion":"1.3.0",
"nepoexitvalue":0"
}
Note: It turns out that these information are not general enough for different robot types. Please suggest more fields or different field names to better describe the robot system. We want to make some changes in the protocol in Version 2.0 anyway.
This JsonObject will stay the same for almost all POST requests. Only the fields "cmd" and obviously "battery" will change. The "cmd" field tells the server, that a new robot wants to connect to Open Roberta. For example, the field "lejos" from "firmwarename" will tell the code generator, which programming language the NEPO blocks should be translated to (in the case of lejos it is Java). All of these fields are mandatory. If any fields are missing in the JsonObject, the server will provoke an error and it will throw away the request.
These keywords are the base for controlling the workflow of the distributed system. By agreeing on this set of commands, we make sure that the system will always work "the same" for different robot types. From robot to server
- register
- push
From server to robot
- repeat
- abort
- update
- download
- (configuration) not yet used
By using the command "register in the "cmd" field in the JsonObject, the server will hold the connection for approximately 5 minutes. In this time, the user has to enter the token on the web page to pair the client with the robot. In case of success, the server will return a JsonObject with "repeat" in the "cmd" field. Otherwise, if no one types in the token within five minutes, the server will answer the request from the robot by returning "abort". The robot can reuse this token trying to connect again or it generates a new one.
If the registration was successful and the robot receives a "repeat" from the server, the robot will send the very same JsonObject from the registration again to the server. However, the "cmd" field's value is now "push". This basically is a notification, that the robot is still alive and online. The push request will be answered by the server roughly every 10 seconds with a "repeat". Keep in mind, if the name of the robot or the battery voltage changes, the fields in the JsonObject should also be updated, therefor the server will always receive up-to-date informations.
As already stated, responsiveness of the system is very important. The user should be able to run the program on the robot just by clicking the "run" button on the web page. By doing so, the server will answer the pending push request immediately by sending the command "download" instead of "repeat". This induces the robot to download the program from the server by sending a push request ("push" command) to the/rest/download rest interface. The file is transfered as binary content, the file name is set in the header field "Filename". After downloading the file, the program is executed immediately.
Important: While running a user program on the robot, there is no communication (push requests) between the robot and the server. This is sufficient, because in case of an USB connection, it is disconnected anyway to let the robot move. The push requests will continue as normal after plugging in the cable again (and if the program is finished of course). The server considers the robot as "running the program" for a very 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 but the following one is missing, the brick is considered as offline/ disconnected after several seconds by the server. In case of heavy lagspikes in the network, it can occur, that the robot loses the connection to Open Roberta Lab. There is no explicit disconnect function needed. Disconnecting the robot after downloading the user program: The server will consider the robot as running a program for a long time. This state does not change until the next push request arrives.
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 user decides to update the firmware, the server answers the push request with an "update" command. This issues the robot to download all files from /rest/update/. At this point, the robot is no longer connected to Open Roberta Lab. To download the files, http GET method is used. The robot does not need to send any information about itself for downloading the files. The filename is available in the header field "Filename". 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.
There is a new field nepoexitvalue in the push protocol, which provides informations about running nepo programs, especially if they fail to execute:
- 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 the first time. How to react on different exit codes must be programmed in the javascript client (e. g. popup for the user with a message).
Because of firewall restrictions of routers and operating system, it is important that the connection is initiated from the "correct" side. For example, the server will not be able to access a robot device which is behind a router (unless you manually open some ports). Therefor it is important to let the robot initiate the connection. If there are helper programs for USB on Windows, similar thinks have to be kept in mind. In case of helper programs for USB, it is a good idea to have some robot test requests, to check, if a program is currently running or not. This kind of functionality can be used specifically for individual robot systems. Our Lego EV3 firmware (based on leJOS as well as ev3dev) both are using a network emulation for the USB connection. This enables the use of Http connections via USB to keep it "high level" and simple.
In addition ev3@lejos 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.
Home | Community | Installation | Team
Installation Tutorials
- Instructions to run a openroberta lab server using DOCKER
- Instructions to run the Open Roberta Lab Server natively on ubuntu ‐ not recommended
- Raspberry Pi 2/3/4 and the Open Roberta Lab
- EV3 and leJOS
- EV3 and ev3dev
- Creating the OR leJOS image
- Arduino Create Agent
- Mbed DAL: Generation and automation
Development
-
Workflows
-
Architecture
-
Blockly
-
Software engineering issues
-
Misc
-
Notes on robots
Textual Representation
Contribution
Discussions on future development