Controlling a Doosan robot using Python
Problem
Doosan has three official methods to control their robots.
- Doosan DRL (using Dart studio - Windows only)
- ROS2 (using their GitHub repository - Linux only)
- Doosan C++ API-DRFL (using their GitHub repository - Linux and Windows)
I wanted a setup that would be cross-platform, so a Linux user and a Windows user could both develop for the robot. With the given options, the API-DRFL would be the only solution, but C++ isn’t the best for rapid development and prototyping.
For this problem I’ve created a Python wrapper. This wrapper translates the C++ API-DRFL functions into Python functions, so a developer can control the Doosan using Python.
Setup
Linux (Ubuntu)
First, download the Python library.
git clone --recurse-submodules https://github.com/wouter1602/API-DRFL-Wrapper.git
Go into the created directory and create a venv.
python3 -m venv .venv
source .venv/bin/activate
Note: A venv is required; otherwise, it can’t put the compiled Python library anywhere.
Install the required packages.
pip install -r ./requirements.txt
sudo apt install libpoco-dev
Compile the library.
python3 ./install.py
This will compile the library so it can be used in Python. (This may take some time depending on the speed of your PC.)
Run an example script to verify that it’s working.
python3 ./examples/minimal_motion_sample_async.py
This will move the robot a little bit to show it can move.
Note: You’ll need to change the IP to that of your Doosan control box.
IP_ADDRESS = "127.0.0.1" #<- IP OF DOOSAN ROBOT HERE
PORT = 12345
SPEED = 5.0 # deg/s
ACCELERATION = 5.0 # deg/s2
MOVE_TIMEOUT = 10.0 # seconds
POLL_INTERVAL = 0.05 # seconds (50ms polling rate)
VIRTUAL = False # Will set the movement to be virtual (simulated)
Windows
Currently the Windows version has compile errors. I have not had the opportunity to fix these errors. Below are the steps you’ll need to get to the compile errors.
First, download the Python library:
git clone --recurse-submodules https://github.com/wouter1602/API-DRFL-Wrapper.git
Go into the created directory and set up a venv.
python -m venv .venv
.venv\script\activate.bash
Note: By default, PowerShell won’t allow running scripts. See this link on how to allow it
Note: A venv is required; otherwise, it can’t put the compiled Python library anywhere.
Download the correct runtime:
You’ll need to download the C++ Visual Studio runtime 2017 or newer. You can do that by following the link.
Install the python librarys:
pip install -r ./requirements.txt
Compile the library.
python3 ./install.py
This will compile the library so it can be used in Python. (This may take some time depending on the speed of your PC.)
Note: This currently fails when generating the stubgen because of a library import issue.
Run an example script to verify that it’s working.
python3 ./examples/minimal_motion_sample_async.py
This will move the robot a little bit to show it can move.
Note: You’ll need to change the IP to that of your Doosan control box.
IP_ADDRESS = "127.0.0.1" #<- IP OF DOOSAN ROBOT HERE
PORT = 12345
SPEED = 5.0 # deg/s
ACCELERATION = 5.0 # deg/s2
MOVE_TIMEOUT = 10.0 # seconds
POLL_INTERVAL = 0.05 # seconds (50ms polling rate)
VIRTUAL = False # Will set the movement to be virtual (simulated)
Docs
The functions and variables haven’t changed from the original Doosan C++ API docs, so you can use them to program inside Python. Link
Advantages
Here are some of the advantages of using this wrapper to control a Doosan robot.
One program
You can create one program to control the robot and do other actions your system has to do. (For example, use vision and OpenCV to check alignment.) No need for multiple programs and interprogram communication.
Ease of use
This method is less complex than setting up an ROS environment and programming your robot using the ROS system. It can also do more than the default Dart studio programming.
Cross-platform
Since the original API-DRFL can be used on both Windows and Linux, you can write one Python code that should work on both systems.
Compile once
With rapid development, you don’t want to wait on the compilation each time you change the code. Because this runs in Python, you’ll only need to compile the library once.
Limitations
This method of controlling the Doosan isn’t perfect and comes with some limitations.
Windows
Currently the install.py script detects the user is running Windows, but the compilation fails when running. I haven’t had an opportunity to debug the issue to get it working. Currently a solution is running Ubuntu using WSL.
Linux
The library is only designed to compile against the LTS version of Ubuntu. Other distros or Ubuntu versions ship with the wrong libraries needed, and the program will fail when trying to run. If you’re running a different distro, you can use Docker or Podman in combination with Toolbox to run an Ubuntu instance that works with the library.
Control box
Currently I’ve only tested this wrapper using the Doosan control box version 2. In theory it should work with version 3 boxes. You’ll need to change the compile tag of the setup.py to compile for this version.
# ---------------------------------------------------------------------------
# Build
# ---------------------------------------------------------------------------
def build_extension() -> Extension:
platform_kwargs = _platform_extension_kwargs()
return Extension(
name="doosan_drfl",
sources=SOURCES,
include_dirs=[
str(INCLUDE_DIR),
_pybind11_includes(),
],
language="c++",
extra_compile_args=[
"-std=c++17",
"-O2",
"-fvisibility=hidden", # reduces symbol leakage on Linux
"-DDRCF_VERSION=2", # <- change this to "-DDRCF_VERSION=3" for V3 controlbox
"-DPYBIND11_DETAILED_ERROR_MESSAGES"
] if sys.platform != "win32" else ["/std:c++17", "/O2", "/DDRCF_VERSION=2"],
**platform_kwargs,
)
Not every function
Currently not every function is ported using the wrapper. All the functions for getting control rights, move commands, force feedback, and callback functions are implementendt.
What is missing:
- Welding commands
- Real-time control commands
- LED functions
Multi threading
By default, Python doesn’t really have true multithreading. This is a problem because some of the functions in the wrapper are blocking. This means your program can’t run anything else in parallel while these functions are called (the system will wait for the function to return before continuing).
The problem can be mitigated by using the multiprocessing library of Python and running the robot communication in a separate thread.