Dorna API Quick Start


This guide will help you get up and running with your new Dorna robot using the Python API. You can find find more detail on the Dorna API here.

Installation


There are two ways of getting the current Dorna API: from PyPi or GitHub.

PyPi

To install the package from the PyPI server, use the pip command in command line:

pip install dorna

or

pip install git+https://github.com/smhty/dorna.git

Github

You can also check the latest release page for download. Download the compressed source code file ( for example Source code.zip or Source code.tar.gz). After downloading, decompress the file, go to the directory, and run:

python setup.py install

You can also clone the repository directly from Github:

git clone https://github.com/smhty/dorna.git

Once you’ve cloned the repository, install the API by running the setup.py script:

python setup.py install

Note: If you clone the Github repository, the bossac file for mac users does not get cloned as an executable, and you will not be able to update your firmware, so it’s recommended to download from the release page.

Now that we’ve installed the Dorna API, let’s move over to Python and start using it.

Initialization


In Python, let’s import the Dorna API and create a Dorna object.

# Import the API
>>> from dorna import Dorna

# Create the Dorna object
>>> robot = Dorna()

The Dorna object has a default configuration. You can initialize the Dorna object with your own custom configuration file:

>>> robot = Dorna("path_to_a_customized_config.yaml")

Connection


After initialization step, we need to establish a communication link between the Dorna object and the robot controller box. First, plug your USB cable into your laptop and the controller box.

Updating the Firmware

The first thing to do is to make sure that your firmware is up to date. Let’s update the firmware.

# Update the firmware
>>> robot.update_firmware()
Progressing...
    100%  |████████████████████████████████|     709/709 pages
    100%  |████████████████████████████████|     709/709 pages
'{"status": 0, "message": "firmware updated"}'

You should see a successful status code0, and a message: "firmware updated".

Note: In the Linux systems, make sure to install the BOSSA utility software before running the update_firmware method. For installing BOSSA, run the following command in the terminal:

sudo apt-get install bossa-cli

Connecting to the Robot

Now, let’s establish a connection between the Dorna object and the robot.

# Start the connection process 
>>> robot.connect()
Progressing...
    100%  |████████████████████████████████|  113/113 commands
'{"id": "xxx-yyy-zzz", "connection": 2, "port": "COM1", "fv": 1.21, "config": "xxx.yaml", "state": 0}'

If you connected successfully, you should see "connection": 2.

Note: If no USB connection is available, or connection failed, try to physically reconnect the USB device and reconnect again.

Homing


Now we need to set the absolute machine coordinates to a known position. This is known as the homing process. Each joint j0, j1, j2, j3 and j4 is either homed 1, or not homed 0. Note that the homing status of j3 and j4 are coupled to each other. This means, they are both either homed, or not homed, and homing one of them also home the other one.

You can check if your joints are homed with the following:

>>> robot.homed()
'{"j0": 0, "j1": 0, "j2": 0, "j3": 0, "j4": 0}'

Notice that since we haven’t homed the robot yet, all of our joints display 0. So let’s home all of our joints.

>>> robot.home("j0")
'{"j0": 1, "j1": 0, "j2": 0, "j3": 0, "j4": 0}'

>>> robot.home("j1")
'{"j0": 1, "j1": 1, "j2": 0, "j3": 0, "j4": 0}'

>>> robot.home("j2")
'{"j0": 1, "j1": 1, "j2": 1, "j3": 0, "j4": 0}'

>>> robot.home("j3")
'{"j0": 1, "j1": 1, "j2": 1, "j3": 1, "j4": 1}'

Once this process is finished, the robot should be in the position pictured below.

homed

You can check the coordinates of this position with the .position() method.

>>> robot.position()
'[0, 145, -90, 0.0, 0.0]'

Now your robot is in a known position, and we can now start sending the robot commands.

Sending Commands to the Robot


After a successful connection, the robot is ready to receive and execute commands. Each command is a JSON object with three main keys:

  • "command": Name of the command.
  • "prm": Parameters associated to the command.
  • "fulfill": Whether to ignore any errors in this command ("True"), or pause if any errors happened ("False").

Each Dorna object has a queue (submission queue) which is responsible for holding submitted commands. Commands in the submission queue will be sent to the robot one by one. For more detail on commands, visit the wiki.

Playing Commands

We’ll use the .play() method to submit commands in the form of a JSON object to the submission queue. Note that we can group multiple commands together as an JSON array, and feed them all to the submission queue, instead of sending them one by one.

There are four main commands, move, wait_for_input, set_io, and sleep which I’ll demonstrate below.

Move
{"command": "move", "prm": }

This command moves the robot to the given point in space. During a move command, the robot moves from an initial point (start point), to the end point. The end point positions can be given either in the joint coordinate system or the Cartesian coordinate system format.

A summary of the parameters are given below.

Key Value Note
"path" "joint" or "line" Required
"movement" 0 = absolute or 1 = relative Required
"speed" speed_value Optional
"jerk" jerk_array Optional
Position of the end point Specify the position of the end point Required

Here’s an example of using the move command:

# Move j0 by 10 degrees
>>> robot.play({"command": "move", "prm": {"movement": 1, "path": "joint", "j0": 10}})

# Note that our position has changed
>>> robot.position()
'[10, 145, -90, 0.0, 0.0]'
Wait for Input
{"command": "wait_for_input", "prm": }

This command stops the program and waits for the inputs to match the input pattern. If the pattern appeared then the program proceeds. Note that this command only takes one input as a parameter. Here’s an example:

# Stops the program until input 1 is off (0), and then proceeds
>>> robot.play({"command": "wait_for_input", "prm": {"in1": 0}})

# Stops the program until input 4 is on (1), and then proceeds 
>>> robot.play({"command": "wait_for_input", "prm": {"in4": 1}})
Set IO
{"command": "set_io", "prm": }

This command is able to set outputs, mode of inputs and outputs, laser and servo. Here’s a summary of the availiable parameters:

Key Value Note
"outN" 0 (off) or 1 (on) Set the value for the output N, for N from 1 to 4
"doNmo" 0 (active low) or 1 (active high) Set the mode for the output N, for N from 1 to 4
"diNmo" 0 (active low) or 1 (active high) Set the mode for the input N, for N from 1 to 4
"laser" 0 (off) or 1 (on) Turn the laser on or off
"servo" Any number from 0 (all open) to 1000 (all closed) Set the servo

Here’s an example:

# Set the input 1 mode to active low, 
# output 1 value to 1, 
# turn on the laser, 
# and set the servo to 500   
>>> robot.play({"command": "set_io", "prm": {"in1mo": 0, "ou1": 1, "laser": 1, "servo": 500}})
Sleep
{"command": "sleep", "prm": }

This command suspends execution for the given number of seconds. The number of seconds is the value assigned to the "prm" key.

Here’s an example:

# sleep of 1.01 seconds  
>>> robot.play({"command": "sleep", "prm": 1.01})

What Next?

When you’re done, be sure to terminate the Dorna object. The Dorna object runs multiple threads in the background. So, it’s necessary to run this method for every single Dorna object and properly close all the background threads before closing the program.

>>> robot.terminate()

For a more in depth overview of the Dorna API and all its features, you can refer to the Dorna wiki.